@segmentstream/app 0.0.0-stage → 0.38.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 +201 -0
- package/NOTICE +2 -0
- package/README.md +1236 -2
- package/dist/agent.d.ts +56 -0
- package/dist/agent.js +203 -0
- package/dist/app.d.ts +82 -0
- package/dist/app.js +434 -0
- package/dist/browser-auth-capability.d.ts +2 -0
- package/dist/browser-auth-capability.js +2 -0
- package/dist/browser-revision.d.ts +19 -0
- package/dist/browser-revision.js +140 -0
- package/dist/channel-protocol.d.ts +16 -0
- package/dist/channel-protocol.js +17 -0
- package/dist/channel-session.d.ts +22 -0
- package/dist/channel-session.js +89 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.js +112 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.js +1 -0
- package/dist/cookies.d.ts +56 -0
- package/dist/cookies.js +131 -0
- package/dist/data.d.ts +233 -0
- package/dist/data.js +206 -0
- package/dist/decision-pages.d.ts +14 -0
- package/dist/decision-pages.js +87 -0
- package/dist/deployment.d.ts +30 -0
- package/dist/deployment.js +72 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.js +123 -0
- package/dist/federation.d.ts +24 -0
- package/dist/federation.js +613 -0
- package/dist/groups.d.ts +95 -0
- package/dist/groups.js +280 -0
- package/dist/handlers.d.ts +10 -0
- package/dist/handlers.js +161 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +29 -0
- package/dist/jobs.d.ts +49 -0
- package/dist/jobs.js +40 -0
- package/dist/legacy.d.ts +77 -0
- package/dist/legacy.js +57 -0
- package/dist/logo.d.ts +1 -0
- package/dist/logo.js +25 -0
- package/dist/me.d.ts +42 -0
- package/dist/me.js +54 -0
- package/dist/navigation/build.d.ts +68 -0
- package/dist/navigation/build.js +290 -0
- package/dist/navigation/cli.d.ts +19 -0
- package/dist/navigation/cli.js +37 -0
- package/dist/navigation/generate.d.ts +43 -0
- package/dist/navigation/generate.js +138 -0
- package/dist/navigation/next.d.ts +10 -0
- package/dist/navigation/next.js +18 -0
- package/dist/navigation-protocol.d.ts +55 -0
- package/dist/navigation-protocol.js +298 -0
- package/dist/neon.d.ts +101 -0
- package/dist/neon.js +539 -0
- package/dist/oauth-completion.d.ts +6 -0
- package/dist/oauth-completion.js +106 -0
- package/dist/oauth.d.ts +59 -0
- package/dist/oauth.js +129 -0
- package/dist/ontology-names.d.ts +10 -0
- package/dist/ontology-names.js +38 -0
- package/dist/ontology-transport.d.ts +34 -0
- package/dist/ontology-transport.js +130 -0
- package/dist/ontology-wire.d.ts +66 -0
- package/dist/ontology-wire.js +355 -0
- package/dist/ontology.d.ts +381 -0
- package/dist/ontology.js +367 -0
- package/dist/pages.d.ts +6 -0
- package/dist/pages.js +6 -0
- package/dist/parameters.d.ts +55 -0
- package/dist/parameters.js +118 -0
- package/dist/permissions.d.ts +19 -0
- package/dist/permissions.js +55 -0
- package/dist/pkce.d.ts +8 -0
- package/dist/pkce.js +40 -0
- package/dist/proxy.d.ts +25 -0
- package/dist/proxy.js +135 -0
- package/dist/request-timing.d.ts +6 -0
- package/dist/request-timing.js +53 -0
- package/dist/return-to.d.ts +2 -0
- package/dist/return-to.js +24 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +80 -0
- package/dist/sessions.d.ts +27 -0
- package/dist/sessions.js +72 -0
- package/dist/sign-in.d.ts +37 -0
- package/dist/sign-in.js +95 -0
- package/dist/storage.d.ts +79 -0
- package/dist/storage.js +180 -0
- package/dist/telegram-launch.d.ts +7 -0
- package/dist/telegram-launch.js +134 -0
- package/dist/telegram.d.ts +2 -0
- package/dist/telegram.js +6 -0
- package/dist/tokens.d.ts +51 -0
- package/dist/tokens.js +70 -0
- package/dist/ui/agent-connect.d.ts +18 -0
- package/dist/ui/agent-connect.js +23 -0
- package/dist/ui/components.d.ts +27 -0
- package/dist/ui/components.js +71 -0
- package/dist/ui/hooks.d.ts +19 -0
- package/dist/ui/hooks.js +56 -0
- package/dist/ui/index.d.ts +22 -0
- package/dist/ui/index.js +15 -0
- package/dist/ui/navigation.d.ts +5 -0
- package/dist/ui/navigation.js +8 -0
- package/dist/ui/segmentstream-logo.d.ts +2 -0
- package/dist/ui/segmentstream-logo.js +7 -0
- package/dist/ui/sign-in-check.d.ts +14 -0
- package/dist/ui/sign-in-check.js +41 -0
- package/dist/ui/sign-in.d.ts +17 -0
- package/dist/ui/sign-in.js +65 -0
- package/dist/ui/store.d.ts +80 -0
- package/dist/ui/store.js +280 -0
- package/dist/ui/styles.css +249 -0
- package/dist/ui/telegram-sign-in.d.ts +16 -0
- package/dist/ui/telegram-sign-in.js +21 -0
- package/dist/ui/use-browser-sign-in.d.ts +52 -0
- package/dist/ui/use-browser-sign-in.js +169 -0
- package/dist/ui/use-channel-sign-in.d.ts +10 -0
- package/dist/ui/use-channel-sign-in.js +118 -0
- package/dist/ui/use-sign-in.d.ts +109 -0
- package/dist/ui/use-sign-in.js +304 -0
- package/package.json +95 -4
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import { NOT_INVITED, SIGN_IN_LINK_INVALID } from "../errors.js";
|
|
4
|
+
import { safeReturnTo } from "../return-to.js";
|
|
5
|
+
import { useSession } from "./hooks.js";
|
|
6
|
+
import { navigate } from "./navigation.js";
|
|
7
|
+
import { checkSignIn } from "./sign-in-check.js";
|
|
8
|
+
import { appSignInConfiguration, authClient, clearSession, endBrowserSession, refreshSession, } from "./store.js";
|
|
9
|
+
/** Seconds before another code or link may be requested. */
|
|
10
|
+
const RESEND_AFTER_SECONDS = 30;
|
|
11
|
+
const CODE_LENGTH = 6;
|
|
12
|
+
/** The SDK's sentence for each {@link SignInErrorCode}. */
|
|
13
|
+
export const SIGN_IN_ERROR_MESSAGES = {
|
|
14
|
+
email_required: "Enter your email address.",
|
|
15
|
+
email_invalid: "Enter a valid email address.",
|
|
16
|
+
not_invited: "This app has not invited this address. Check it, or ask your administrator for an invitation.",
|
|
17
|
+
code_incomplete: `Enter the ${CODE_LENGTH}-digit code from the email.`,
|
|
18
|
+
code_invalid: "That code is not right. Check the email and try again.",
|
|
19
|
+
code_expired: "That code has expired. Send a new one.",
|
|
20
|
+
too_many_attempts: "Too many wrong codes. Send a new code.",
|
|
21
|
+
rate_limited: "Too many requests. Wait a minute, then try again.",
|
|
22
|
+
unavailable: "Sign-in is unavailable right now. Try again in a moment.",
|
|
23
|
+
failed: "Sign-in failed. Try again.",
|
|
24
|
+
};
|
|
25
|
+
const noSubscription = () => () => { };
|
|
26
|
+
/** The page's fragment, with its `#`; empty during server rendering. */
|
|
27
|
+
function useLocationHash() {
|
|
28
|
+
return useSyncExternalStore(noSubscription, () => window.location.hash, () => "");
|
|
29
|
+
}
|
|
30
|
+
/** The page's own query string; empty during server rendering. */
|
|
31
|
+
function useSearchParameter(name) {
|
|
32
|
+
const search = useSyncExternalStore(noSubscription, () => window.location.search, () => "");
|
|
33
|
+
return new URLSearchParams(search).get(name);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The address and code that a sign-in code email's link carries in the sign-in page's fragment, as
|
|
37
|
+
* the platform writes it for apps that declare `signIn.codeLink`:
|
|
38
|
+
* `/sign-in#code=482915&email=ada%40example.com`. Browsers never send the fragment to a server.
|
|
39
|
+
*/
|
|
40
|
+
export function signInCodeFromLink(hash) {
|
|
41
|
+
const fragment = new URLSearchParams(hash.startsWith("#") ? hash.slice(1) : hash);
|
|
42
|
+
const code = fragment.get("code") ?? "";
|
|
43
|
+
const email = fragment.get("email")?.trim() ?? "";
|
|
44
|
+
return new RegExp(`^[0-9]{${CODE_LENGTH}}$`).test(code) && email.includes("@")
|
|
45
|
+
? { email, code }
|
|
46
|
+
: null;
|
|
47
|
+
}
|
|
48
|
+
function noticeFor(notice, email) {
|
|
49
|
+
switch (notice) {
|
|
50
|
+
case "code_resent":
|
|
51
|
+
return `We sent a new code to ${email}.`;
|
|
52
|
+
case "link_resent":
|
|
53
|
+
return `We sent a new sign-in link to ${email}.`;
|
|
54
|
+
case null:
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Email sign-in with Neon Auth, without markup. The ontology first says whether the address may
|
|
60
|
+
* sign in (`POST /api/ontology/sign-in/check`): a member with a Neon Auth account gets a six-digit
|
|
61
|
+
* code, a first sign-in gets a sign-in link, which creates the account, and an address the ontology
|
|
62
|
+
* refuses gets `not_invited` without an email. Without an ontology to ask, every address gets a
|
|
63
|
+
* code. `<SignIn />` renders it with the SDK's own styles; apps with their own design system render
|
|
64
|
+
* the controller themselves.
|
|
65
|
+
*/
|
|
66
|
+
export function useSignIn({ returnTo, error: reason } = {}) {
|
|
67
|
+
const session = useSession();
|
|
68
|
+
const pageReturnTo = useSearchParameter("returnTo");
|
|
69
|
+
const pageError = useSearchParameter("error");
|
|
70
|
+
const [step, setStep] = useState("email");
|
|
71
|
+
const [email, setEmail] = useState("");
|
|
72
|
+
const [code, setCode] = useState("");
|
|
73
|
+
const [pending, setPending] = useState(null);
|
|
74
|
+
const [errorCode, setErrorCode] = useState(null);
|
|
75
|
+
const [noticeCode, setNoticeCode] = useState(null);
|
|
76
|
+
const [resendIn, setResendIn] = useState(0);
|
|
77
|
+
const [switchingAccount, setSwitchingAccount] = useState(false);
|
|
78
|
+
const [codeFromLink, setCodeFromLink] = useState(false);
|
|
79
|
+
const [segmentstreamEnabled, setSegmentstreamEnabled] = useState(false);
|
|
80
|
+
const [emailEnabled, setEmailEnabled] = useState(true);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
let active = true;
|
|
83
|
+
void appSignInConfiguration().then((body) => {
|
|
84
|
+
if (active) {
|
|
85
|
+
setSegmentstreamEnabled(body?.enabled === true);
|
|
86
|
+
setEmailEnabled(body?.neon !== false);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return () => {
|
|
90
|
+
active = false;
|
|
91
|
+
};
|
|
92
|
+
}, []);
|
|
93
|
+
// A code email's link fills in its address and code once, during the first client render.
|
|
94
|
+
const linked = signInCodeFromLink(useLocationHash());
|
|
95
|
+
const [linkRead, setLinkRead] = useState(false);
|
|
96
|
+
if (linked !== null && !linkRead) {
|
|
97
|
+
setLinkRead(true);
|
|
98
|
+
setEmail(linked.email);
|
|
99
|
+
setCode(linked.code);
|
|
100
|
+
setStep("code");
|
|
101
|
+
setCodeFromLink(true);
|
|
102
|
+
}
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (linkRead && window.location.hash !== "") {
|
|
105
|
+
// The code stays out of the history and of the address the person might copy.
|
|
106
|
+
window.history.replaceState(window.history.state, "", `${window.location.pathname}${window.location.search}`);
|
|
107
|
+
}
|
|
108
|
+
}, [linkRead]);
|
|
109
|
+
const verifying = useRef(false);
|
|
110
|
+
const resendTimer = useRef(undefined);
|
|
111
|
+
const destination = safeReturnTo(returnTo ?? pageReturnTo);
|
|
112
|
+
const why = reason ?? pageError;
|
|
113
|
+
useEffect(() => () => clearInterval(resendTimer.current), []);
|
|
114
|
+
function holdResend() {
|
|
115
|
+
const deadline = Date.now() + RESEND_AFTER_SECONDS * 1000;
|
|
116
|
+
clearInterval(resendTimer.current);
|
|
117
|
+
setResendIn(RESEND_AFTER_SECONDS);
|
|
118
|
+
resendTimer.current = setInterval(() => {
|
|
119
|
+
const remaining = Math.max(0, Math.ceil((deadline - Date.now()) / 1000));
|
|
120
|
+
setResendIn(remaining);
|
|
121
|
+
if (remaining === 0) {
|
|
122
|
+
clearInterval(resendTimer.current);
|
|
123
|
+
}
|
|
124
|
+
}, 1000);
|
|
125
|
+
}
|
|
126
|
+
function clearMessages() {
|
|
127
|
+
setErrorCode(null);
|
|
128
|
+
setNoticeCode(null);
|
|
129
|
+
}
|
|
130
|
+
/** Runs a Neon Auth call that emails the person; on success it holds the next one back. */
|
|
131
|
+
async function send(call) {
|
|
132
|
+
const result = await attempt(call);
|
|
133
|
+
if (result !== null) {
|
|
134
|
+
setErrorCode(signInErrorCode(result));
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
holdResend();
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
function sendCode(address) {
|
|
141
|
+
return send(() => authClient().emailOtp.sendVerificationOtp({ email: address, type: "sign-in" }));
|
|
142
|
+
}
|
|
143
|
+
function sendLink(address) {
|
|
144
|
+
// Neon Auth checks the callback against the app's trusted origins, so it is absolute.
|
|
145
|
+
const callbackURL = new URL(destination, window.location.origin).href;
|
|
146
|
+
return send(() => authClient().signIn.magicLink({ email: address, callbackURL }));
|
|
147
|
+
}
|
|
148
|
+
async function submitEmail() {
|
|
149
|
+
if (!emailEnabled) {
|
|
150
|
+
setErrorCode("unavailable");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const address = email.trim();
|
|
154
|
+
if (address === "") {
|
|
155
|
+
setErrorCode("email_required");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
setPending("send");
|
|
159
|
+
clearMessages();
|
|
160
|
+
const outcome = await checkSignIn(address);
|
|
161
|
+
if (outcome !== "code" && outcome !== "link") {
|
|
162
|
+
setErrorCode(outcome);
|
|
163
|
+
}
|
|
164
|
+
else if (await (outcome === "code" ? sendCode(address) : sendLink(address))) {
|
|
165
|
+
setEmail(address);
|
|
166
|
+
setCode("");
|
|
167
|
+
setStep(outcome);
|
|
168
|
+
}
|
|
169
|
+
setPending(null);
|
|
170
|
+
}
|
|
171
|
+
async function submitCode(value = code) {
|
|
172
|
+
// The last digit and the Enter key may both submit the same code.
|
|
173
|
+
if (verifying.current) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!new RegExp(`^[0-9]{${CODE_LENGTH}}$`).test(value)) {
|
|
177
|
+
setErrorCode("code_incomplete");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
verifying.current = true;
|
|
181
|
+
setPending("verify");
|
|
182
|
+
clearMessages();
|
|
183
|
+
const result = await attempt(() => authClient().signIn.emailOtp({ email, otp: value }));
|
|
184
|
+
if (result !== null) {
|
|
185
|
+
verifying.current = false;
|
|
186
|
+
setErrorCode(signInErrorCode(result));
|
|
187
|
+
setCode("");
|
|
188
|
+
setCodeFromLink(false);
|
|
189
|
+
setPending(null);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
navigate(destination);
|
|
193
|
+
}
|
|
194
|
+
async function resend() {
|
|
195
|
+
setPending("resend");
|
|
196
|
+
clearMessages();
|
|
197
|
+
if (step === "link") {
|
|
198
|
+
if (await sendLink(email)) {
|
|
199
|
+
setNoticeCode("link_resent");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else if (await sendCode(email)) {
|
|
203
|
+
setCode("");
|
|
204
|
+
setCodeFromLink(false);
|
|
205
|
+
setNoticeCode("code_resent");
|
|
206
|
+
}
|
|
207
|
+
setPending(null);
|
|
208
|
+
}
|
|
209
|
+
function changeEmail() {
|
|
210
|
+
setStep("email");
|
|
211
|
+
setCode("");
|
|
212
|
+
setCodeFromLink(false);
|
|
213
|
+
clearMessages();
|
|
214
|
+
}
|
|
215
|
+
async function switchAccount() {
|
|
216
|
+
setPending("sign-out");
|
|
217
|
+
setErrorCode(null);
|
|
218
|
+
const result = await attempt(async () => {
|
|
219
|
+
await endBrowserSession();
|
|
220
|
+
return { error: null };
|
|
221
|
+
});
|
|
222
|
+
if (result !== null) {
|
|
223
|
+
setErrorCode(signInErrorCode(result));
|
|
224
|
+
setPending(null);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
clearSession();
|
|
228
|
+
await refreshSession();
|
|
229
|
+
setSwitchingAccount(true);
|
|
230
|
+
setStep("email");
|
|
231
|
+
setPending(null);
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
emailEnabled,
|
|
235
|
+
segmentstreamSignInUrl: segmentstreamEnabled
|
|
236
|
+
? `/api/segmentstream/sign-in?returnTo=${encodeURIComponent(destination)}`
|
|
237
|
+
: null,
|
|
238
|
+
step,
|
|
239
|
+
email,
|
|
240
|
+
setEmail,
|
|
241
|
+
code,
|
|
242
|
+
setCode,
|
|
243
|
+
pending,
|
|
244
|
+
error: errorCode === null ? null : SIGN_IN_ERROR_MESSAGES[errorCode],
|
|
245
|
+
errorCode,
|
|
246
|
+
notice: noticeFor(noticeCode, email),
|
|
247
|
+
noticeCode,
|
|
248
|
+
resendIn,
|
|
249
|
+
codeLength: CODE_LENGTH,
|
|
250
|
+
destination,
|
|
251
|
+
signedIn: session.status === "signed-in" && !switchingAccount,
|
|
252
|
+
notInvited: why === NOT_INVITED && !switchingAccount,
|
|
253
|
+
linkInvalid: why === SIGN_IN_LINK_INVALID,
|
|
254
|
+
codeFromLink,
|
|
255
|
+
sessionEmail: session.status === "signed-in" ? (session.user.email ?? session.user.name) : null,
|
|
256
|
+
submitEmail,
|
|
257
|
+
submitCode,
|
|
258
|
+
resend,
|
|
259
|
+
changeEmail,
|
|
260
|
+
switchAccount,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/** Runs a Neon Auth client call; its failure, returned or thrown, or `null` on success. */
|
|
264
|
+
async function attempt(call) {
|
|
265
|
+
try {
|
|
266
|
+
const result = await call();
|
|
267
|
+
return result.error ?? null;
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
return error ?? new Error("Sign-in failed.");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/** Why a Neon Auth (Better Auth) call failed. */
|
|
274
|
+
export function signInErrorCode(error) {
|
|
275
|
+
const details = typeof error === "object" && error !== null ? error : {};
|
|
276
|
+
const status = typeof details.status === "number" ? details.status : undefined;
|
|
277
|
+
const text = [details.code, details.message]
|
|
278
|
+
.filter((part) => typeof part === "string")
|
|
279
|
+
.join(" ")
|
|
280
|
+
.toLowerCase();
|
|
281
|
+
if (status === 429 || text.includes("rate limit") || text.includes("too many requests")) {
|
|
282
|
+
return "rate_limited";
|
|
283
|
+
}
|
|
284
|
+
if (text.includes("too many attempts") || text.includes("too_many_attempts")) {
|
|
285
|
+
return "too_many_attempts";
|
|
286
|
+
}
|
|
287
|
+
if (text.includes("expired")) {
|
|
288
|
+
return "code_expired";
|
|
289
|
+
}
|
|
290
|
+
if (text.includes("otp") || text.includes("code")) {
|
|
291
|
+
return "code_invalid";
|
|
292
|
+
}
|
|
293
|
+
if (text.includes("email")) {
|
|
294
|
+
return "email_invalid";
|
|
295
|
+
}
|
|
296
|
+
if (status === undefined || status >= 500 || text.includes("network")) {
|
|
297
|
+
return "unavailable";
|
|
298
|
+
}
|
|
299
|
+
return "failed";
|
|
300
|
+
}
|
|
301
|
+
/** A sentence for a Neon Auth (Better Auth) failure. */
|
|
302
|
+
export function signInErrorMessage(error) {
|
|
303
|
+
return SIGN_IN_ERROR_MESSAGES[signInErrorCode(error)];
|
|
304
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,97 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@segmentstream/app",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.38.0",
|
|
4
|
+
"description": "Sign-in, users, permissions, the ontology client and warehouse data access for SegmentStream workspace apps built with Next.js.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "SegmentStream",
|
|
7
|
+
"homepage": "https://segmentstream.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/segmentstream/segmentstream.git",
|
|
11
|
+
"directory": "packages/app-sdk"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"segmentstream",
|
|
15
|
+
"nextjs",
|
|
16
|
+
"authentication",
|
|
17
|
+
"neon-auth",
|
|
18
|
+
"ontology"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./ui": {
|
|
27
|
+
"types": "./dist/ui/index.d.ts",
|
|
28
|
+
"import": "./dist/ui/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./ui/styles.css": "./dist/ui/styles.css",
|
|
31
|
+
"./storage": {
|
|
32
|
+
"types": "./dist/storage.d.ts",
|
|
33
|
+
"import": "./dist/storage.js"
|
|
34
|
+
},
|
|
35
|
+
"./navigation/build": {
|
|
36
|
+
"types": "./dist/navigation/build.d.ts",
|
|
37
|
+
"import": "./dist/navigation/build.js",
|
|
38
|
+
"default": "./dist/navigation/build.js"
|
|
39
|
+
},
|
|
40
|
+
"./navigation/next": {
|
|
41
|
+
"types": "./dist/navigation/next.d.ts",
|
|
42
|
+
"import": "./dist/navigation/next.js",
|
|
43
|
+
"default": "./dist/navigation/next.js"
|
|
44
|
+
},
|
|
45
|
+
"./browser-auth-capability": {
|
|
46
|
+
"types": "./dist/browser-auth-capability.d.ts",
|
|
47
|
+
"import": "./dist/browser-auth-capability.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
"NOTICE"
|
|
55
|
+
],
|
|
56
|
+
"sideEffects": [
|
|
57
|
+
"**/*.css"
|
|
58
|
+
],
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=20"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "node scripts/prepare-channel-protocol.mjs && node scripts/prepare-navigation-protocol.mjs && rm -rf dist && tsc -p tsconfig.build.json && cp src/ui/styles.css dist/ui/styles.css",
|
|
64
|
+
"typecheck": "node scripts/prepare-channel-protocol.mjs && node scripts/prepare-navigation-protocol.mjs && tsc -p tsconfig.json --noEmit",
|
|
65
|
+
"lint": "node scripts/prepare-channel-protocol.mjs && node scripts/prepare-navigation-protocol.mjs && eslint src tests --config ../../eslint.config.mjs",
|
|
66
|
+
"test": "node scripts/prepare-channel-protocol.mjs && node scripts/prepare-navigation-protocol.mjs && vitest run",
|
|
67
|
+
"prepack": "pnpm run build",
|
|
68
|
+
"test:navigation:integration": "pnpm run build && node --test tests/navigation-build.integration.mjs"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@neondatabase/auth": "0.5.0-beta",
|
|
72
|
+
"jose": "^6.2.12"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"next": ">=16.0.0",
|
|
76
|
+
"react": ">=19.0.0"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@testing-library/react": "^16.3.2",
|
|
80
|
+
"@types/node": "^24",
|
|
81
|
+
"@types/react": "^19",
|
|
82
|
+
"@types/react-dom": "^19",
|
|
83
|
+
"effect": "4.0.0-rc.113",
|
|
84
|
+
"jsdom": "^28.1.0",
|
|
85
|
+
"next": "16.3.8",
|
|
86
|
+
"react": "19.2.8",
|
|
87
|
+
"react-dom": "19.2.8",
|
|
88
|
+
"typescript": "^5.9",
|
|
89
|
+
"vitest": "^4.1.11"
|
|
90
|
+
},
|
|
91
|
+
"publishConfig": {
|
|
92
|
+
"access": "public"
|
|
93
|
+
},
|
|
94
|
+
"bin": {
|
|
95
|
+
"segmentstream-page-catalog": "./dist/navigation/cli.js"
|
|
96
|
+
}
|
|
97
|
+
}
|