@ethisyscore/vite-plugin 1.9.0 → 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 +147 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -1
- package/dist/index.d.ts +69 -1
- package/dist/index.js +149 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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] =
|
|
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 (
|
|
1218
|
+
if (slash4(file) === slash4(manifestAbsPath)) {
|
|
1092
1219
|
try {
|
|
1093
|
-
entries =
|
|
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 =
|
|
1236
|
+
const normalizedId = slash4(id);
|
|
1110
1237
|
const match = entries.find(
|
|
1111
|
-
(e) =>
|
|
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 =
|
|
1246
|
+
const normalizedId = slash4(id);
|
|
1120
1247
|
const match = entries.find(
|
|
1121
|
-
(e) =>
|
|
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;
|