@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.d.cts
CHANGED
|
@@ -352,6 +352,74 @@ interface ParsePlatformReactPagesOptions {
|
|
|
352
352
|
*/
|
|
353
353
|
declare function parsePlatformReactPages(manifestPath: string, options?: ParsePlatformReactPagesOptions): ResolvedPlatformReactPage[];
|
|
354
354
|
|
|
355
|
+
/** One emitted artifact from a per-page Vite sub-build. */
|
|
356
|
+
type IframeBuildOutputItem = {
|
|
357
|
+
type: "chunk";
|
|
358
|
+
fileName: string;
|
|
359
|
+
code: string;
|
|
360
|
+
} | {
|
|
361
|
+
type: "asset";
|
|
362
|
+
fileName: string;
|
|
363
|
+
source: string | Uint8Array;
|
|
364
|
+
};
|
|
365
|
+
interface IframeBuildResult {
|
|
366
|
+
output: IframeBuildOutputItem[];
|
|
367
|
+
}
|
|
368
|
+
/** A single page handed to the (injectable) builder. */
|
|
369
|
+
interface IframeBuildContext {
|
|
370
|
+
id: string;
|
|
371
|
+
title: string;
|
|
372
|
+
entryPath: string;
|
|
373
|
+
root: string;
|
|
374
|
+
/** Per-page output directory (`<outputDir>/<id>`). */
|
|
375
|
+
outDir: string;
|
|
376
|
+
}
|
|
377
|
+
/** Injectable per-page builder. Defaults to a real Vite library build. */
|
|
378
|
+
type IframeViteBuild = (page: IframeBuildContext) => Promise<IframeBuildResult>;
|
|
379
|
+
interface IframeSandboxPluginOptions {
|
|
380
|
+
/** Root the manifest + entry paths resolve against. Defaults to Vite's resolved root / cwd. */
|
|
381
|
+
root?: string;
|
|
382
|
+
/** Manifest path (relative to `root`). Default `feature.manifest.json`. */
|
|
383
|
+
manifestPath?: string;
|
|
384
|
+
/** Output directory for per-page bundles + the digest map. Default `dist/iframe-sandbox`. */
|
|
385
|
+
outputDir?: string;
|
|
386
|
+
/** Inline manifest object (test injection). When omitted, the manifest is read from disk. */
|
|
387
|
+
manifest?: unknown;
|
|
388
|
+
/** Injectable per-page builder (test injection). When omitted, a real Vite build runs. */
|
|
389
|
+
build?: IframeViteBuild;
|
|
390
|
+
/** Injectable file writer (test injection). When omitted, writes via `fs` (creating dirs). */
|
|
391
|
+
writeFile?: (path: string, contents: string) => void;
|
|
392
|
+
}
|
|
393
|
+
interface IframeSandboxBuildSummary {
|
|
394
|
+
digests: Array<{
|
|
395
|
+
path: string;
|
|
396
|
+
sha256: string;
|
|
397
|
+
}>;
|
|
398
|
+
digestMapPath: string | null;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Build each `ui.iframeSandboxPages[]` declaration as its own Vite app bundle and
|
|
402
|
+
* emit a per-asset SHA-256 digest map in the SAME shape `ethisysPlatformReactPlugin`
|
|
403
|
+
* produces (`{ digests: [{ path, sha256 }] }`). Tier U surfaces are independent
|
|
404
|
+
* cross-origin apps, so each page is a separate sub-build under `<outputDir>/<id>/`;
|
|
405
|
+
* every emitted artifact is hashed (and validated against the protocol `AssetDigest`
|
|
406
|
+
* schema) so the edge integrity endpoint (sub-plan 5, Task 6) can verify served bytes.
|
|
407
|
+
*
|
|
408
|
+
* No-op when no pages are declared. Page shape is validated by the protocol
|
|
409
|
+
* `IframeSandboxPageDeclaration` schema (a malformed entry rejects the build).
|
|
410
|
+
*/
|
|
411
|
+
declare function buildIframeSandboxPages(options?: IframeSandboxPluginOptions): Promise<IframeSandboxBuildSummary>;
|
|
412
|
+
/**
|
|
413
|
+
* Tier U (iframe-sandbox) Vite build pass (WI 4858 sub-plan 5). Mirrors
|
|
414
|
+
* `ethisysPlatformReactPlugin`: keyed off `ui.iframeSandboxPages[]` and a no-op
|
|
415
|
+
* when absent, so a single Vite config can compose every render-mode pass.
|
|
416
|
+
*
|
|
417
|
+
* Unlike Tier T (ESM modules in the parent build), each Tier U page is an
|
|
418
|
+
* independent cross-origin app — so the pass runs a separate Vite sub-build per
|
|
419
|
+
* page in `closeBundle` and emits the integrity digest map the host verifies.
|
|
420
|
+
*/
|
|
421
|
+
declare function ethisysIframeSandboxPlugin(options?: IframeSandboxPluginOptions): Plugin;
|
|
422
|
+
|
|
355
423
|
interface EthisysPluginOptions {
|
|
356
424
|
/**
|
|
357
425
|
* Path to the manifest file, relative to Vite's root directory.
|
|
@@ -375,4 +443,4 @@ interface EthisysPluginOptions {
|
|
|
375
443
|
*/
|
|
376
444
|
declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
|
|
377
445
|
|
|
378
|
-
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
|
446
|
+
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
package/dist/index.d.ts
CHANGED
|
@@ -352,6 +352,74 @@ interface ParsePlatformReactPagesOptions {
|
|
|
352
352
|
*/
|
|
353
353
|
declare function parsePlatformReactPages(manifestPath: string, options?: ParsePlatformReactPagesOptions): ResolvedPlatformReactPage[];
|
|
354
354
|
|
|
355
|
+
/** One emitted artifact from a per-page Vite sub-build. */
|
|
356
|
+
type IframeBuildOutputItem = {
|
|
357
|
+
type: "chunk";
|
|
358
|
+
fileName: string;
|
|
359
|
+
code: string;
|
|
360
|
+
} | {
|
|
361
|
+
type: "asset";
|
|
362
|
+
fileName: string;
|
|
363
|
+
source: string | Uint8Array;
|
|
364
|
+
};
|
|
365
|
+
interface IframeBuildResult {
|
|
366
|
+
output: IframeBuildOutputItem[];
|
|
367
|
+
}
|
|
368
|
+
/** A single page handed to the (injectable) builder. */
|
|
369
|
+
interface IframeBuildContext {
|
|
370
|
+
id: string;
|
|
371
|
+
title: string;
|
|
372
|
+
entryPath: string;
|
|
373
|
+
root: string;
|
|
374
|
+
/** Per-page output directory (`<outputDir>/<id>`). */
|
|
375
|
+
outDir: string;
|
|
376
|
+
}
|
|
377
|
+
/** Injectable per-page builder. Defaults to a real Vite library build. */
|
|
378
|
+
type IframeViteBuild = (page: IframeBuildContext) => Promise<IframeBuildResult>;
|
|
379
|
+
interface IframeSandboxPluginOptions {
|
|
380
|
+
/** Root the manifest + entry paths resolve against. Defaults to Vite's resolved root / cwd. */
|
|
381
|
+
root?: string;
|
|
382
|
+
/** Manifest path (relative to `root`). Default `feature.manifest.json`. */
|
|
383
|
+
manifestPath?: string;
|
|
384
|
+
/** Output directory for per-page bundles + the digest map. Default `dist/iframe-sandbox`. */
|
|
385
|
+
outputDir?: string;
|
|
386
|
+
/** Inline manifest object (test injection). When omitted, the manifest is read from disk. */
|
|
387
|
+
manifest?: unknown;
|
|
388
|
+
/** Injectable per-page builder (test injection). When omitted, a real Vite build runs. */
|
|
389
|
+
build?: IframeViteBuild;
|
|
390
|
+
/** Injectable file writer (test injection). When omitted, writes via `fs` (creating dirs). */
|
|
391
|
+
writeFile?: (path: string, contents: string) => void;
|
|
392
|
+
}
|
|
393
|
+
interface IframeSandboxBuildSummary {
|
|
394
|
+
digests: Array<{
|
|
395
|
+
path: string;
|
|
396
|
+
sha256: string;
|
|
397
|
+
}>;
|
|
398
|
+
digestMapPath: string | null;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Build each `ui.iframeSandboxPages[]` declaration as its own Vite app bundle and
|
|
402
|
+
* emit a per-asset SHA-256 digest map in the SAME shape `ethisysPlatformReactPlugin`
|
|
403
|
+
* produces (`{ digests: [{ path, sha256 }] }`). Tier U surfaces are independent
|
|
404
|
+
* cross-origin apps, so each page is a separate sub-build under `<outputDir>/<id>/`;
|
|
405
|
+
* every emitted artifact is hashed (and validated against the protocol `AssetDigest`
|
|
406
|
+
* schema) so the edge integrity endpoint (sub-plan 5, Task 6) can verify served bytes.
|
|
407
|
+
*
|
|
408
|
+
* No-op when no pages are declared. Page shape is validated by the protocol
|
|
409
|
+
* `IframeSandboxPageDeclaration` schema (a malformed entry rejects the build).
|
|
410
|
+
*/
|
|
411
|
+
declare function buildIframeSandboxPages(options?: IframeSandboxPluginOptions): Promise<IframeSandboxBuildSummary>;
|
|
412
|
+
/**
|
|
413
|
+
* Tier U (iframe-sandbox) Vite build pass (WI 4858 sub-plan 5). Mirrors
|
|
414
|
+
* `ethisysPlatformReactPlugin`: keyed off `ui.iframeSandboxPages[]` and a no-op
|
|
415
|
+
* when absent, so a single Vite config can compose every render-mode pass.
|
|
416
|
+
*
|
|
417
|
+
* Unlike Tier T (ESM modules in the parent build), each Tier U page is an
|
|
418
|
+
* independent cross-origin app — so the pass runs a separate Vite sub-build per
|
|
419
|
+
* page in `closeBundle` and emits the integrity digest map the host verifies.
|
|
420
|
+
*/
|
|
421
|
+
declare function ethisysIframeSandboxPlugin(options?: IframeSandboxPluginOptions): Plugin;
|
|
422
|
+
|
|
355
423
|
interface EthisysPluginOptions {
|
|
356
424
|
/**
|
|
357
425
|
* Path to the manifest file, relative to Vite's root directory.
|
|
@@ -375,4 +443,4 @@ interface EthisysPluginOptions {
|
|
|
375
443
|
*/
|
|
376
444
|
declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
|
|
377
445
|
|
|
378
|
-
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
|
446
|
+
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'fs';
|
|
2
|
-
import { isAbsolute, resolve, sep, normalize } from 'path';
|
|
3
|
-
import { KNOWN_PRIMITIVES, KNOWN_OPERATORS, KNOWN_RULE_KINDS, SduiNode, ReactiveRule } from '@ethisyscore/protocol';
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { isAbsolute, resolve, sep, normalize, dirname } from 'path';
|
|
3
|
+
import { KNOWN_PRIMITIVES, KNOWN_OPERATORS, KNOWN_RULE_KINDS, SduiNode, ReactiveRule, IframeSandboxPageDeclaration, AssetDigest } from '@ethisyscore/protocol';
|
|
4
|
+
import { createHash } from 'crypto';
|
|
4
5
|
|
|
5
6
|
// src/index.ts
|
|
6
7
|
var KNOWN_PRIMITIVE_SET = new Set(KNOWN_PRIMITIVES);
|
|
@@ -121,7 +122,7 @@ function ethisysContractAPlugin(options = {}) {
|
|
|
121
122
|
manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
|
|
122
123
|
return resolvedRoot;
|
|
123
124
|
}
|
|
124
|
-
function
|
|
125
|
+
function readManifest2() {
|
|
125
126
|
resolveRoot();
|
|
126
127
|
if (!existsSync(manifestAbsPath)) {
|
|
127
128
|
return null;
|
|
@@ -138,7 +139,7 @@ function ethisysContractAPlugin(options = {}) {
|
|
|
138
139
|
function validate() {
|
|
139
140
|
validatedResources = [];
|
|
140
141
|
resourcePayloads.clear();
|
|
141
|
-
const manifest =
|
|
142
|
+
const manifest = readManifest2();
|
|
142
143
|
if (manifest === null) {
|
|
143
144
|
return;
|
|
144
145
|
}
|
|
@@ -384,7 +385,7 @@ function ethisysContractBPlugin(options = {}) {
|
|
|
384
385
|
manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
|
|
385
386
|
return resolvedRoot;
|
|
386
387
|
}
|
|
387
|
-
function
|
|
388
|
+
function readManifest2() {
|
|
388
389
|
resolveRoot();
|
|
389
390
|
if (!existsSync(manifestAbsPath)) {
|
|
390
391
|
return null;
|
|
@@ -401,7 +402,7 @@ function ethisysContractBPlugin(options = {}) {
|
|
|
401
402
|
function validate() {
|
|
402
403
|
workerEntryAbs = null;
|
|
403
404
|
workerEntryRel = null;
|
|
404
|
-
const manifest =
|
|
405
|
+
const manifest = readManifest2();
|
|
405
406
|
if (manifest === null) {
|
|
406
407
|
return;
|
|
407
408
|
}
|
|
@@ -632,7 +633,7 @@ function ethisysPlatformReactPlugin(options = {}) {
|
|
|
632
633
|
manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
|
|
633
634
|
return resolvedRoot;
|
|
634
635
|
}
|
|
635
|
-
function
|
|
636
|
+
function readManifest2() {
|
|
636
637
|
resolveRoot();
|
|
637
638
|
if (!existsSync(manifestAbsPath)) {
|
|
638
639
|
return null;
|
|
@@ -648,7 +649,7 @@ function ethisysPlatformReactPlugin(options = {}) {
|
|
|
648
649
|
}
|
|
649
650
|
function validate() {
|
|
650
651
|
pages = [];
|
|
651
|
-
const manifest =
|
|
652
|
+
const manifest = readManifest2();
|
|
652
653
|
if (manifest === null) {
|
|
653
654
|
return;
|
|
654
655
|
}
|
|
@@ -727,7 +728,11 @@ function ethisysPlatformReactPlugin(options = {}) {
|
|
|
727
728
|
entryFileNames: `${outputPrefix}[name].js`,
|
|
728
729
|
chunkFileNames: `${outputPrefix}[name]-[hash].js`,
|
|
729
730
|
assetFileNames: `${outputPrefix}[name][extname]`
|
|
730
|
-
}
|
|
731
|
+
},
|
|
732
|
+
// Auto-externalise the host-ui-externals specifier so the host's
|
|
733
|
+
// module-registry rewriter resolves it to the live `@coreconnect/gogo-ui`
|
|
734
|
+
// instance at runtime — Tier T remotes never ship their own Gogo copy.
|
|
735
|
+
external: ["@ethisyscore/host-ui-externals"]
|
|
731
736
|
}
|
|
732
737
|
}
|
|
733
738
|
};
|
|
@@ -785,10 +790,20 @@ function ethisysPlatformReactPlugin(options = {}) {
|
|
|
785
790
|
* this file to discover which page modules ship in the bundle without
|
|
786
791
|
* having to re-parse the manifest.
|
|
787
792
|
*/
|
|
788
|
-
generateBundle() {
|
|
793
|
+
generateBundle(_options, bundle) {
|
|
789
794
|
if (pages.length === 0) {
|
|
790
795
|
return;
|
|
791
796
|
}
|
|
797
|
+
const digests = [];
|
|
798
|
+
for (const chunk of Object.values(bundle ?? {})) {
|
|
799
|
+
if (chunk.type !== "chunk") {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
const code = chunk.code;
|
|
803
|
+
const fileName = chunk.fileName;
|
|
804
|
+
const hash = createHash("sha256").update(code, "utf8").digest("hex");
|
|
805
|
+
digests.push({ path: fileName, sha256: hash });
|
|
806
|
+
}
|
|
792
807
|
const summary = {
|
|
793
808
|
pages: pages.map((p) => ({
|
|
794
809
|
id: p.id,
|
|
@@ -803,6 +818,11 @@ function ethisysPlatformReactPlugin(options = {}) {
|
|
|
803
818
|
fileName: `${outputPrefix}platform-react-pages.json`,
|
|
804
819
|
source: JSON.stringify(summary, null, 2)
|
|
805
820
|
});
|
|
821
|
+
this.emitFile({
|
|
822
|
+
type: "asset",
|
|
823
|
+
fileName: `${outputPrefix}platform-react-digest-map.json`,
|
|
824
|
+
source: JSON.stringify({ digests }, null, 2)
|
|
825
|
+
});
|
|
806
826
|
}
|
|
807
827
|
};
|
|
808
828
|
}
|
|
@@ -894,9 +914,116 @@ function parsePlatformReactPages(manifestPath, options = {}) {
|
|
|
894
914
|
}
|
|
895
915
|
return result;
|
|
896
916
|
}
|
|
917
|
+
var DEFAULT_MANIFEST = "feature.manifest.json";
|
|
918
|
+
var DEFAULT_OUTPUT_DIR = "dist/iframe-sandbox";
|
|
919
|
+
var DIGEST_MAP_FILENAME = "iframe-sandbox-digest-map.json";
|
|
920
|
+
function slash3(p) {
|
|
921
|
+
return sep === "\\" ? p.replace(/\\/g, "/") : p;
|
|
922
|
+
}
|
|
923
|
+
function defaultWriteFile(path, contents) {
|
|
924
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
925
|
+
writeFileSync(path, contents);
|
|
926
|
+
}
|
|
927
|
+
var defaultBuild = async (page) => {
|
|
928
|
+
const { build } = await import('vite');
|
|
929
|
+
const result = await build({
|
|
930
|
+
root: page.root,
|
|
931
|
+
logLevel: "warn",
|
|
932
|
+
build: {
|
|
933
|
+
outDir: page.outDir,
|
|
934
|
+
emptyOutDir: true,
|
|
935
|
+
rollupOptions: {
|
|
936
|
+
input: resolve(page.root, page.entryPath)
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
const out = Array.isArray(result) ? result[0] : result;
|
|
941
|
+
return { output: out.output };
|
|
942
|
+
};
|
|
943
|
+
function digestOf(item) {
|
|
944
|
+
const bytes = item.type === "chunk" ? item.code : item.source;
|
|
945
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
946
|
+
}
|
|
947
|
+
function readManifest(options, root) {
|
|
948
|
+
if (options.manifest !== void 0) {
|
|
949
|
+
return options.manifest;
|
|
950
|
+
}
|
|
951
|
+
const rel = options.manifestPath ?? DEFAULT_MANIFEST;
|
|
952
|
+
const abs = isAbsolute(rel) ? rel : resolve(root, rel);
|
|
953
|
+
if (!existsSync(abs)) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
const raw = readFileSync(abs, "utf8");
|
|
957
|
+
try {
|
|
958
|
+
return JSON.parse(raw);
|
|
959
|
+
} catch (e) {
|
|
960
|
+
throw new Error(`[ethisys-iframe-sandbox] Failed to parse manifest at "${abs}": ${e.message}`);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
async function buildIframeSandboxPages(options = {}) {
|
|
964
|
+
const root = options.root ?? process.cwd();
|
|
965
|
+
const manifest = readManifest(options, root);
|
|
966
|
+
const declared = manifest?.ui?.iframeSandboxPages;
|
|
967
|
+
if (!Array.isArray(declared) || declared.length === 0) {
|
|
968
|
+
return { digests: [], digestMapPath: null };
|
|
969
|
+
}
|
|
970
|
+
const pages = declared.map((raw, i) => {
|
|
971
|
+
try {
|
|
972
|
+
return IframeSandboxPageDeclaration.parse(raw);
|
|
973
|
+
} catch (e) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
`[ethisys-iframe-sandbox] ui.iframeSandboxPages[${i}] is invalid: ${e.message}`
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
const seen = /* @__PURE__ */ new Set();
|
|
980
|
+
for (const p of pages) {
|
|
981
|
+
if (seen.has(p.id)) {
|
|
982
|
+
throw new Error(`[ethisys-iframe-sandbox] Duplicate iframe-sandbox page id "${p.id}".`);
|
|
983
|
+
}
|
|
984
|
+
seen.add(p.id);
|
|
985
|
+
}
|
|
986
|
+
const build = options.build ?? defaultBuild;
|
|
987
|
+
const write = options.writeFile ?? defaultWriteFile;
|
|
988
|
+
const outputDir = options.outputDir ?? DEFAULT_OUTPUT_DIR;
|
|
989
|
+
const outDirAbs = isAbsolute(outputDir) ? outputDir : resolve(root, outputDir);
|
|
990
|
+
const digests = [];
|
|
991
|
+
for (const page of pages) {
|
|
992
|
+
const result = await build({
|
|
993
|
+
id: page.id,
|
|
994
|
+
title: page.title,
|
|
995
|
+
entryPath: page.entryPath,
|
|
996
|
+
root,
|
|
997
|
+
outDir: resolve(outDirAbs, page.id)
|
|
998
|
+
});
|
|
999
|
+
for (const item of result.output) {
|
|
1000
|
+
const entry = { path: `${page.id}/${item.fileName}`, sha256: digestOf(item) };
|
|
1001
|
+
AssetDigest.parse(entry);
|
|
1002
|
+
digests.push(entry);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
const digestMapPath = resolve(outDirAbs, DIGEST_MAP_FILENAME);
|
|
1006
|
+
write(slash3(digestMapPath), JSON.stringify({ digests }, null, 2));
|
|
1007
|
+
return { digests, digestMapPath };
|
|
1008
|
+
}
|
|
1009
|
+
function ethisysIframeSandboxPlugin(options = {}) {
|
|
1010
|
+
let resolvedRoot = options.root;
|
|
1011
|
+
return {
|
|
1012
|
+
name: "ethisys-iframe-sandbox",
|
|
1013
|
+
enforce: "pre",
|
|
1014
|
+
configResolved(config) {
|
|
1015
|
+
if (!options.root) {
|
|
1016
|
+
resolvedRoot = config.root;
|
|
1017
|
+
}
|
|
1018
|
+
},
|
|
1019
|
+
async closeBundle() {
|
|
1020
|
+
await buildIframeSandboxPages({ ...options, root: options.root ?? resolvedRoot });
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
897
1024
|
|
|
898
1025
|
// src/index.ts
|
|
899
|
-
function
|
|
1026
|
+
function slash4(p) {
|
|
900
1027
|
return sep === "\\" ? p.replace(/\\/g, "/") : p;
|
|
901
1028
|
}
|
|
902
1029
|
function escapeHtml(str) {
|
|
@@ -955,7 +1082,7 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
955
1082
|
</body>
|
|
956
1083
|
</html>`;
|
|
957
1084
|
}
|
|
958
|
-
function
|
|
1085
|
+
function readManifest2() {
|
|
959
1086
|
if (!existsSync(manifestAbsPath)) {
|
|
960
1087
|
return [];
|
|
961
1088
|
}
|
|
@@ -1007,7 +1134,7 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1007
1134
|
config(config, { command }) {
|
|
1008
1135
|
rootDir = config.root ?? process.cwd();
|
|
1009
1136
|
manifestAbsPath = resolve(rootDir, manifestRelPath);
|
|
1010
|
-
entries =
|
|
1137
|
+
entries = readManifest2();
|
|
1011
1138
|
if (entries.length === 0) {
|
|
1012
1139
|
return;
|
|
1013
1140
|
}
|
|
@@ -1021,7 +1148,7 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1021
1148
|
}
|
|
1022
1149
|
seen.add(entry.entrypoint);
|
|
1023
1150
|
const name = entry.entrypoint.replace(/\.html$/, "");
|
|
1024
|
-
input[name] =
|
|
1151
|
+
input[name] = slash4(resolve(rootDir, entry.entrypoint));
|
|
1025
1152
|
}
|
|
1026
1153
|
return {
|
|
1027
1154
|
build: {
|
|
@@ -1086,9 +1213,9 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1086
1213
|
// Entire handler is wrapped in try/catch so JSON syntax errors in the
|
|
1087
1214
|
// manifest don't crash the dev server (common during active editing).
|
|
1088
1215
|
handleHotUpdate({ file, server }) {
|
|
1089
|
-
if (
|
|
1216
|
+
if (slash4(file) === slash4(manifestAbsPath)) {
|
|
1090
1217
|
try {
|
|
1091
|
-
entries =
|
|
1218
|
+
entries = readManifest2();
|
|
1092
1219
|
validateEntries();
|
|
1093
1220
|
htmlCache.clear();
|
|
1094
1221
|
} catch (e) {
|
|
@@ -1104,9 +1231,9 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1104
1231
|
},
|
|
1105
1232
|
// Build: resolve virtual HTML module IDs (no physical files exist on disk)
|
|
1106
1233
|
resolveId(id) {
|
|
1107
|
-
const normalizedId =
|
|
1234
|
+
const normalizedId = slash4(id);
|
|
1108
1235
|
const match = entries.find(
|
|
1109
|
-
(e) =>
|
|
1236
|
+
(e) => slash4(resolve(rootDir, e.entrypoint)) === normalizedId
|
|
1110
1237
|
);
|
|
1111
1238
|
if (match) {
|
|
1112
1239
|
return id;
|
|
@@ -1114,9 +1241,9 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1114
1241
|
},
|
|
1115
1242
|
// Build: provide virtual HTML content for Rollup
|
|
1116
1243
|
load(id) {
|
|
1117
|
-
const normalizedId =
|
|
1244
|
+
const normalizedId = slash4(id);
|
|
1118
1245
|
const match = entries.find(
|
|
1119
|
-
(e) =>
|
|
1246
|
+
(e) => slash4(resolve(rootDir, e.entrypoint)) === normalizedId
|
|
1120
1247
|
);
|
|
1121
1248
|
if (match) {
|
|
1122
1249
|
return generateHtml(match);
|
|
@@ -1125,6 +1252,6 @@ function ethisysManifestPlugin(options = {}) {
|
|
|
1125
1252
|
};
|
|
1126
1253
|
}
|
|
1127
1254
|
|
|
1128
|
-
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
|
1255
|
+
export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
|
|
1129
1256
|
//# sourceMappingURL=index.js.map
|
|
1130
1257
|
//# sourceMappingURL=index.js.map
|