@miaixz/sdk 0.5.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/LICENSE +202 -0
- package/NOTICE +7 -0
- package/README.md +412 -0
- package/dist/api/client.d.ts +223 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +1069 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/endpoint.d.ts +10 -0
- package/dist/api/endpoint.d.ts.map +1 -0
- package/dist/api/endpoint.js +51 -0
- package/dist/api/endpoint.js.map +1 -0
- package/dist/api/errors.d.ts +180 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +173 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +5 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/request.d.ts +135 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/api/request.js +2 -0
- package/dist/api/request.js.map +1 -0
- package/dist/api/response.d.ts +69 -0
- package/dist/api/response.d.ts.map +1 -0
- package/dist/api/response.js +43 -0
- package/dist/api/response.js.map +1 -0
- package/dist/api/telemetry.d.ts +139 -0
- package/dist/api/telemetry.d.ts.map +1 -0
- package/dist/api/telemetry.js +2 -0
- package/dist/api/telemetry.js.map +1 -0
- package/dist/appearance/appearance.d.ts +161 -0
- package/dist/appearance/appearance.d.ts.map +1 -0
- package/dist/appearance/appearance.js +614 -0
- package/dist/appearance/appearance.js.map +1 -0
- package/dist/appearance/index.d.ts +3 -0
- package/dist/appearance/index.d.ts.map +1 -0
- package/dist/appearance/index.js +3 -0
- package/dist/appearance/index.js.map +1 -0
- package/dist/auth/auth.d.ts +197 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +314 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/config/config.d.ts +117 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +241 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/consts/index.d.ts +35 -0
- package/dist/consts/index.d.ts.map +1 -0
- package/dist/consts/index.js +35 -0
- package/dist/consts/index.js.map +1 -0
- package/dist/context/context.d.ts +123 -0
- package/dist/context/context.d.ts.map +1 -0
- package/dist/context/context.js +252 -0
- package/dist/context/context.js.map +1 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/contracts/host-context.d.ts +132 -0
- package/dist/contracts/host-context.d.ts.map +1 -0
- package/dist/contracts/host-context.js +2 -0
- package/dist/contracts/host-context.js.map +1 -0
- package/dist/contracts/index.d.ts +8 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/lifecycle.d.ts +49 -0
- package/dist/contracts/lifecycle.d.ts.map +1 -0
- package/dist/contracts/lifecycle.js +2 -0
- package/dist/contracts/lifecycle.js.map +1 -0
- package/dist/contracts/module-manifest.d.ts +110 -0
- package/dist/contracts/module-manifest.d.ts.map +1 -0
- package/dist/contracts/module-manifest.js +317 -0
- package/dist/contracts/module-manifest.js.map +1 -0
- package/dist/contracts/navigation.d.ts +36 -0
- package/dist/contracts/navigation.d.ts.map +1 -0
- package/dist/contracts/navigation.js +11 -0
- package/dist/contracts/navigation.js.map +1 -0
- package/dist/contracts/permission.d.ts +8 -0
- package/dist/contracts/permission.d.ts.map +1 -0
- package/dist/contracts/permission.js +14 -0
- package/dist/contracts/permission.js.map +1 -0
- package/dist/contracts/post-message.d.ts +124 -0
- package/dist/contracts/post-message.d.ts.map +1 -0
- package/dist/contracts/post-message.js +2 -0
- package/dist/contracts/post-message.js.map +1 -0
- package/dist/contracts/route.d.ts +45 -0
- package/dist/contracts/route.d.ts.map +1 -0
- package/dist/contracts/route.js +35 -0
- package/dist/contracts/route.js.map +1 -0
- package/dist/events/events.d.ts +191 -0
- package/dist/events/events.d.ts.map +1 -0
- package/dist/events/events.js +486 -0
- package/dist/events/events.js.map +1 -0
- package/dist/events/index.d.ts +2 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +2 -0
- package/dist/events/index.js.map +1 -0
- package/dist/files/files.d.ts +138 -0
- package/dist/files/files.d.ts.map +1 -0
- package/dist/files/files.js +144 -0
- package/dist/files/files.js.map +1 -0
- package/dist/files/index.d.ts +2 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +2 -0
- package/dist/files/index.js.map +1 -0
- package/dist/formatters/index.d.ts +44 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +50 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/i18n/default-translator.d.ts +17 -0
- package/dist/i18n/default-translator.d.ts.map +1 -0
- package/dist/i18n/default-translator.js +19 -0
- package/dist/i18n/default-translator.js.map +1 -0
- package/dist/i18n/i18n.d.ts +248 -0
- package/dist/i18n/i18n.d.ts.map +1 -0
- package/dist/i18n/i18n.js +617 -0
- package/dist/i18n/i18n.js.map +1 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +2 -0
- package/dist/models/index.js.map +1 -0
- package/dist/permissions/index.d.ts +2 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +2 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/permissions.d.ts +67 -0
- package/dist/permissions/permissions.d.ts.map +1 -0
- package/dist/permissions/permissions.js +123 -0
- package/dist/permissions/permissions.js.map +1 -0
- package/dist/runtime/direct-host-bridge.d.ts +11 -0
- package/dist/runtime/direct-host-bridge.d.ts.map +1 -0
- package/dist/runtime/direct-host-bridge.js +299 -0
- package/dist/runtime/direct-host-bridge.js.map +1 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +3 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/post-message-bridge.d.ts +20 -0
- package/dist/runtime/post-message-bridge.d.ts.map +1 -0
- package/dist/runtime/post-message-bridge.js +1115 -0
- package/dist/runtime/post-message-bridge.js.map +1 -0
- package/dist/sdk.d.ts +177 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +214 -0
- package/dist/sdk.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +246 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +358 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/types/api.d.ts +82 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +2 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/appearance.d.ts +85 -0
- package/dist/types/appearance.d.ts.map +1 -0
- package/dist/types/appearance.js +48 -0
- package/dist/types/appearance.js.map +1 -0
- package/dist/types/config.d.ts +49 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/context.d.ts +41 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +2 -0
- package/dist/types/context.js.map +1 -0
- package/dist/types/file.d.ts +48 -0
- package/dist/types/file.d.ts.map +1 -0
- package/dist/types/file.js +2 -0
- package/dist/types/file.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/organization.d.ts +56 -0
- package/dist/types/organization.d.ts.map +1 -0
- package/dist/types/organization.js +2 -0
- package/dist/types/organization.js.map +1 -0
- package/dist/types/pagination.d.ts +55 -0
- package/dist/types/pagination.d.ts.map +1 -0
- package/dist/types/pagination.js +13 -0
- package/dist/types/pagination.js.map +1 -0
- package/dist/types/permissions.d.ts +26 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +2 -0
- package/dist/types/permissions.js.map +1 -0
- package/dist/types/space.d.ts +43 -0
- package/dist/types/space.d.ts.map +1 -0
- package/dist/types/space.js +2 -0
- package/dist/types/space.js.map +1 -0
- package/dist/types/tenant.d.ts +31 -0
- package/dist/types/tenant.d.ts.map +1 -0
- package/dist/types/tenant.js +2 -0
- package/dist/types/tenant.js.map +1 -0
- package/dist/types/user.d.ts +48 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +2 -0
- package/dist/types/user.js.map +1 -0
- package/dist/utils/date.d.ts +9 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +11 -0
- package/dist/utils/date.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/number.d.ts +11 -0
- package/dist/utils/number.d.ts.map +1 -0
- package/dist/utils/number.js +13 -0
- package/dist/utils/number.js.map +1 -0
- package/dist/utils/object.d.ts +9 -0
- package/dist/utils/object.d.ts.map +1 -0
- package/dist/utils/object.js +11 -0
- package/dist/utils/object.js.map +1 -0
- package/dist/utils/string.d.ts +9 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/string.js +11 -0
- package/dist/utils/string.js.map +1 -0
- package/dist/validators/index.d.ts +8 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +8 -0
- package/dist/validators/index.js.map +1 -0
- package/package.json +156 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/contracts/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;CACnD;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,wBAAwB,GAAG,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC5F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/contracts/lifecycle.ts"],"names":[],"mappings":"","sourcesContent":["import type { MiaixzHostBridge } from \"./host-context.js\";\nimport type { MiaixzModuleManifest } from \"./module-manifest.js\";\n\n/**\n * Provides the host-owned resources required to mount an integrated module.\n *\n * @public\n */\nexport interface MiaixzModuleMountContext {\n /**\n * DOM container owned by the host application.\n */\n readonly container: HTMLElement;\n\n /**\n * Capability-limited bridge supplied by the host.\n */\n readonly bridge: MiaixzHostBridge;\n\n /**\n * Validated immutable manifest associated with the module.\n */\n readonly manifest: Readonly<MiaixzModuleManifest>;\n}\n\n/**\n * Represents the resources returned by a mounted integrated module.\n *\n * @public\n */\nexport interface MiaixzModuleHandle {\n /**\n * Releases every resource created by the mounted module.\n *\n * @returns Nothing, or a promise resolved after asynchronous cleanup.\n */\n unmount(): void | Promise<void>;\n}\n\n/**\n * Defines the only lifecycle entry exposed by an integrated module.\n *\n * @public\n */\nexport interface MiaixzIntegratedModule {\n /**\n * Mounts the module into its host-owned container.\n *\n * @param context - Validated host resources supplied to the module.\n * @returns Handle used by the host to unmount the module.\n */\n mount(context: MiaixzModuleMountContext): MiaixzModuleHandle | Promise<MiaixzModuleHandle>;\n}\n"]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { MiaixzEnvironment } from "../types/index.js";
|
|
2
|
+
import { type MiaixzModuleNavigationItem } from "./navigation.js";
|
|
3
|
+
import { type MiaixzModuleRoute } from "./route.js";
|
|
4
|
+
/**
|
|
5
|
+
* Version of the Miaixz micro-frontend manifest and lifecycle protocol.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export declare const MIAIXZ_MODULE_PROTOCOL_VERSION: "1.0.0";
|
|
10
|
+
/**
|
|
11
|
+
* Identifies how a module is loaded and isolated by its host.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export type MiaixzModuleKind = "integrated" | "iframe";
|
|
16
|
+
/**
|
|
17
|
+
* Identifies one host capability that a module may require.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
export type MiaixzHostCapability = "context" | "events" | "i18n" | "navigation" | "permissions";
|
|
22
|
+
/**
|
|
23
|
+
* Describes a pure-data manifest for one independently deployed frontend module.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface MiaixzModuleManifest {
|
|
28
|
+
/**
|
|
29
|
+
* Protocol version understood by the module.
|
|
30
|
+
*/
|
|
31
|
+
readonly protocolVersion: "1.0.0";
|
|
32
|
+
/**
|
|
33
|
+
* Globally stable kebab-case module identifier.
|
|
34
|
+
*/
|
|
35
|
+
readonly id: string;
|
|
36
|
+
/**
|
|
37
|
+
* Complete semantic version of the module release.
|
|
38
|
+
*/
|
|
39
|
+
readonly version: string;
|
|
40
|
+
/**
|
|
41
|
+
* Caret range describing the minimum compatible host release.
|
|
42
|
+
*/
|
|
43
|
+
readonly hostVersion: string;
|
|
44
|
+
/**
|
|
45
|
+
* Loading and isolation strategy used by the module.
|
|
46
|
+
*/
|
|
47
|
+
readonly kind: MiaixzModuleKind;
|
|
48
|
+
/**
|
|
49
|
+
* Static host path reserved for the module.
|
|
50
|
+
*/
|
|
51
|
+
readonly basePath: string;
|
|
52
|
+
/**
|
|
53
|
+
* Integrated module identifier or iframe deployment URL.
|
|
54
|
+
*/
|
|
55
|
+
readonly entry: string;
|
|
56
|
+
/**
|
|
57
|
+
* Routes contributed by the module.
|
|
58
|
+
*/
|
|
59
|
+
readonly routes: readonly MiaixzModuleRoute[];
|
|
60
|
+
/**
|
|
61
|
+
* Navigation items contributed by the module.
|
|
62
|
+
*/
|
|
63
|
+
readonly navigation: readonly MiaixzModuleNavigationItem[];
|
|
64
|
+
/**
|
|
65
|
+
* Permissions required before the module may load.
|
|
66
|
+
*/
|
|
67
|
+
readonly requiredPermissions: readonly string[];
|
|
68
|
+
/**
|
|
69
|
+
* Host capabilities required by the module.
|
|
70
|
+
*/
|
|
71
|
+
readonly requiredCapabilities: readonly MiaixzHostCapability[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Configures environment-specific and host-version manifest validation.
|
|
75
|
+
*
|
|
76
|
+
* @public
|
|
77
|
+
*/
|
|
78
|
+
export interface MiaixzModuleManifestParseOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Runtime environment used to validate iframe URLs.
|
|
81
|
+
*
|
|
82
|
+
* @defaultValue `"production"`
|
|
83
|
+
*/
|
|
84
|
+
readonly environment?: MiaixzEnvironment;
|
|
85
|
+
/**
|
|
86
|
+
* Optional concrete host version checked against the manifest range.
|
|
87
|
+
*/
|
|
88
|
+
readonly hostVersion?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Determines whether a concrete host satisfies the frozen caret-range compatibility rule.
|
|
92
|
+
*
|
|
93
|
+
* @param hostVersion - Concrete complete semantic version of the host.
|
|
94
|
+
* @param requiredHostVersion - Required caret range in `^MAJOR.MINOR.PATCH` form.
|
|
95
|
+
* @returns Whether majors match and the host is at least the required range floor.
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
export declare function isMiaixzHostVersionCompatible(hostVersion: string, requiredHostVersion: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Parses, validates, sorts, and deeply freezes a remote module manifest.
|
|
101
|
+
*
|
|
102
|
+
* @param value - Untrusted manifest candidate.
|
|
103
|
+
* @param options - Optional runtime environment and concrete host version.
|
|
104
|
+
* @returns A deeply immutable manifest copy owned by the SDK.
|
|
105
|
+
* @throws MiaixzSdkError With `MODULE_MANIFEST_INVALID` for malformed manifest data.
|
|
106
|
+
* @throws MiaixzSdkError With `MODULE_HOST_INCOMPATIBLE` for an incompatible concrete host.
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
export declare function parseMiaixzModuleManifest(value: unknown, options?: Readonly<MiaixzModuleManifestParseOptions>): Readonly<MiaixzModuleManifest>;
|
|
110
|
+
//# sourceMappingURL=module-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-manifest.d.ts","sourceRoot":"","sources":["../../src/contracts/module-manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAiC,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAG,OAAgB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC;AAEhG;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAE9C;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAE3D;;OAEG;IACH,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,oBAAoB,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAChE;AAED;;;;GAIG;AACH,MAAM,WAAW,gCAAgC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAsKD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAST;AAkFD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,QAAQ,CAAC,gCAAgC,CAAM,GACvD,QAAQ,CAAC,oBAAoB,CAAC,CA4DhC"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { MiaixzSdkError } from "../api/errors.js";
|
|
2
|
+
import { translateMiaixzDefaultMessage } from "../i18n/default-translator.js";
|
|
3
|
+
import { compareMiaixzModuleNavigation } from "./navigation.js";
|
|
4
|
+
import { isMiaixzModuleIdentifier, isMiaixzModulePath, isMiaixzModulePermissionList, } from "./route.js";
|
|
5
|
+
/**
|
|
6
|
+
* Version of the Miaixz micro-frontend manifest and lifecycle protocol.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export const MIAIXZ_MODULE_PROTOCOL_VERSION = "1.0.0";
|
|
11
|
+
const manifestKeys = new Set([
|
|
12
|
+
"protocolVersion",
|
|
13
|
+
"id",
|
|
14
|
+
"version",
|
|
15
|
+
"hostVersion",
|
|
16
|
+
"kind",
|
|
17
|
+
"basePath",
|
|
18
|
+
"entry",
|
|
19
|
+
"routes",
|
|
20
|
+
"navigation",
|
|
21
|
+
"requiredPermissions",
|
|
22
|
+
"requiredCapabilities",
|
|
23
|
+
]);
|
|
24
|
+
const routeKeys = new Set(["id", "path", "titleKey", "requiredPermissions"]);
|
|
25
|
+
const navigationKeys = new Set(["id", "routeId", "labelKey", "icon", "order"]);
|
|
26
|
+
const environments = new Set(["development", "test", "staging", "production"]);
|
|
27
|
+
const capabilities = new Set([
|
|
28
|
+
"context",
|
|
29
|
+
"events",
|
|
30
|
+
"i18n",
|
|
31
|
+
"navigation",
|
|
32
|
+
"permissions",
|
|
33
|
+
]);
|
|
34
|
+
const semanticVersionPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?$/;
|
|
35
|
+
const hostVersionPattern = /^\^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
36
|
+
/**
|
|
37
|
+
* Creates the frozen manifest-validation error without including untrusted values.
|
|
38
|
+
*
|
|
39
|
+
* @returns Manifest-validation error using the registered public error code.
|
|
40
|
+
*/
|
|
41
|
+
function invalidManifest() {
|
|
42
|
+
return new MiaixzSdkError(translateMiaixzDefaultMessage("sdk.error.module.manifestInvalid"), {
|
|
43
|
+
code: "MODULE_MANIFEST_INVALID",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates the frozen host-version compatibility error without including version values.
|
|
48
|
+
*
|
|
49
|
+
* @returns Host-compatibility error using the registered public error code.
|
|
50
|
+
*/
|
|
51
|
+
function incompatibleHost() {
|
|
52
|
+
return new MiaixzSdkError(translateMiaixzDefaultMessage("sdk.error.module.hostIncompatible"), {
|
|
53
|
+
code: "MODULE_HOST_INCOMPATIBLE",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Determines whether a value is a plain JSON-style record.
|
|
58
|
+
*
|
|
59
|
+
* @param value - Value to inspect.
|
|
60
|
+
* @returns Whether the value is a plain record without a custom prototype.
|
|
61
|
+
*/
|
|
62
|
+
function isPlainRecord(value) {
|
|
63
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
64
|
+
return false;
|
|
65
|
+
const prototype = Object.getPrototypeOf(value);
|
|
66
|
+
return prototype === Object.prototype || prototype === null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Determines whether a record contains exactly the allowed field names.
|
|
70
|
+
*
|
|
71
|
+
* @param value - Record whose keys should be checked.
|
|
72
|
+
* @param allowed - Complete allowed key set.
|
|
73
|
+
* @returns Whether every own enumerable key is allowed.
|
|
74
|
+
*/
|
|
75
|
+
function hasOnlyKeys(value, allowed) {
|
|
76
|
+
return Object.keys(value).every((key) => allowed.has(key));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parses a complete semantic version without build metadata.
|
|
80
|
+
*
|
|
81
|
+
* @param value - Version candidate to parse.
|
|
82
|
+
* @returns Parsed semantic version, or undefined for invalid syntax.
|
|
83
|
+
*/
|
|
84
|
+
function parseSemanticVersion(value) {
|
|
85
|
+
const match = semanticVersionPattern.exec(value);
|
|
86
|
+
if (!match)
|
|
87
|
+
return undefined;
|
|
88
|
+
return {
|
|
89
|
+
major: Number(match[1]),
|
|
90
|
+
minor: Number(match[2]),
|
|
91
|
+
patch: Number(match[3]),
|
|
92
|
+
prerelease: Object.freeze(match[4]?.split(".") ?? []),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Parses the only host-version range syntax accepted by module manifests.
|
|
97
|
+
*
|
|
98
|
+
* @param value - Host range candidate to parse.
|
|
99
|
+
* @returns Parsed range floor, or undefined for invalid syntax.
|
|
100
|
+
*/
|
|
101
|
+
function parseHostVersion(value) {
|
|
102
|
+
const match = hostVersionPattern.exec(value);
|
|
103
|
+
if (!match)
|
|
104
|
+
return undefined;
|
|
105
|
+
return {
|
|
106
|
+
major: Number(match[1]),
|
|
107
|
+
minor: Number(match[2]),
|
|
108
|
+
patch: Number(match[3]),
|
|
109
|
+
prerelease: Object.freeze([]),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Compares two parsed semantic versions using standard prerelease precedence.
|
|
114
|
+
*
|
|
115
|
+
* @param first - First semantic version.
|
|
116
|
+
* @param second - Second semantic version.
|
|
117
|
+
* @returns Negative, zero, or positive precedence result.
|
|
118
|
+
*/
|
|
119
|
+
function compareSemanticVersions(first, second) {
|
|
120
|
+
const core = first.major - second.major || first.minor - second.minor || first.patch - second.patch;
|
|
121
|
+
if (core !== 0)
|
|
122
|
+
return core;
|
|
123
|
+
if (first.prerelease.length === 0)
|
|
124
|
+
return second.prerelease.length === 0 ? 0 : 1;
|
|
125
|
+
if (second.prerelease.length === 0)
|
|
126
|
+
return -1;
|
|
127
|
+
const length = Math.max(first.prerelease.length, second.prerelease.length);
|
|
128
|
+
for (let index = 0; index < length; index += 1) {
|
|
129
|
+
const left = first.prerelease[index];
|
|
130
|
+
const right = second.prerelease[index];
|
|
131
|
+
if (left === undefined)
|
|
132
|
+
return -1;
|
|
133
|
+
if (right === undefined)
|
|
134
|
+
return 1;
|
|
135
|
+
if (left === right)
|
|
136
|
+
continue;
|
|
137
|
+
const leftNumeric = /^\d+$/.test(left);
|
|
138
|
+
const rightNumeric = /^\d+$/.test(right);
|
|
139
|
+
if (leftNumeric && rightNumeric)
|
|
140
|
+
return Number(left) - Number(right);
|
|
141
|
+
if (leftNumeric)
|
|
142
|
+
return -1;
|
|
143
|
+
if (rightNumeric)
|
|
144
|
+
return 1;
|
|
145
|
+
return left.localeCompare(right);
|
|
146
|
+
}
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Determines whether a concrete host satisfies the frozen caret-range compatibility rule.
|
|
151
|
+
*
|
|
152
|
+
* @param hostVersion - Concrete complete semantic version of the host.
|
|
153
|
+
* @param requiredHostVersion - Required caret range in `^MAJOR.MINOR.PATCH` form.
|
|
154
|
+
* @returns Whether majors match and the host is at least the required range floor.
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
export function isMiaixzHostVersionCompatible(hostVersion, requiredHostVersion) {
|
|
158
|
+
const host = parseSemanticVersion(hostVersion);
|
|
159
|
+
const required = parseHostVersion(requiredHostVersion);
|
|
160
|
+
return (host !== undefined &&
|
|
161
|
+
required !== undefined &&
|
|
162
|
+
host.major === required.major &&
|
|
163
|
+
compareSemanticVersions(host, required) >= 0);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Parses one route and creates its immutable manifest-owned copy.
|
|
167
|
+
*
|
|
168
|
+
* @param value - Route candidate to parse.
|
|
169
|
+
* @param basePath - Validated module base path.
|
|
170
|
+
* @returns Frozen route copy, or undefined for invalid data.
|
|
171
|
+
*/
|
|
172
|
+
function parseRoute(value, basePath) {
|
|
173
|
+
if (!isPlainRecord(value) || !hasOnlyKeys(value, routeKeys))
|
|
174
|
+
return undefined;
|
|
175
|
+
if (!isMiaixzModuleIdentifier(value.id) || !isMiaixzModulePath(value.path))
|
|
176
|
+
return undefined;
|
|
177
|
+
if (typeof value.titleKey !== "string" || value.titleKey.trim().length === 0)
|
|
178
|
+
return undefined;
|
|
179
|
+
if (basePath !== "/" && (value.path === basePath || value.path.startsWith(`${basePath}/`))) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
if (value.requiredPermissions !== undefined &&
|
|
183
|
+
!isMiaixzModulePermissionList(value.requiredPermissions)) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
return Object.freeze({
|
|
187
|
+
id: value.id,
|
|
188
|
+
path: value.path,
|
|
189
|
+
titleKey: value.titleKey,
|
|
190
|
+
...(value.requiredPermissions === undefined
|
|
191
|
+
? {}
|
|
192
|
+
: { requiredPermissions: Object.freeze([...value.requiredPermissions]) }),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Parses one navigation item and creates its immutable manifest-owned copy.
|
|
197
|
+
*
|
|
198
|
+
* @param value - Navigation candidate to parse.
|
|
199
|
+
* @returns Frozen navigation item, or undefined for invalid data.
|
|
200
|
+
*/
|
|
201
|
+
function parseNavigation(value) {
|
|
202
|
+
if (!isPlainRecord(value) || !hasOnlyKeys(value, navigationKeys))
|
|
203
|
+
return undefined;
|
|
204
|
+
if (!isMiaixzModuleIdentifier(value.id) || !isMiaixzModuleIdentifier(value.routeId)) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
if (typeof value.labelKey !== "string" || value.labelKey.trim().length === 0)
|
|
208
|
+
return undefined;
|
|
209
|
+
if (value.icon !== undefined && typeof value.icon !== "string")
|
|
210
|
+
return undefined;
|
|
211
|
+
if (typeof value.order !== "number" || !Number.isFinite(value.order))
|
|
212
|
+
return undefined;
|
|
213
|
+
return Object.freeze({
|
|
214
|
+
id: value.id,
|
|
215
|
+
routeId: value.routeId,
|
|
216
|
+
labelKey: value.labelKey,
|
|
217
|
+
...(value.icon === undefined ? {} : { icon: value.icon }),
|
|
218
|
+
order: value.order,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Determines whether a module entry is valid for its loading strategy and environment.
|
|
223
|
+
*
|
|
224
|
+
* @param kind - Module loading strategy.
|
|
225
|
+
* @param entry - Entry candidate to validate.
|
|
226
|
+
* @param environment - Runtime environment controlling localhost iframe support.
|
|
227
|
+
* @returns Whether the entry satisfies the selected strategy.
|
|
228
|
+
*/
|
|
229
|
+
function isValidEntry(kind, entry, environment) {
|
|
230
|
+
if (typeof entry !== "string" || entry.trim().length === 0 || entry !== entry.trim())
|
|
231
|
+
return false;
|
|
232
|
+
if (kind === "integrated")
|
|
233
|
+
return true;
|
|
234
|
+
try {
|
|
235
|
+
const url = new URL(entry);
|
|
236
|
+
return (url.protocol === "https:" ||
|
|
237
|
+
(environment === "test" && url.protocol === "http:" && url.hostname === "localhost"));
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Parses, validates, sorts, and deeply freezes a remote module manifest.
|
|
245
|
+
*
|
|
246
|
+
* @param value - Untrusted manifest candidate.
|
|
247
|
+
* @param options - Optional runtime environment and concrete host version.
|
|
248
|
+
* @returns A deeply immutable manifest copy owned by the SDK.
|
|
249
|
+
* @throws MiaixzSdkError With `MODULE_MANIFEST_INVALID` for malformed manifest data.
|
|
250
|
+
* @throws MiaixzSdkError With `MODULE_HOST_INCOMPATIBLE` for an incompatible concrete host.
|
|
251
|
+
* @public
|
|
252
|
+
*/
|
|
253
|
+
export function parseMiaixzModuleManifest(value, options = {}) {
|
|
254
|
+
if (!isPlainRecord(value) || !hasOnlyKeys(value, manifestKeys))
|
|
255
|
+
throw invalidManifest();
|
|
256
|
+
const environment = options.environment ?? "production";
|
|
257
|
+
if (!environments.has(environment))
|
|
258
|
+
throw invalidManifest();
|
|
259
|
+
if (value.protocolVersion !== MIAIXZ_MODULE_PROTOCOL_VERSION)
|
|
260
|
+
throw invalidManifest();
|
|
261
|
+
if (!isMiaixzModuleIdentifier(value.id))
|
|
262
|
+
throw invalidManifest();
|
|
263
|
+
if (typeof value.version !== "string" || !parseSemanticVersion(value.version)) {
|
|
264
|
+
throw invalidManifest();
|
|
265
|
+
}
|
|
266
|
+
if (typeof value.hostVersion !== "string" || !parseHostVersion(value.hostVersion)) {
|
|
267
|
+
throw invalidManifest();
|
|
268
|
+
}
|
|
269
|
+
if (value.kind !== "integrated" && value.kind !== "iframe")
|
|
270
|
+
throw invalidManifest();
|
|
271
|
+
if (!isMiaixzModulePath(value.basePath))
|
|
272
|
+
throw invalidManifest();
|
|
273
|
+
const basePath = value.basePath;
|
|
274
|
+
if (!isValidEntry(value.kind, value.entry, environment))
|
|
275
|
+
throw invalidManifest();
|
|
276
|
+
if (!Array.isArray(value.routes) || !Array.isArray(value.navigation))
|
|
277
|
+
throw invalidManifest();
|
|
278
|
+
if (!isMiaixzModulePermissionList(value.requiredPermissions))
|
|
279
|
+
throw invalidManifest();
|
|
280
|
+
if (!Array.isArray(value.requiredCapabilities) ||
|
|
281
|
+
!value.requiredCapabilities.every((capability) => typeof capability === "string" && capabilities.has(capability))) {
|
|
282
|
+
throw invalidManifest();
|
|
283
|
+
}
|
|
284
|
+
const routes = value.routes.map((route) => parseRoute(route, basePath));
|
|
285
|
+
if (routes.some((route) => route === undefined))
|
|
286
|
+
throw invalidManifest();
|
|
287
|
+
const navigation = value.navigation.map(parseNavigation);
|
|
288
|
+
if (navigation.some((item) => item === undefined))
|
|
289
|
+
throw invalidManifest();
|
|
290
|
+
const parsedRoutes = routes;
|
|
291
|
+
const parsedNavigation = navigation;
|
|
292
|
+
const routeIds = new Set(parsedRoutes.map((route) => route.id));
|
|
293
|
+
const navigationIds = new Set(parsedNavigation.map((item) => item.id));
|
|
294
|
+
if (routeIds.size !== parsedRoutes.length || navigationIds.size !== parsedNavigation.length) {
|
|
295
|
+
throw invalidManifest();
|
|
296
|
+
}
|
|
297
|
+
if (parsedNavigation.some((item) => !routeIds.has(item.routeId)))
|
|
298
|
+
throw invalidManifest();
|
|
299
|
+
if (options.hostVersion !== undefined &&
|
|
300
|
+
!isMiaixzHostVersionCompatible(options.hostVersion, value.hostVersion)) {
|
|
301
|
+
throw incompatibleHost();
|
|
302
|
+
}
|
|
303
|
+
return Object.freeze({
|
|
304
|
+
protocolVersion: MIAIXZ_MODULE_PROTOCOL_VERSION,
|
|
305
|
+
id: value.id,
|
|
306
|
+
version: value.version,
|
|
307
|
+
hostVersion: value.hostVersion,
|
|
308
|
+
kind: value.kind,
|
|
309
|
+
basePath,
|
|
310
|
+
entry: value.entry,
|
|
311
|
+
routes: Object.freeze([...parsedRoutes]),
|
|
312
|
+
navigation: Object.freeze([...parsedNavigation].sort(compareMiaixzModuleNavigation)),
|
|
313
|
+
requiredPermissions: Object.freeze([...value.requiredPermissions]),
|
|
314
|
+
requiredCapabilities: Object.freeze([...value.requiredCapabilities]),
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=module-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-manifest.js","sourceRoot":"","sources":["../../src/contracts/module-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { MiaixzSdkError } from \"../api/errors.js\";\nimport { translateMiaixzDefaultMessage } from \"../i18n/default-translator.js\";\nimport type { MiaixzEnvironment } from \"../types/index.js\";\nimport { compareMiaixzModuleNavigation, type MiaixzModuleNavigationItem } from \"./navigation.js\";\nimport {\n isMiaixzModuleIdentifier,\n isMiaixzModulePath,\n isMiaixzModulePermissionList,\n type MiaixzModuleRoute,\n} from \"./route.js\";\n\n/**\n * Version of the Miaixz micro-frontend manifest and lifecycle protocol.\n *\n * @public\n */\nexport const MIAIXZ_MODULE_PROTOCOL_VERSION = \"1.0.0\" as const;\n\n/**\n * Identifies how a module is loaded and isolated by its host.\n *\n * @public\n */\nexport type MiaixzModuleKind = \"integrated\" | \"iframe\";\n\n/**\n * Identifies one host capability that a module may require.\n *\n * @public\n */\nexport type MiaixzHostCapability = \"context\" | \"events\" | \"i18n\" | \"navigation\" | \"permissions\";\n\n/**\n * Describes a pure-data manifest for one independently deployed frontend module.\n *\n * @public\n */\nexport interface MiaixzModuleManifest {\n /**\n * Protocol version understood by the module.\n */\n readonly protocolVersion: \"1.0.0\";\n\n /**\n * Globally stable kebab-case module identifier.\n */\n readonly id: string;\n\n /**\n * Complete semantic version of the module release.\n */\n readonly version: string;\n\n /**\n * Caret range describing the minimum compatible host release.\n */\n readonly hostVersion: string;\n\n /**\n * Loading and isolation strategy used by the module.\n */\n readonly kind: MiaixzModuleKind;\n\n /**\n * Static host path reserved for the module.\n */\n readonly basePath: string;\n\n /**\n * Integrated module identifier or iframe deployment URL.\n */\n readonly entry: string;\n\n /**\n * Routes contributed by the module.\n */\n readonly routes: readonly MiaixzModuleRoute[];\n\n /**\n * Navigation items contributed by the module.\n */\n readonly navigation: readonly MiaixzModuleNavigationItem[];\n\n /**\n * Permissions required before the module may load.\n */\n readonly requiredPermissions: readonly string[];\n\n /**\n * Host capabilities required by the module.\n */\n readonly requiredCapabilities: readonly MiaixzHostCapability[];\n}\n\n/**\n * Configures environment-specific and host-version manifest validation.\n *\n * @public\n */\nexport interface MiaixzModuleManifestParseOptions {\n /**\n * Runtime environment used to validate iframe URLs.\n *\n * @defaultValue `\"production\"`\n */\n readonly environment?: MiaixzEnvironment;\n\n /**\n * Optional concrete host version checked against the manifest range.\n */\n readonly hostVersion?: string;\n}\n\ninterface MiaixzParsedSemanticVersion {\n /**\n * Major semantic-version number.\n */\n readonly major: number;\n\n /**\n * Minor semantic-version number.\n */\n readonly minor: number;\n\n /**\n * Patch semantic-version number.\n */\n readonly patch: number;\n\n /**\n * Optional prerelease identifiers.\n */\n readonly prerelease: readonly string[];\n}\n\nconst manifestKeys = new Set([\n \"protocolVersion\",\n \"id\",\n \"version\",\n \"hostVersion\",\n \"kind\",\n \"basePath\",\n \"entry\",\n \"routes\",\n \"navigation\",\n \"requiredPermissions\",\n \"requiredCapabilities\",\n]);\nconst routeKeys = new Set([\"id\", \"path\", \"titleKey\", \"requiredPermissions\"]);\nconst navigationKeys = new Set([\"id\", \"routeId\", \"labelKey\", \"icon\", \"order\"]);\nconst environments = new Set<MiaixzEnvironment>([\"development\", \"test\", \"staging\", \"production\"]);\nconst capabilities = new Set<MiaixzHostCapability>([\n \"context\",\n \"events\",\n \"i18n\",\n \"navigation\",\n \"permissions\",\n]);\nconst semanticVersionPattern =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*))*))?$/;\nconst hostVersionPattern = /^\\^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/;\n\n/**\n * Creates the frozen manifest-validation error without including untrusted values.\n *\n * @returns Manifest-validation error using the registered public error code.\n */\nfunction invalidManifest(): MiaixzSdkError {\n return new MiaixzSdkError(translateMiaixzDefaultMessage(\"sdk.error.module.manifestInvalid\"), {\n code: \"MODULE_MANIFEST_INVALID\",\n });\n}\n\n/**\n * Creates the frozen host-version compatibility error without including version values.\n *\n * @returns Host-compatibility error using the registered public error code.\n */\nfunction incompatibleHost(): MiaixzSdkError {\n return new MiaixzSdkError(translateMiaixzDefaultMessage(\"sdk.error.module.hostIncompatible\"), {\n code: \"MODULE_HOST_INCOMPATIBLE\",\n });\n}\n\n/**\n * Determines whether a value is a plain JSON-style record.\n *\n * @param value - Value to inspect.\n * @returns Whether the value is a plain record without a custom prototype.\n */\nfunction isPlainRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Determines whether a record contains exactly the allowed field names.\n *\n * @param value - Record whose keys should be checked.\n * @param allowed - Complete allowed key set.\n * @returns Whether every own enumerable key is allowed.\n */\nfunction hasOnlyKeys(\n value: Readonly<Record<string, unknown>>,\n allowed: ReadonlySet<string>,\n): boolean {\n return Object.keys(value).every((key) => allowed.has(key));\n}\n\n/**\n * Parses a complete semantic version without build metadata.\n *\n * @param value - Version candidate to parse.\n * @returns Parsed semantic version, or undefined for invalid syntax.\n */\nfunction parseSemanticVersion(value: string): MiaixzParsedSemanticVersion | undefined {\n const match = semanticVersionPattern.exec(value);\n if (!match) return undefined;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: Object.freeze(match[4]?.split(\".\") ?? []),\n };\n}\n\n/**\n * Parses the only host-version range syntax accepted by module manifests.\n *\n * @param value - Host range candidate to parse.\n * @returns Parsed range floor, or undefined for invalid syntax.\n */\nfunction parseHostVersion(value: string): MiaixzParsedSemanticVersion | undefined {\n const match = hostVersionPattern.exec(value);\n if (!match) return undefined;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: Object.freeze([]),\n };\n}\n\n/**\n * Compares two parsed semantic versions using standard prerelease precedence.\n *\n * @param first - First semantic version.\n * @param second - Second semantic version.\n * @returns Negative, zero, or positive precedence result.\n */\nfunction compareSemanticVersions(\n first: MiaixzParsedSemanticVersion,\n second: MiaixzParsedSemanticVersion,\n): number {\n const core =\n first.major - second.major || first.minor - second.minor || first.patch - second.patch;\n if (core !== 0) return core;\n if (first.prerelease.length === 0) return second.prerelease.length === 0 ? 0 : 1;\n if (second.prerelease.length === 0) return -1;\n const length = Math.max(first.prerelease.length, second.prerelease.length);\n for (let index = 0; index < length; index += 1) {\n const left = first.prerelease[index];\n const right = second.prerelease[index];\n if (left === undefined) return -1;\n if (right === undefined) return 1;\n if (left === right) continue;\n const leftNumeric = /^\\d+$/.test(left);\n const rightNumeric = /^\\d+$/.test(right);\n if (leftNumeric && rightNumeric) return Number(left) - Number(right);\n if (leftNumeric) return -1;\n if (rightNumeric) return 1;\n return left.localeCompare(right);\n }\n return 0;\n}\n\n/**\n * Determines whether a concrete host satisfies the frozen caret-range compatibility rule.\n *\n * @param hostVersion - Concrete complete semantic version of the host.\n * @param requiredHostVersion - Required caret range in `^MAJOR.MINOR.PATCH` form.\n * @returns Whether majors match and the host is at least the required range floor.\n * @public\n */\nexport function isMiaixzHostVersionCompatible(\n hostVersion: string,\n requiredHostVersion: string,\n): boolean {\n const host = parseSemanticVersion(hostVersion);\n const required = parseHostVersion(requiredHostVersion);\n return (\n host !== undefined &&\n required !== undefined &&\n host.major === required.major &&\n compareSemanticVersions(host, required) >= 0\n );\n}\n\n/**\n * Parses one route and creates its immutable manifest-owned copy.\n *\n * @param value - Route candidate to parse.\n * @param basePath - Validated module base path.\n * @returns Frozen route copy, or undefined for invalid data.\n */\nfunction parseRoute(value: unknown, basePath: string): Readonly<MiaixzModuleRoute> | undefined {\n if (!isPlainRecord(value) || !hasOnlyKeys(value, routeKeys)) return undefined;\n if (!isMiaixzModuleIdentifier(value.id) || !isMiaixzModulePath(value.path)) return undefined;\n if (typeof value.titleKey !== \"string\" || value.titleKey.trim().length === 0) return undefined;\n if (basePath !== \"/\" && (value.path === basePath || value.path.startsWith(`${basePath}/`))) {\n return undefined;\n }\n if (\n value.requiredPermissions !== undefined &&\n !isMiaixzModulePermissionList(value.requiredPermissions)\n ) {\n return undefined;\n }\n return Object.freeze({\n id: value.id,\n path: value.path,\n titleKey: value.titleKey,\n ...(value.requiredPermissions === undefined\n ? {}\n : { requiredPermissions: Object.freeze([...value.requiredPermissions]) }),\n });\n}\n\n/**\n * Parses one navigation item and creates its immutable manifest-owned copy.\n *\n * @param value - Navigation candidate to parse.\n * @returns Frozen navigation item, or undefined for invalid data.\n */\nfunction parseNavigation(value: unknown): Readonly<MiaixzModuleNavigationItem> | undefined {\n if (!isPlainRecord(value) || !hasOnlyKeys(value, navigationKeys)) return undefined;\n if (!isMiaixzModuleIdentifier(value.id) || !isMiaixzModuleIdentifier(value.routeId)) {\n return undefined;\n }\n if (typeof value.labelKey !== \"string\" || value.labelKey.trim().length === 0) return undefined;\n if (value.icon !== undefined && typeof value.icon !== \"string\") return undefined;\n if (typeof value.order !== \"number\" || !Number.isFinite(value.order)) return undefined;\n return Object.freeze({\n id: value.id,\n routeId: value.routeId,\n labelKey: value.labelKey,\n ...(value.icon === undefined ? {} : { icon: value.icon }),\n order: value.order,\n });\n}\n\n/**\n * Determines whether a module entry is valid for its loading strategy and environment.\n *\n * @param kind - Module loading strategy.\n * @param entry - Entry candidate to validate.\n * @param environment - Runtime environment controlling localhost iframe support.\n * @returns Whether the entry satisfies the selected strategy.\n */\nfunction isValidEntry(\n kind: MiaixzModuleKind,\n entry: unknown,\n environment: MiaixzEnvironment,\n): entry is string {\n if (typeof entry !== \"string\" || entry.trim().length === 0 || entry !== entry.trim())\n return false;\n if (kind === \"integrated\") return true;\n try {\n const url = new URL(entry);\n return (\n url.protocol === \"https:\" ||\n (environment === \"test\" && url.protocol === \"http:\" && url.hostname === \"localhost\")\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Parses, validates, sorts, and deeply freezes a remote module manifest.\n *\n * @param value - Untrusted manifest candidate.\n * @param options - Optional runtime environment and concrete host version.\n * @returns A deeply immutable manifest copy owned by the SDK.\n * @throws MiaixzSdkError With `MODULE_MANIFEST_INVALID` for malformed manifest data.\n * @throws MiaixzSdkError With `MODULE_HOST_INCOMPATIBLE` for an incompatible concrete host.\n * @public\n */\nexport function parseMiaixzModuleManifest(\n value: unknown,\n options: Readonly<MiaixzModuleManifestParseOptions> = {},\n): Readonly<MiaixzModuleManifest> {\n if (!isPlainRecord(value) || !hasOnlyKeys(value, manifestKeys)) throw invalidManifest();\n const environment = options.environment ?? \"production\";\n if (!environments.has(environment)) throw invalidManifest();\n if (value.protocolVersion !== MIAIXZ_MODULE_PROTOCOL_VERSION) throw invalidManifest();\n if (!isMiaixzModuleIdentifier(value.id)) throw invalidManifest();\n if (typeof value.version !== \"string\" || !parseSemanticVersion(value.version)) {\n throw invalidManifest();\n }\n if (typeof value.hostVersion !== \"string\" || !parseHostVersion(value.hostVersion)) {\n throw invalidManifest();\n }\n if (value.kind !== \"integrated\" && value.kind !== \"iframe\") throw invalidManifest();\n if (!isMiaixzModulePath(value.basePath)) throw invalidManifest();\n const basePath = value.basePath;\n if (!isValidEntry(value.kind, value.entry, environment)) throw invalidManifest();\n if (!Array.isArray(value.routes) || !Array.isArray(value.navigation)) throw invalidManifest();\n if (!isMiaixzModulePermissionList(value.requiredPermissions)) throw invalidManifest();\n if (\n !Array.isArray(value.requiredCapabilities) ||\n !value.requiredCapabilities.every(\n (capability): capability is MiaixzHostCapability =>\n typeof capability === \"string\" && capabilities.has(capability as MiaixzHostCapability),\n )\n ) {\n throw invalidManifest();\n }\n\n const routes = value.routes.map((route) => parseRoute(route, basePath));\n if (routes.some((route) => route === undefined)) throw invalidManifest();\n const navigation = value.navigation.map(parseNavigation);\n if (navigation.some((item) => item === undefined)) throw invalidManifest();\n const parsedRoutes = routes as readonly Readonly<MiaixzModuleRoute>[];\n const parsedNavigation = navigation as readonly Readonly<MiaixzModuleNavigationItem>[];\n const routeIds = new Set(parsedRoutes.map((route) => route.id));\n const navigationIds = new Set(parsedNavigation.map((item) => item.id));\n if (routeIds.size !== parsedRoutes.length || navigationIds.size !== parsedNavigation.length) {\n throw invalidManifest();\n }\n if (parsedNavigation.some((item) => !routeIds.has(item.routeId))) throw invalidManifest();\n if (\n options.hostVersion !== undefined &&\n !isMiaixzHostVersionCompatible(options.hostVersion, value.hostVersion)\n ) {\n throw incompatibleHost();\n }\n\n return Object.freeze({\n protocolVersion: MIAIXZ_MODULE_PROTOCOL_VERSION,\n id: value.id,\n version: value.version,\n hostVersion: value.hostVersion,\n kind: value.kind,\n basePath,\n entry: value.entry,\n routes: Object.freeze([...parsedRoutes]),\n navigation: Object.freeze([...parsedNavigation].sort(compareMiaixzModuleNavigation)),\n requiredPermissions: Object.freeze([...value.requiredPermissions]),\n requiredCapabilities: Object.freeze([...value.requiredCapabilities]),\n });\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes a navigation item contributed by a remotely loaded Miaixz module.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface MiaixzModuleNavigationItem {
|
|
7
|
+
/**
|
|
8
|
+
* Module-local navigation item identifier.
|
|
9
|
+
*/
|
|
10
|
+
readonly id: string;
|
|
11
|
+
/**
|
|
12
|
+
* Identifier of a route declared by the same manifest.
|
|
13
|
+
*/
|
|
14
|
+
readonly routeId: string;
|
|
15
|
+
/**
|
|
16
|
+
* Internationalization key used for the navigation label.
|
|
17
|
+
*/
|
|
18
|
+
readonly labelKey: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional UI icon name interpreted by the host application.
|
|
21
|
+
*/
|
|
22
|
+
readonly icon?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Numeric position used before the identifier tie-breaker.
|
|
25
|
+
*/
|
|
26
|
+
readonly order: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Compares navigation items using the frozen order and identifier sort rules.
|
|
30
|
+
*
|
|
31
|
+
* @param first - First navigation item to compare.
|
|
32
|
+
* @param second - Second navigation item to compare.
|
|
33
|
+
* @returns Negative, zero, or positive sort result.
|
|
34
|
+
*/
|
|
35
|
+
export declare function compareMiaixzModuleNavigation(first: MiaixzModuleNavigationItem, second: MiaixzModuleNavigationItem): number;
|
|
36
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/contracts/navigation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,0BAA0B,EACjC,MAAM,EAAE,0BAA0B,GACjC,MAAM,CAER"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares navigation items using the frozen order and identifier sort rules.
|
|
3
|
+
*
|
|
4
|
+
* @param first - First navigation item to compare.
|
|
5
|
+
* @param second - Second navigation item to compare.
|
|
6
|
+
* @returns Negative, zero, or positive sort result.
|
|
7
|
+
*/
|
|
8
|
+
export function compareMiaixzModuleNavigation(first, second) {
|
|
9
|
+
return first.order - second.order || first.id.localeCompare(second.id);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/contracts/navigation.ts"],"names":[],"mappings":"AAgCA;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,KAAiC,EACjC,MAAkC;IAElC,OAAO,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC","sourcesContent":["/**\n * Describes a navigation item contributed by a remotely loaded Miaixz module.\n *\n * @public\n */\nexport interface MiaixzModuleNavigationItem {\n /**\n * Module-local navigation item identifier.\n */\n readonly id: string;\n\n /**\n * Identifier of a route declared by the same manifest.\n */\n readonly routeId: string;\n\n /**\n * Internationalization key used for the navigation label.\n */\n readonly labelKey: string;\n\n /**\n * Optional UI icon name interpreted by the host application.\n */\n readonly icon?: string;\n\n /**\n * Numeric position used before the identifier tie-breaker.\n */\n readonly order: number;\n}\n\n/**\n * Compares navigation items using the frozen order and identifier sort rules.\n *\n * @param first - First navigation item to compare.\n * @param second - Second navigation item to compare.\n * @returns Negative, zero, or positive sort result.\n */\nexport function compareMiaixzModuleNavigation(\n first: MiaixzModuleNavigationItem,\n second: MiaixzModuleNavigationItem,\n): number {\n return first.order - second.order || first.id.localeCompare(second.id);\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a value is a non-wildcard permission accepted in module manifests.
|
|
3
|
+
*
|
|
4
|
+
* @param value - Permission candidate to inspect.
|
|
5
|
+
* @returns Whether the value uses the frozen lowercase three-segment format.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isMiaixzModulePermission(value: unknown): value is string;
|
|
8
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/contracts/permission.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matches one non-wildcard module permission in namespace, resource, and action form.
|
|
3
|
+
*/
|
|
4
|
+
const modulePermissionPattern = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/;
|
|
5
|
+
/**
|
|
6
|
+
* Determines whether a value is a non-wildcard permission accepted in module manifests.
|
|
7
|
+
*
|
|
8
|
+
* @param value - Permission candidate to inspect.
|
|
9
|
+
* @returns Whether the value uses the frozen lowercase three-segment format.
|
|
10
|
+
*/
|
|
11
|
+
export function isMiaixzModulePermission(value) {
|
|
12
|
+
return typeof value === "string" && modulePermissionPattern.test(value);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=permission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.js","sourceRoot":"","sources":["../../src/contracts/permission.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,uBAAuB,GAAG,mDAAmD,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * Matches one non-wildcard module permission in namespace, resource, and action form.\n */\nconst modulePermissionPattern = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/;\n\n/**\n * Determines whether a value is a non-wildcard permission accepted in module manifests.\n *\n * @param value - Permission candidate to inspect.\n * @returns Whether the value uses the frozen lowercase three-segment format.\n */\nexport function isMiaixzModulePermission(value: unknown): value is string {\n return typeof value === \"string\" && modulePermissionPattern.test(value);\n}\n"]}
|