@eventusgo/sdk 0.1.2 → 0.1.3
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.d.ts +13 -1
- package/dist/index.js +135 -1
- package/package.json +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,16 @@ type EventusManifest = {
|
|
|
19
19
|
version: string;
|
|
20
20
|
permissions?: Array<EventusPermission | string>;
|
|
21
21
|
};
|
|
22
|
+
type EventusDevPreviewDescriptor = {
|
|
23
|
+
type: "eventus-dev-preview";
|
|
24
|
+
version: 1;
|
|
25
|
+
manifest: EventusManifest;
|
|
26
|
+
urls: {
|
|
27
|
+
local: string;
|
|
28
|
+
network: string | null;
|
|
29
|
+
preview: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
22
32
|
type EventusRuntimeSource = "native" | "mock";
|
|
23
33
|
type EventusEventMap = {
|
|
24
34
|
ready: {
|
|
@@ -49,6 +59,7 @@ type ConfigureMockEventusOptions = {
|
|
|
49
59
|
declare class EventusBridgeUnavailableError extends Error {
|
|
50
60
|
constructor(message?: string);
|
|
51
61
|
}
|
|
62
|
+
declare function isBridgeUnavailableError(error: unknown): boolean;
|
|
52
63
|
type NativeBridgeUser = Record<string, unknown>;
|
|
53
64
|
type NativeBridgeRecord = Record<string, unknown>;
|
|
54
65
|
type NativeEventusBridge = {
|
|
@@ -64,6 +75,7 @@ declare global {
|
|
|
64
75
|
Eventus?: NativeEventusBridge;
|
|
65
76
|
}
|
|
66
77
|
}
|
|
78
|
+
declare function getLivePreviewHtml(): Promise<string | null>;
|
|
67
79
|
declare class EventusClientImpl implements EventusClient {
|
|
68
80
|
private emitter;
|
|
69
81
|
private lastReadySource;
|
|
@@ -82,4 +94,4 @@ declare class EventusClientImpl implements EventusClient {
|
|
|
82
94
|
declare const eventus: EventusClientImpl;
|
|
83
95
|
declare function configureMockEventus(options?: ConfigureMockEventusOptions): void;
|
|
84
96
|
|
|
85
|
-
export { type ConfigureMockEventusOptions, EventusBridgeUnavailableError, type EventusClient, type EventusContext, type EventusEventHandler, type EventusEventMap, type EventusEventName, type EventusManifest, type EventusPermission, type EventusRuntimeSource, type EventusTheme, type EventusUser, configureMockEventus, eventus };
|
|
97
|
+
export { type ConfigureMockEventusOptions, EventusBridgeUnavailableError, type EventusClient, type EventusContext, type EventusDevPreviewDescriptor, type EventusEventHandler, type EventusEventMap, type EventusEventName, type EventusManifest, type EventusPermission, type EventusRuntimeSource, type EventusTheme, type EventusUser, configureMockEventus, eventus, getLivePreviewHtml, isBridgeUnavailableError };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import QRCode from "qrcode";
|
|
2
3
|
var EventusBridgeUnavailableError = class extends Error {
|
|
3
4
|
constructor(message = "No Eventus bridge is connected.") {
|
|
4
5
|
super(message);
|
|
5
6
|
this.name = "EventusBridgeUnavailableError";
|
|
6
7
|
}
|
|
7
8
|
};
|
|
9
|
+
function isBridgeUnavailableError(error) {
|
|
10
|
+
return error instanceof Error && error.name === "EventusBridgeUnavailableError";
|
|
11
|
+
}
|
|
8
12
|
var EventEmitter = class {
|
|
9
13
|
listeners = /* @__PURE__ */ new Map();
|
|
10
14
|
on(event, handler) {
|
|
@@ -53,6 +57,134 @@ function readInjectedManifest() {
|
|
|
53
57
|
}
|
|
54
58
|
return manifest ?? null;
|
|
55
59
|
}
|
|
60
|
+
function escapeHtml(value) {
|
|
61
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
62
|
+
}
|
|
63
|
+
function isAbsoluteHttpUrl(value) {
|
|
64
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const parsed = new URL(value);
|
|
69
|
+
return (parsed.protocol === "http:" || parsed.protocol === "https:") && !!parsed.hostname;
|
|
70
|
+
} catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function parseDevPreviewDescriptor(value) {
|
|
75
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const descriptor = value;
|
|
79
|
+
const manifest = descriptor.manifest;
|
|
80
|
+
const urls = descriptor.urls;
|
|
81
|
+
if (descriptor.type !== "eventus-dev-preview" || descriptor.version !== 1 || !manifest || typeof manifest !== "object" || Array.isArray(manifest) || !urls || typeof urls !== "object" || Array.isArray(urls)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const nextManifest = manifest;
|
|
85
|
+
const nextUrls = urls;
|
|
86
|
+
const permissions = nextManifest.permissions;
|
|
87
|
+
if (typeof nextManifest.name !== "string" || !nextManifest.name.trim() || typeof nextManifest.appId !== "string" || !nextManifest.appId.trim() || typeof nextManifest.version !== "string" || !nextManifest.version.trim() || !isAbsoluteHttpUrl(nextUrls.local) || (nextUrls.network !== null && nextUrls.network !== void 0 ? !isAbsoluteHttpUrl(nextUrls.network) : false) || !isAbsoluteHttpUrl(nextUrls.preview) || permissions !== void 0 && (!Array.isArray(permissions) || permissions.some((permission) => typeof permission !== "string"))) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
type: "eventus-dev-preview",
|
|
92
|
+
version: 1,
|
|
93
|
+
manifest: {
|
|
94
|
+
name: nextManifest.name,
|
|
95
|
+
appId: nextManifest.appId,
|
|
96
|
+
version: nextManifest.version,
|
|
97
|
+
...permissions ? { permissions } : {}
|
|
98
|
+
},
|
|
99
|
+
urls: {
|
|
100
|
+
local: nextUrls.local,
|
|
101
|
+
network: nextUrls.network === void 0 ? null : nextUrls.network,
|
|
102
|
+
preview: nextUrls.preview
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async function fetchDevPreviewDescriptor() {
|
|
107
|
+
if (typeof fetch !== "function") {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const response = await fetch("/__eventus__/preview.json", {
|
|
112
|
+
headers: {
|
|
113
|
+
Accept: "application/json"
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return parseDevPreviewDescriptor(await response.json());
|
|
120
|
+
} catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function renderPreviewValue(label, value) {
|
|
125
|
+
const escaped = escapeHtml(value);
|
|
126
|
+
return `
|
|
127
|
+
<div>
|
|
128
|
+
<dt>${escapeHtml(label)}</dt>
|
|
129
|
+
<dd><code>${escaped}</code></dd>
|
|
130
|
+
</div>
|
|
131
|
+
`;
|
|
132
|
+
}
|
|
133
|
+
function renderPermissions(permissions) {
|
|
134
|
+
const value = permissions && permissions.length > 0 ? permissions.join(", ") : "None";
|
|
135
|
+
return renderPreviewValue("Permissions", value);
|
|
136
|
+
}
|
|
137
|
+
function createLivePreviewHtml(preview, qrSvg) {
|
|
138
|
+
return `
|
|
139
|
+
<section aria-label="Eventus live preview handoff" style="margin:24px 0;display:grid;gap:20px;">
|
|
140
|
+
<style>
|
|
141
|
+
.eventus-live-preview{display:grid;gap:20px;}
|
|
142
|
+
.eventus-live-preview__copy{color:#102347;}
|
|
143
|
+
.eventus-live-preview__copy h2{margin:0 0 12px;font-size:1.4rem;line-height:1.2;}
|
|
144
|
+
.eventus-live-preview__copy p{margin:0;color:#465d82;line-height:1.6;}
|
|
145
|
+
.eventus-live-preview__grid{display:grid;gap:14px;margin:18px 0 0;}
|
|
146
|
+
.eventus-live-preview__grid > div{padding:14px 16px;border-radius:16px;background:#f8fbff;border:1px solid rgba(16,35,71,0.08);}
|
|
147
|
+
.eventus-live-preview__grid dt{font-size:0.72rem;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#6880a6;}
|
|
148
|
+
.eventus-live-preview__grid dd{margin:6px 0 0;color:#102347;word-break:break-word;}
|
|
149
|
+
.eventus-live-preview__grid code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:0.9rem;}
|
|
150
|
+
.eventus-live-preview__hint{margin-top:16px !important;color:#465d82 !important;}
|
|
151
|
+
.eventus-live-preview__qr{display:grid;place-items:center;padding:18px;border-radius:24px;background:linear-gradient(180deg,#fefefe 0%,#f3f7ff 100%);border:1px solid rgba(16,35,71,0.08);box-shadow:0 20px 50px rgba(38,73,134,0.14);}
|
|
152
|
+
.eventus-live-preview__qr svg{display:block;width:min(220px,100%);height:auto;}
|
|
153
|
+
.eventus-live-preview__meta{display:none;}
|
|
154
|
+
@media (min-width: 720px){
|
|
155
|
+
.eventus-live-preview{grid-template-columns:minmax(0,1.7fr) minmax(220px,0.9fr);align-items:center;}
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
158
|
+
<div class="eventus-live-preview">
|
|
159
|
+
<div class="eventus-live-preview__copy">
|
|
160
|
+
<h2>Live preview from your phone</h2>
|
|
161
|
+
<p>Open Eventus X, go to <strong>Developer</strong>, and scan this QR code to launch the mini app with the real Eventus bridge.</p>
|
|
162
|
+
<dl class="eventus-live-preview__grid">
|
|
163
|
+
${renderPreviewValue("Preview URL", preview.urls.preview)}
|
|
164
|
+
${renderPreviewValue("Local URL", preview.urls.local)}
|
|
165
|
+
${preview.urls.network ? renderPreviewValue("Network URL", preview.urls.network) : ""}
|
|
166
|
+
${renderPermissions(preview.manifest.permissions)}
|
|
167
|
+
</dl>
|
|
168
|
+
<p class="eventus-live-preview__hint">Your phone and computer must be on the same local network.</p>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="eventus-live-preview__qr" aria-label="Eventus live preview QR code">
|
|
171
|
+
${qrSvg}
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</section>`.trim();
|
|
175
|
+
}
|
|
176
|
+
async function getLivePreviewHtml() {
|
|
177
|
+
const preview = await fetchDevPreviewDescriptor();
|
|
178
|
+
if (!preview) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const qrSvg = await QRCode.toString(JSON.stringify(preview), {
|
|
182
|
+
type: "svg",
|
|
183
|
+
width: 220,
|
|
184
|
+
margin: 1
|
|
185
|
+
});
|
|
186
|
+
return createLivePreviewHtml(preview, qrSvg);
|
|
187
|
+
}
|
|
56
188
|
function readWindowBridge() {
|
|
57
189
|
if (typeof window === "undefined") {
|
|
58
190
|
return void 0;
|
|
@@ -255,5 +387,7 @@ function configureMockEventus(options = {}) {
|
|
|
255
387
|
export {
|
|
256
388
|
EventusBridgeUnavailableError,
|
|
257
389
|
configureMockEventus,
|
|
258
|
-
eventus
|
|
390
|
+
eventus,
|
|
391
|
+
getLivePreviewHtml,
|
|
392
|
+
isBridgeUnavailableError
|
|
259
393
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventusgo/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Eventus mini-app SDK with an explicit browser mock mode.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,5 +22,11 @@
|
|
|
22
22
|
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
23
23
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
24
24
|
"test": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"qrcode": "1.5.4"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/qrcode": "1.5.5"
|
|
25
31
|
}
|
|
26
32
|
}
|