@gerege-systems/eid-mongolia-sdk 0.14.2 → 0.15.1
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/README.md +176 -54
- package/dist/{browser-CSZjH9Xs.d.cts → browser-8k_VDSP8.d.cts} +8 -183
- package/dist/{browser-CSZjH9Xs.d.ts → browser-BZ3hvv6-.d.ts} +8 -183
- package/dist/browser.d.cts +2 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.js +5 -3
- package/dist/button.cjs +55 -45
- package/dist/button.js +55 -45
- package/dist/chunk-REWNE7PO.js +51 -0
- package/dist/{chunk-DXVHOZO7.js → chunk-TB2KQH3W.js} +1 -46
- package/dist/errors-Z7SgLVTr.d.cts +149 -0
- package/dist/errors-Z7SgLVTr.d.ts +149 -0
- package/dist/index.cjs +270 -256
- package/dist/index.d.cts +169 -159
- package/dist/index.d.ts +169 -159
- package/dist/index.js +256 -241
- package/dist/pades.cjs +3520 -0
- package/dist/pades.d.cts +128 -0
- package/dist/pades.d.ts +128 -0
- package/dist/pades.js +3484 -0
- package/package.json +16 -6
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import './errors-Z7SgLVTr.js';
|
|
2
|
+
|
|
1
3
|
/** Сертификатын баталгаажуулалтын түвшин (eIDAS LoA). QUALIFIED — хууль ёсны гарын үсэгт. */
|
|
2
4
|
type CertificateLevel = "ADVANCED" | "QUALIFIED" | "QSCD";
|
|
3
5
|
/** Гарын үсгийн протокол: auth → ACSP_V2, sign → RAW_DIGEST_SIGNATURE (Smart-ID v3). */
|
|
@@ -177,11 +179,6 @@ interface SessionResult {
|
|
|
177
179
|
* RP энэ талбарыг л итгэж уншина (клиентийн сонголтод биш). docs/ORG_LOGIN.md.
|
|
178
180
|
*/
|
|
179
181
|
onBehalfOf: OrgResult | null;
|
|
180
|
-
/**
|
|
181
|
-
* PAdES (`POST /pdf/sign/prepare`) session-ий `pdf` блок — PDF урсгал биш бол null (талбар алга = хуучин SDK-аар
|
|
182
|
-
* угсарсан объект). {@link PdfSessionBlock}.
|
|
183
|
-
*/
|
|
184
|
-
pdf?: PdfSessionBlock | null;
|
|
185
182
|
/**
|
|
186
183
|
* COMPLETE+OK auth session-ий `person` блок (CA бүртгэлээс: кирилл нэр, төрсөн огноо, хүйс — гэрчилгээнд байдаггүй).
|
|
187
184
|
* Зөвхөн session эзэмшигч RP-д; CA иргэнийг олоогүй бол null. ГАРЫН ҮСЭГТ ОРДОГГҮЙ — validateAuth-ийн дараа
|
|
@@ -223,35 +220,6 @@ interface TokenCertSessionBlock {
|
|
|
223
220
|
authSerialHex?: string;
|
|
224
221
|
signSerialHex?: string;
|
|
225
222
|
}
|
|
226
|
-
/** PDF баримтын төлөв: PENDING → READY (эсвэл FAILED / EXPIRED). */
|
|
227
|
-
type PdfDocumentStatus = "PENDING" | "READY" | "FAILED" | "EXPIRED";
|
|
228
|
-
/** PAdES гаралтын гарын үсэг зурагч. */
|
|
229
|
-
interface PdfSigner {
|
|
230
|
-
etsi: string;
|
|
231
|
-
certSerial: string;
|
|
232
|
-
/** Байгууллагын нэрийн өмнөөс бол байгууллагын ETSI (`NTRMN-…`) — баримтад бичигдсэн утга. */
|
|
233
|
-
onBehalfOf?: string;
|
|
234
|
-
/** CMS signer-attributes-v2-д бичигдсэн мэдүүлсэн үүрэг: «<албан тушаал>, <нэр> (NTRMN-…)». */
|
|
235
|
-
claimedRole?: string;
|
|
236
|
-
}
|
|
237
|
-
/** GET /session/{id}-ийн `pdf` объект (PAdES, CA угсарна). */
|
|
238
|
-
interface PdfSessionBlock {
|
|
239
|
-
docID: string;
|
|
240
|
-
documentStatus: PdfDocumentStatus | string;
|
|
241
|
-
/** FAILED үед — ж: `REPRESENTATION_REVOKED` (prepare-ээс хойш эрх хасагдсан, баримт үүсээгүй). */
|
|
242
|
-
errorCode?: string;
|
|
243
|
-
/** Гарын үсэгтэй PDF-ийн SHA-256 (hex) — татсан файлтай тулгана. */
|
|
244
|
-
outSha256?: string;
|
|
245
|
-
size?: number;
|
|
246
|
-
expiresAt?: string;
|
|
247
|
-
signatureLevel?: string;
|
|
248
|
-
signer?: PdfSigner;
|
|
249
|
-
validation?: {
|
|
250
|
-
indication: string;
|
|
251
|
-
ltv: boolean;
|
|
252
|
-
signatures: number;
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
223
|
/** Иргэний төлөөлж чадах нэг байгууллага (GET /organization/representations/etsi/{personEtsi}). */
|
|
256
224
|
interface Representation {
|
|
257
225
|
/** `NTRMN-<бүртгэл>` — `onBehalfOf`-д өгөх утга. */
|
|
@@ -275,6 +243,11 @@ interface Representation {
|
|
|
275
243
|
source: "REGISTRY" | "MANUAL" | string;
|
|
276
244
|
/** Эх үүсвэрийн хүнд харуулах нэр (REGISTRY → «Улсын бүртгэл», MANUAL → «Захирал нэмсэн»; хэл нь `roleLabel`-тэй ижил). Хуучин CA-д байхгүй. */
|
|
277
245
|
sourceLabel?: string;
|
|
246
|
+
/**
|
|
247
|
+
* CMS signer-attributes-v2-д бичих мэдүүлсэн үүрэг («<албан тушаал>, <нэр> (NTRMN-…)») — клиент талын PAdES-д
|
|
248
|
+
* `pades.prepare({claimedRole})`-д ЯГ ХЭВЭЭР өгнө (CA бүртгэлд дахин тооцож тулгана). Хуучин CA-д байхгүй.
|
|
249
|
+
*/
|
|
250
|
+
claimedRole?: string;
|
|
278
251
|
/** ISO 8601. */
|
|
279
252
|
validFrom: string;
|
|
280
253
|
/** ISO 8601; байхгүй = хугацаагүй. */
|
|
@@ -360,152 +333,4 @@ interface OpenOrShowQROptions {
|
|
|
360
333
|
*/
|
|
361
334
|
declare function openOrShowQR(session: DeviceLinkInput, opts: OpenOrShowQROptions): "opened" | "qr";
|
|
362
335
|
|
|
363
|
-
|
|
364
|
-
declare class EidError extends Error {
|
|
365
|
-
constructor(message: string);
|
|
366
|
-
}
|
|
367
|
-
/** HTTP хариуны нэмэлт мэдээлэл (алдааны төрлүүдэд). */
|
|
368
|
-
interface HttpErrorInit {
|
|
369
|
-
/** Хариуны header-ууд. */
|
|
370
|
-
headers?: Headers;
|
|
371
|
-
/** Retry-After (секунд эсвэл HTTP-огноо задалсан), мс; байхгүй/буруу бол undefined. */
|
|
372
|
-
retryAfterMs?: number;
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* HTTP 401 — API secret буруу/байхгүй. Тохиргооны (RP secret) алдаа. CA-ийн өөрийн 401 нь JSON `{"error"[,"code"]}` —
|
|
376
|
-
* `serverMessage` (ба байвал `code`) бөглөгдөнө; JSON биш (proxy / nginx) бол хоёул undefined — үүгээр CA-ийн 401-ийг
|
|
377
|
-
* proxy-ийнхоос ялгана.
|
|
378
|
-
*/
|
|
379
|
-
declare class AuthenticationError extends EidError {
|
|
380
|
-
/** Серверийн `{"code"}`; байхгүй / JSON биш (proxy) бол undefined. */
|
|
381
|
-
readonly code?: string;
|
|
382
|
-
/** Серверийн `{"error"}` текст (логт); JSON биш (proxy) бол undefined. */
|
|
383
|
-
readonly serverMessage?: string;
|
|
384
|
-
/** Хариуны бие (таслагдаагүй текст). */
|
|
385
|
-
readonly body?: string;
|
|
386
|
-
readonly headers?: Headers;
|
|
387
|
-
constructor(message: string, init?: {
|
|
388
|
-
code?: string;
|
|
389
|
-
serverMessage?: string;
|
|
390
|
-
body?: string;
|
|
391
|
-
headers?: Headers;
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* HTTP 403 — IP allowlist/mTLS зөвшөөрөөгүй, RP-д эрх алга, эсвэл onBehalfOf-ийн төлөөлөл татгалзсан.
|
|
396
|
-
* Сервер `{"error","code"}` буцаасан бол `code` (ж: `REPRESENTATION_DENIED`) — салааллыг үүгээр хийнэ.
|
|
397
|
-
*/
|
|
398
|
-
declare class ForbiddenError extends EidError {
|
|
399
|
-
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
400
|
-
readonly code?: string | undefined;
|
|
401
|
-
readonly headers?: Headers;
|
|
402
|
-
/** Retry-After (мс), байхгүй бол undefined. */
|
|
403
|
-
readonly retryAfterMs?: number;
|
|
404
|
-
constructor(message: string,
|
|
405
|
-
/** Серверийн тогтвортой алдааны код (`{"code"}`), байхгүй бол undefined. */
|
|
406
|
-
code?: string | undefined, init?: HttpErrorInit);
|
|
407
|
-
}
|
|
408
|
-
/** RP-API-аас ирсэн бусад HTTP алдаа (4xx/5xx). status ба хариуны биеийг агуулна. */
|
|
409
|
-
declare class ApiError extends EidError {
|
|
410
|
-
readonly status: number;
|
|
411
|
-
readonly body: string;
|
|
412
|
-
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
413
|
-
readonly code?: string | undefined;
|
|
414
|
-
readonly headers?: Headers;
|
|
415
|
-
/**
|
|
416
|
-
* Retry-After (мс, секунд эсвэл HTTP-огноо задалсан); байхгүй/буруу бол undefined. CA түр алдаанд (429
|
|
417
|
-
* PDF_PREPARE_BUSY / RATE_LIMITED, 503 DOCUMENT_PENDING / TSA_UNAVAILABLE / LTV_UNAVAILABLE г.м.) тавина.
|
|
418
|
-
*/
|
|
419
|
-
readonly retryAfterMs?: number;
|
|
420
|
-
constructor(status: number, body: string,
|
|
421
|
-
/** Серверийн тогтвортой алдааны код (`{"error","code"}`-ийн `code`), байхгүй бол undefined. */
|
|
422
|
-
code?: string | undefined, init?: HttpErrorInit);
|
|
423
|
-
/**
|
|
424
|
-
* CA-ийн түр алдаа ({@link RETRYABLE_ERROR_CODES}-ийн нэг, эсвэл 429/503 + Retry-After): `retryAfterMs`-ийн дараа
|
|
425
|
-
* ижил хүсэлтийг давтаж болно.
|
|
426
|
-
*/
|
|
427
|
-
get retryable(): boolean;
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* 409 `NO_SIGNING_CERTIFICATE` — иргэнд (баримтад) идэвхтэй төхөөрөмж / SIGN credential / хүчинтэй гарын үсгийн
|
|
431
|
-
* гэрчилгээ алга: sign ба certificate-choice session start, `/pdf/sign/prepare`. Session үүсээгүй. Танихгүй
|
|
432
|
-
* лавлагаанд ч ижил хариу (бүртгэл задлахгүй) — хэрэглэгчид «eID гарын үсгийн гэрчилгээгүй» гэж харуулна.
|
|
433
|
-
*/
|
|
434
|
-
declare class NoSigningCertificateError extends ApiError {
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* 409 `CERT_CHOICE_INVALID` — linked sign-ийн `linkedSessionID` (certificate-choice) хүчингүй: өөр RP, COMPLETE+OK биш,
|
|
438
|
-
* өөр documentNumber, 5 минутаас хуучин, гэрчилгээ солигдсон, эсвэл аль хэдийн ашиглагдсан. Certificate-choice-ийг
|
|
439
|
-
* дахин эхлүүлнэ.
|
|
440
|
-
*/
|
|
441
|
-
declare class CertChoiceInvalidError extends ApiError {
|
|
442
|
-
}
|
|
443
|
-
/** 400 `REQUEST_INVALID` — хүсэлтийн бие/талбар буруу (ж: linked sign-д `linkedSessionID` дутуу). Програмын алдаа. */
|
|
444
|
-
declare class RequestInvalidError extends ApiError {
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* CA-ийн түр (давтаж болох) алдааны кодууд — `ApiError.code`. PDF_PREPARE_BUSY (429 prepare, Retry-After 5),
|
|
448
|
-
* DOCUMENT_PENDING (503 document, 5), TSA_UNAVAILABLE (503, 30), LTV_UNAVAILABLE (503, 60), RATE_LIMITED (429 токен),
|
|
449
|
-
* STATE_UNAVAILABLE (503 токен), ISSUANCE_PENDING (503 токены үр дүн, 5).
|
|
450
|
-
*/
|
|
451
|
-
type RetryableErrorCode = "PDF_PREPARE_BUSY" | "DOCUMENT_PENDING" | "TSA_UNAVAILABLE" | "LTV_UNAVAILABLE" | "RATE_LIMITED" | "STATE_UNAVAILABLE" | "ISSUANCE_PENDING";
|
|
452
|
-
/** {@link RetryableErrorCode}-ийн бүх утга. */
|
|
453
|
-
declare const RETRYABLE_ERROR_CODES: readonly RetryableErrorCode[];
|
|
454
|
-
/** RFC 9110 §10.2.3: delay-seconds эсвэл HTTP-date → мс. Буруу / өнгөрсөн / 24 цагаас их → undefined. */
|
|
455
|
-
declare function parseRetryAfter(value: string | null | undefined, now?: number): number | undefined;
|
|
456
|
-
/**
|
|
457
|
-
* Байгууллагын нэрийн өмнөөс (`onBehalfOf`) урсгалын татгалзлын кодууд — `ForbiddenError.code` /
|
|
458
|
-
* `ApiError.code`-д ирнэ. 403: REPRESENTATION_DENIED (идэвхтэй төлөөлөгч биш), REPRESENTATION_PENDING (PIN2-оор
|
|
459
|
-
* баталгаажуулаагүй), REPRESENTATION_EXPIRED (хугацааны гадна), ORG_NOT_ACTIVE, SIGNER_UNIDENTIFIED (anonymous
|
|
460
|
-
* session); 404: ORG_NOT_FOUND; PDF баримт татахад 403 REPRESENTATION_REVOKED (prepare-ээс хойш эрх хасагдсан —
|
|
461
|
-
* баримт үүсээгүй).
|
|
462
|
-
*/
|
|
463
|
-
type OnBehalfErrorCode = "REPRESENTATION_DENIED" | "REPRESENTATION_PENDING" | "REPRESENTATION_EXPIRED" | "ORG_NOT_ACTIVE" | "SIGNER_UNIDENTIFIED" | "ORG_NOT_FOUND" | "REPRESENTATION_REVOKED";
|
|
464
|
-
/** {@link OnBehalfErrorCode}-ийн бүх утга (runtime шалгалтад). */
|
|
465
|
-
declare const ON_BEHALF_ERROR_CODES: readonly OnBehalfErrorCode[];
|
|
466
|
-
/**
|
|
467
|
-
* Сүлжээ/timeout — upstream хариу өгсөнгүй. Мессеж ба `op`-д хувь хүний таних тэмдэг ОРОХГҮЙ (замын `/etsi/{…}`,
|
|
468
|
-
* `/document/{…}` → `…`) — шууд лог руу бичиж болно.
|
|
469
|
-
*/
|
|
470
|
-
declare class NetworkError extends EidError {
|
|
471
|
-
/** "GET /session/…" (таних тэмдэг хасагдсан зам). */
|
|
472
|
-
readonly op?: string;
|
|
473
|
-
/** Хүсэлт хугацаа хэтэрсэн. */
|
|
474
|
-
readonly timeout?: boolean;
|
|
475
|
-
constructor(message: string, init?: {
|
|
476
|
-
op?: string;
|
|
477
|
-
timeout?: boolean;
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
/**
|
|
481
|
-
* Хариуны бие SDK-ийн хязгаараас их (JSON 4 MiB, PDF `pdfMaxBytes`) — бие таслагдаж задлагдахгүй. `op` — method +
|
|
482
|
-
* таних тэмдэггүй зам.
|
|
483
|
-
*/
|
|
484
|
-
declare class ResponseTooLargeError extends EidError {
|
|
485
|
-
readonly op: string;
|
|
486
|
-
readonly limit: number;
|
|
487
|
-
constructor(op: string, limit: number);
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Session амжилтгүй дууссан (endResult ≠ OK): TIMEOUT, USER_REFUSED*, DOCUMENT_UNUSABLE гм.
|
|
491
|
-
* endResult-оор салгаж RP UI-д тохирох мессеж харуулна.
|
|
492
|
-
*/
|
|
493
|
-
declare class SessionFailedError extends EidError {
|
|
494
|
-
readonly endResult: string;
|
|
495
|
-
constructor(endResult: string);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Хариуны баталгаажуулалт бүтэлгүйтсэн — cert chain итгэлцэлгүй, signature challenge-тэй
|
|
499
|
-
* таарсангүй, эсвэл certLevel хүрэлцээгүй. ЭНЭ алдаа гарвал хариунд ИТГЭХГҮЙ
|
|
500
|
-
* (хуурамч/proxy хийгдсэн байж болзошгүй).
|
|
501
|
-
*/
|
|
502
|
-
declare class ValidationError extends EidError {
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Device-link (App2App/Web2App) холбоос угсрах боломжгүй — хариунд `deviceLinkBase` байхгүй,
|
|
506
|
-
* эсвэл sessionId/vc/суурь URL хэлбэр буруу. Session-ийг дахин эхлүүлнэ; холбоосыг таахгүй.
|
|
507
|
-
*/
|
|
508
|
-
declare class DeviceLinkError extends EidError {
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
export { type AcspContext as A, type SessionState as B, type CertificateLevel as C, type DeviceLinkSession as D, EidError as E, type FlowType as F, type SignContext as G, type HashAlgorithm as H, type Interaction as I, type SignatureAlgorithmParameters as J, type SignatureProtocol as K, type TokenCertStatus as L, deviceLink as M, type NotificationSession as N, ON_BEHALF_ERROR_CODES as O, type PersonBlock as P, isMobileUserAgent as Q, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, openOrShowQR as U, ValidationError as V, parseExpiresAt as W, parseRetryAfter as X, sessionExpiry as Y, startExpiry as Z, type SessionResult as a, type PdfSessionBlock as b, type RepresentationsResponse as c, ApiError as d, AuthenticationError as e, CertChoiceInvalidError as f, DEFAULT_SIGN_SESSION_TTL_MS as g, DeviceLinkError as h, type DeviceLinkInput as i, type EndResult as j, ForbiddenError as k, type HttpErrorInit as l, type NavigatorLike as m, NetworkError as n, NoSigningCertificateError as o, type OnBehalfErrorCode as p, type OpenOrShowQROptions as q, type OrgResult as r, type PdfDocumentStatus as s, type PdfSigner as t, RETRYABLE_ERROR_CODES as u, type Representation as v, RequestInvalidError as w, ResponseTooLargeError as x, type RetryableErrorCode as y, SessionFailedError as z };
|
|
336
|
+
export { type AcspContext as A, type CertificateLevel as C, type DeviceLinkSession as D, type EndResult as E, type FlowType as F, type HashAlgorithm as H, type Interaction as I, type NotificationSession as N, type OpenOrShowQROptions as O, type PersonBlock as P, type RpCredentials as R, type SignatureAlgorithm as S, type TokenCertSessionBlock as T, type SessionResult as a, type RepresentationsResponse as b, DEFAULT_SIGN_SESSION_TTL_MS as c, type DeviceLinkInput as d, type NavigatorLike as e, type OrgResult as f, type Representation as g, type SessionState as h, type SignContext as i, type SignatureAlgorithmParameters as j, type SignatureProtocol as k, type TokenCertStatus as l, deviceLink as m, isMobileUserAgent as n, openOrShowQR as o, parseExpiresAt as p, startExpiry as q, sessionExpiry as s };
|
package/dist/browser.d.cts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { d as DeviceLinkInput, D as DeviceLinkSession, e as NavigatorLike, O as OpenOrShowQROptions, m as deviceLink, n as isMobileUserAgent, o as openOrShowQR } from './browser-8k_VDSP8.cjs';
|
|
2
|
+
export { D as DeviceLinkError, E as EidError } from './errors-Z7SgLVTr.cjs';
|
package/dist/browser.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { d as DeviceLinkInput, D as DeviceLinkSession, e as NavigatorLike, O as OpenOrShowQROptions, m as deviceLink, n as isMobileUserAgent, o as openOrShowQR } from './browser-BZ3hvv6-.js';
|
|
2
|
+
export { D as DeviceLinkError, E as EidError } from './errors-Z7SgLVTr.js';
|
package/dist/browser.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DeviceLinkError,
|
|
3
|
-
EidError,
|
|
4
2
|
deviceLink,
|
|
5
3
|
isMobileUserAgent,
|
|
6
4
|
openOrShowQR
|
|
7
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-REWNE7PO.js";
|
|
6
|
+
import {
|
|
7
|
+
DeviceLinkError,
|
|
8
|
+
EidError
|
|
9
|
+
} from "./chunk-TB2KQH3W.js";
|
|
8
10
|
export {
|
|
9
11
|
DeviceLinkError,
|
|
10
12
|
EidError,
|
package/dist/button.cjs
CHANGED
|
@@ -465,87 +465,97 @@ var T = {
|
|
|
465
465
|
minute: "1 minute left"
|
|
466
466
|
}
|
|
467
467
|
};
|
|
468
|
+
var EID_COLOR_TOKENS = [
|
|
469
|
+
["bg", "hsl(0 0% 100%)", "hsl(229 50% 6%)"],
|
|
470
|
+
["bg-subtle", "hsl(210 40% 98%)", "hsl(222 47% 9%)"],
|
|
471
|
+
["bg-muted", "hsl(210 40% 96%)", "hsl(217 33% 13%)"],
|
|
472
|
+
["fg", "hsl(222 47% 11%)", "hsl(210 40% 98%)"],
|
|
473
|
+
["fg-muted", "hsl(215 19% 35%)", "hsl(213 27% 84%)"],
|
|
474
|
+
["fg-subtle", "hsl(215 16% 45%)", "hsl(215 20% 65%)"],
|
|
475
|
+
["border", "hsl(214 32% 91%)", "hsl(217 33% 17%)"],
|
|
476
|
+
["border-strong", "hsl(213 27% 84%)", "hsl(215 25% 27%)"],
|
|
477
|
+
["accent", "oklch(0.534 0.2 259)", "oklch(0.64 0.15 259)"],
|
|
478
|
+
["accent-fg", "#fff", "hsl(229 50% 6%)"],
|
|
479
|
+
["accent-subtle", "oklch(0.97 0.03 259)", "oklch(0.24 0.06 259)"],
|
|
480
|
+
["accent-subtle-fg", "oklch(0.474 0.19 259)", "oklch(0.82 0.1 259)"],
|
|
481
|
+
["ring", "oklch(0.604 0.2 259)", "oklch(0.68 0.15 259)"],
|
|
482
|
+
["warning-bg", "hsl(48 100% 96%)", "hsl(20 60% 10%)"],
|
|
483
|
+
["warning-border", "hsl(45 95% 78%)", "hsl(22 70% 26%)"],
|
|
484
|
+
["warning-fg", "hsl(23 75% 33%)", "hsl(40 92% 65%)"],
|
|
485
|
+
["danger-fg", "hsl(0 74% 42%)", "hsl(0 91% 71%)"]
|
|
486
|
+
];
|
|
487
|
+
var lightVars = EID_COLOR_TOKENS.map(([n, l]) => `--_eid-${n}: var(--eid-${n}, ${l});`).join("\n ");
|
|
488
|
+
var darkVars = EID_COLOR_TOKENS.map(([n, , d]) => `--_eid-${n}: var(--eid-${n}-dark, var(--eid-${n}, ${d}));`).join("\n ");
|
|
468
489
|
var CSS_BASE = `
|
|
469
|
-
:host { display: inline-block;
|
|
470
|
-
|
|
471
|
-
--
|
|
472
|
-
--eid-border: hsl(214 32% 91%); --eid-border-strong: hsl(213 27% 84%);
|
|
473
|
-
--eid-accent: oklch(0.534 0.2 259); --eid-accent-fg: #fff; --eid-accent-subtle: oklch(0.97 0.03 259);
|
|
474
|
-
--eid-accent-subtle-fg: oklch(0.474 0.19 259); --eid-ring: oklch(0.604 0.2 259);
|
|
475
|
-
--eid-warning-bg: hsl(48 100% 96%); --eid-warning-border: hsl(45 95% 78%); --eid-warning-fg: hsl(23 75% 33%);
|
|
476
|
-
--eid-danger-fg: hsl(0 74% 42%); --eid-radius: 6px; --eid-radius-lg: 8px; font-family: inherit; color-scheme: light; }
|
|
490
|
+
:host { display: inline-block; font-family: inherit; color-scheme: light;
|
|
491
|
+
${lightVars}
|
|
492
|
+
--_eid-radius: var(--eid-radius, 6px); --_eid-radius-lg: var(--eid-radius-lg, 8px); }
|
|
477
493
|
button, input { font-family: inherit; }
|
|
478
494
|
`;
|
|
479
495
|
var DARK_CSS = `:host { color-scheme: dark;
|
|
480
|
-
|
|
481
|
-
--eid-fg: hsl(210 40% 98%); --eid-fg-muted: hsl(213 27% 84%); --eid-fg-subtle: hsl(215 20% 65%);
|
|
482
|
-
--eid-border: hsl(217 33% 17%); --eid-border-strong: hsl(215 25% 27%);
|
|
483
|
-
--eid-accent: oklch(0.64 0.15 259); --eid-accent-fg: hsl(229 50% 6%); --eid-accent-subtle: oklch(0.24 0.06 259);
|
|
484
|
-
--eid-accent-subtle-fg: oklch(0.82 0.1 259); --eid-ring: oklch(0.68 0.15 259);
|
|
485
|
-
--eid-warning-bg: hsl(20 60% 10%); --eid-warning-border: hsl(22 70% 26%); --eid-warning-fg: hsl(40 92% 65%);
|
|
486
|
-
--eid-danger-fg: hsl(0 91% 71%); }
|
|
496
|
+
${darkVars} }
|
|
487
497
|
`;
|
|
488
498
|
var CSS_REST = `
|
|
489
499
|
*, *::before, *::after { box-sizing: border-box; }
|
|
490
500
|
[hidden] { display: none !important; }
|
|
491
501
|
h2, p, ol { margin: 0; }
|
|
492
|
-
:focus-visible { outline: 2px solid var(--
|
|
502
|
+
:focus-visible { outline: 2px solid var(--_eid-ring); outline-offset: 2px; }
|
|
493
503
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
494
504
|
.btn { display: inline-flex; width: 100%; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
|
|
495
|
-
border-radius: var(--
|
|
505
|
+
border-radius: var(--_eid-radius); font-family: inherit; font-weight: 500; font-size: 1rem; line-height: 1.25; text-decoration: none; border: 1px solid transparent; cursor: pointer;
|
|
496
506
|
transition: background-color 160ms cubic-bezier(0,0,0.2,1); }
|
|
497
507
|
.btn:disabled { opacity: 0.6; cursor: progress; }
|
|
498
|
-
.btn-primary { background: var(--
|
|
499
|
-
.btn-primary:hover { background: color-mix(in oklab, var(--
|
|
500
|
-
.btn-outline { background: var(--
|
|
501
|
-
.btn-outline:hover { background: var(--
|
|
508
|
+
.btn-primary { background: var(--_eid-accent); color: var(--_eid-accent-fg); }
|
|
509
|
+
.btn-primary:hover { background: color-mix(in oklab, var(--_eid-accent) 88%, black); }
|
|
510
|
+
.btn-outline { background: var(--_eid-bg); color: var(--_eid-fg); border-color: var(--_eid-border-strong); }
|
|
511
|
+
.btn-outline:hover { background: var(--_eid-bg-muted); }
|
|
502
512
|
.btn-sm { width: auto; min-height: 36px; padding: 0 14px; font-size: 0.8125rem; }
|
|
503
513
|
.trigger { width: auto; }
|
|
504
514
|
.trigger img { width: 20px; height: 20px; border-radius: 4px; }
|
|
505
515
|
.backdrop { position: fixed; inset: 0; z-index: 2147483000; background: hsl(222 47% 11% / 0.5); display: flex; align-items: center;
|
|
506
516
|
justify-content: center; padding: 16px; overflow-y: auto; }
|
|
507
|
-
.dialog { position: relative; width: 100%; max-width: 26rem; max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--
|
|
508
|
-
color: var(--
|
|
517
|
+
.dialog { position: relative; width: 100%; max-width: 26rem; max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--_eid-bg);
|
|
518
|
+
color: var(--_eid-fg); border: 1px solid var(--_eid-border); border-radius: var(--_eid-radius-lg); padding: 24px; font-size: 0.875rem; line-height: 1.5rem; }
|
|
509
519
|
@media (max-width: 639px) { .dialog { padding: 16px; } }
|
|
510
520
|
.head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
|
|
511
|
-
.head img { width: 28px; height: 28px; border-radius: var(--
|
|
521
|
+
.head img { width: 28px; height: 28px; border-radius: var(--_eid-radius); }
|
|
512
522
|
.head h2 { flex: 1; font-size: 1.125rem; line-height: 1.75rem; font-weight: 600; }
|
|
513
|
-
.x { width: 36px; height: 36px; border: 0; border-radius: var(--
|
|
514
|
-
.x:hover { background: var(--
|
|
515
|
-
.qr { position: relative; width: 256px; max-width: 100%; aspect-ratio: 1; margin: 0 auto; border: 1px solid var(--
|
|
516
|
-
border-radius: var(--
|
|
523
|
+
.x { width: 36px; height: 36px; border: 0; border-radius: var(--_eid-radius); background: transparent; color: var(--_eid-fg-muted); cursor: pointer; font-size: 1.25rem; line-height: 1; }
|
|
524
|
+
.x:hover { background: var(--_eid-bg-muted); color: var(--_eid-fg); }
|
|
525
|
+
.qr { position: relative; width: 256px; max-width: 100%; aspect-ratio: 1; margin: 0 auto; border: 1px solid var(--_eid-border);
|
|
526
|
+
border-radius: var(--_eid-radius-lg); background: #fff; overflow: hidden; }
|
|
517
527
|
.qr svg { display: block; width: 100%; height: 100%; }
|
|
518
528
|
.qr.stale svg { opacity: 0.12; }
|
|
519
529
|
.qr-stale { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
|
|
520
530
|
color: hsl(222 47% 11%); font-weight: 500; }
|
|
521
|
-
.qr-vc { margin-top: 8px; text-align: center; font-size: 0.8125rem; color: var(--
|
|
522
|
-
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.08em; color: var(--
|
|
531
|
+
.qr-vc { margin-top: 8px; text-align: center; font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
532
|
+
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.08em; color: var(--_eid-fg-muted); }
|
|
523
533
|
.steps { margin-top: 16px; padding: 0; list-style: none; counter-reset: st; display: grid; gap: 8px; }
|
|
524
534
|
.steps li { counter-increment: st; display: flex; align-items: center; gap: 12px; }
|
|
525
|
-
.steps li::before { content: counter(st); flex: none; width: 24px; height: 24px; border-radius: 9999px; background: var(--
|
|
526
|
-
color: var(--
|
|
527
|
-
.or { display: flex; align-items: center; gap: 12px; margin: 24px 0; color: var(--
|
|
528
|
-
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--
|
|
535
|
+
.steps li::before { content: counter(st); flex: none; width: 24px; height: 24px; border-radius: 9999px; background: var(--_eid-accent-subtle);
|
|
536
|
+
color: var(--_eid-accent-subtle-fg); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 600; }
|
|
537
|
+
.or { display: flex; align-items: center; gap: 12px; margin: 24px 0; color: var(--_eid-fg-subtle); font-size: 0.8125rem; }
|
|
538
|
+
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--_eid-border); }
|
|
529
539
|
.field { display: grid; gap: 8px; }
|
|
530
540
|
.field label { font-weight: 500; }
|
|
531
|
-
.field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--
|
|
532
|
-
background: var(--
|
|
533
|
-
.field input::placeholder { color: var(--
|
|
534
|
-
.field input[aria-invalid="true"] { border-color: var(--
|
|
535
|
-
.hint { font-size: 0.8125rem; color: var(--
|
|
536
|
-
.err { font-size: 0.8125rem; color: var(--
|
|
541
|
+
.field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--_eid-border-strong); border-radius: var(--_eid-radius);
|
|
542
|
+
background: var(--_eid-bg); color: var(--_eid-fg); font-family: inherit; font-size: 1rem; line-height: 1.5rem; letter-spacing: 0.02em; text-transform: uppercase; }
|
|
543
|
+
.field input::placeholder { color: var(--_eid-fg-subtle); text-transform: none; }
|
|
544
|
+
.field input[aria-invalid="true"] { border-color: var(--_eid-danger-fg); }
|
|
545
|
+
.hint { font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
546
|
+
.err { font-size: 0.8125rem; color: var(--_eid-danger-fg); font-weight: 500; }
|
|
537
547
|
.push { margin-top: 16px; }
|
|
538
548
|
.center { text-align: center; }
|
|
539
549
|
.vc { font: 600 2.25rem/2.5rem ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.16em; padding-left: 0.16em; }
|
|
540
550
|
.vc:focus, h2:focus { outline: none; }
|
|
541
|
-
.text { margin-top: 12px; color: var(--
|
|
542
|
-
.pending { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; color: var(--
|
|
551
|
+
.text { margin-top: 12px; color: var(--_eid-fg-muted); }
|
|
552
|
+
.pending { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; color: var(--_eid-fg-muted); }
|
|
543
553
|
.end .btn, .center .btn { margin-top: 24px; }
|
|
544
554
|
.spinner { width: 16px; height: 16px; flex: none; border: 2px solid currentColor; border-right-color: transparent; border-radius: 9999px; animation: spin 0.8s linear infinite; }
|
|
545
555
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
546
|
-
.netwarn { margin-top: 16px; padding: 8px 12px; border: 1px solid var(--
|
|
547
|
-
color: var(--
|
|
548
|
-
.meta { margin-top: 16px; font-size: 0.8125rem; color: var(--
|
|
556
|
+
.netwarn { margin-top: 16px; padding: 8px 12px; border: 1px solid var(--_eid-warning-border); border-radius: var(--_eid-radius); background: var(--_eid-warning-bg);
|
|
557
|
+
color: var(--_eid-warning-fg); font-size: 0.8125rem; }
|
|
558
|
+
.meta { margin-top: 16px; font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
549
559
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; }
|
|
550
560
|
.spinner { animation: none; border-right-color: currentColor; opacity: 0.6; } }
|
|
551
561
|
`;
|
package/dist/button.js
CHANGED
|
@@ -436,87 +436,97 @@ var T = {
|
|
|
436
436
|
minute: "1 minute left"
|
|
437
437
|
}
|
|
438
438
|
};
|
|
439
|
+
var EID_COLOR_TOKENS = [
|
|
440
|
+
["bg", "hsl(0 0% 100%)", "hsl(229 50% 6%)"],
|
|
441
|
+
["bg-subtle", "hsl(210 40% 98%)", "hsl(222 47% 9%)"],
|
|
442
|
+
["bg-muted", "hsl(210 40% 96%)", "hsl(217 33% 13%)"],
|
|
443
|
+
["fg", "hsl(222 47% 11%)", "hsl(210 40% 98%)"],
|
|
444
|
+
["fg-muted", "hsl(215 19% 35%)", "hsl(213 27% 84%)"],
|
|
445
|
+
["fg-subtle", "hsl(215 16% 45%)", "hsl(215 20% 65%)"],
|
|
446
|
+
["border", "hsl(214 32% 91%)", "hsl(217 33% 17%)"],
|
|
447
|
+
["border-strong", "hsl(213 27% 84%)", "hsl(215 25% 27%)"],
|
|
448
|
+
["accent", "oklch(0.534 0.2 259)", "oklch(0.64 0.15 259)"],
|
|
449
|
+
["accent-fg", "#fff", "hsl(229 50% 6%)"],
|
|
450
|
+
["accent-subtle", "oklch(0.97 0.03 259)", "oklch(0.24 0.06 259)"],
|
|
451
|
+
["accent-subtle-fg", "oklch(0.474 0.19 259)", "oklch(0.82 0.1 259)"],
|
|
452
|
+
["ring", "oklch(0.604 0.2 259)", "oklch(0.68 0.15 259)"],
|
|
453
|
+
["warning-bg", "hsl(48 100% 96%)", "hsl(20 60% 10%)"],
|
|
454
|
+
["warning-border", "hsl(45 95% 78%)", "hsl(22 70% 26%)"],
|
|
455
|
+
["warning-fg", "hsl(23 75% 33%)", "hsl(40 92% 65%)"],
|
|
456
|
+
["danger-fg", "hsl(0 74% 42%)", "hsl(0 91% 71%)"]
|
|
457
|
+
];
|
|
458
|
+
var lightVars = EID_COLOR_TOKENS.map(([n, l]) => `--_eid-${n}: var(--eid-${n}, ${l});`).join("\n ");
|
|
459
|
+
var darkVars = EID_COLOR_TOKENS.map(([n, , d]) => `--_eid-${n}: var(--eid-${n}-dark, var(--eid-${n}, ${d}));`).join("\n ");
|
|
439
460
|
var CSS_BASE = `
|
|
440
|
-
:host { display: inline-block;
|
|
441
|
-
|
|
442
|
-
--
|
|
443
|
-
--eid-border: hsl(214 32% 91%); --eid-border-strong: hsl(213 27% 84%);
|
|
444
|
-
--eid-accent: oklch(0.534 0.2 259); --eid-accent-fg: #fff; --eid-accent-subtle: oklch(0.97 0.03 259);
|
|
445
|
-
--eid-accent-subtle-fg: oklch(0.474 0.19 259); --eid-ring: oklch(0.604 0.2 259);
|
|
446
|
-
--eid-warning-bg: hsl(48 100% 96%); --eid-warning-border: hsl(45 95% 78%); --eid-warning-fg: hsl(23 75% 33%);
|
|
447
|
-
--eid-danger-fg: hsl(0 74% 42%); --eid-radius: 6px; --eid-radius-lg: 8px; font-family: inherit; color-scheme: light; }
|
|
461
|
+
:host { display: inline-block; font-family: inherit; color-scheme: light;
|
|
462
|
+
${lightVars}
|
|
463
|
+
--_eid-radius: var(--eid-radius, 6px); --_eid-radius-lg: var(--eid-radius-lg, 8px); }
|
|
448
464
|
button, input { font-family: inherit; }
|
|
449
465
|
`;
|
|
450
466
|
var DARK_CSS = `:host { color-scheme: dark;
|
|
451
|
-
|
|
452
|
-
--eid-fg: hsl(210 40% 98%); --eid-fg-muted: hsl(213 27% 84%); --eid-fg-subtle: hsl(215 20% 65%);
|
|
453
|
-
--eid-border: hsl(217 33% 17%); --eid-border-strong: hsl(215 25% 27%);
|
|
454
|
-
--eid-accent: oklch(0.64 0.15 259); --eid-accent-fg: hsl(229 50% 6%); --eid-accent-subtle: oklch(0.24 0.06 259);
|
|
455
|
-
--eid-accent-subtle-fg: oklch(0.82 0.1 259); --eid-ring: oklch(0.68 0.15 259);
|
|
456
|
-
--eid-warning-bg: hsl(20 60% 10%); --eid-warning-border: hsl(22 70% 26%); --eid-warning-fg: hsl(40 92% 65%);
|
|
457
|
-
--eid-danger-fg: hsl(0 91% 71%); }
|
|
467
|
+
${darkVars} }
|
|
458
468
|
`;
|
|
459
469
|
var CSS_REST = `
|
|
460
470
|
*, *::before, *::after { box-sizing: border-box; }
|
|
461
471
|
[hidden] { display: none !important; }
|
|
462
472
|
h2, p, ol { margin: 0; }
|
|
463
|
-
:focus-visible { outline: 2px solid var(--
|
|
473
|
+
:focus-visible { outline: 2px solid var(--_eid-ring); outline-offset: 2px; }
|
|
464
474
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
465
475
|
.btn { display: inline-flex; width: 100%; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
|
|
466
|
-
border-radius: var(--
|
|
476
|
+
border-radius: var(--_eid-radius); font-family: inherit; font-weight: 500; font-size: 1rem; line-height: 1.25; text-decoration: none; border: 1px solid transparent; cursor: pointer;
|
|
467
477
|
transition: background-color 160ms cubic-bezier(0,0,0.2,1); }
|
|
468
478
|
.btn:disabled { opacity: 0.6; cursor: progress; }
|
|
469
|
-
.btn-primary { background: var(--
|
|
470
|
-
.btn-primary:hover { background: color-mix(in oklab, var(--
|
|
471
|
-
.btn-outline { background: var(--
|
|
472
|
-
.btn-outline:hover { background: var(--
|
|
479
|
+
.btn-primary { background: var(--_eid-accent); color: var(--_eid-accent-fg); }
|
|
480
|
+
.btn-primary:hover { background: color-mix(in oklab, var(--_eid-accent) 88%, black); }
|
|
481
|
+
.btn-outline { background: var(--_eid-bg); color: var(--_eid-fg); border-color: var(--_eid-border-strong); }
|
|
482
|
+
.btn-outline:hover { background: var(--_eid-bg-muted); }
|
|
473
483
|
.btn-sm { width: auto; min-height: 36px; padding: 0 14px; font-size: 0.8125rem; }
|
|
474
484
|
.trigger { width: auto; }
|
|
475
485
|
.trigger img { width: 20px; height: 20px; border-radius: 4px; }
|
|
476
486
|
.backdrop { position: fixed; inset: 0; z-index: 2147483000; background: hsl(222 47% 11% / 0.5); display: flex; align-items: center;
|
|
477
487
|
justify-content: center; padding: 16px; overflow-y: auto; }
|
|
478
|
-
.dialog { position: relative; width: 100%; max-width: 26rem; max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--
|
|
479
|
-
color: var(--
|
|
488
|
+
.dialog { position: relative; width: 100%; max-width: 26rem; max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--_eid-bg);
|
|
489
|
+
color: var(--_eid-fg); border: 1px solid var(--_eid-border); border-radius: var(--_eid-radius-lg); padding: 24px; font-size: 0.875rem; line-height: 1.5rem; }
|
|
480
490
|
@media (max-width: 639px) { .dialog { padding: 16px; } }
|
|
481
491
|
.head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
|
|
482
|
-
.head img { width: 28px; height: 28px; border-radius: var(--
|
|
492
|
+
.head img { width: 28px; height: 28px; border-radius: var(--_eid-radius); }
|
|
483
493
|
.head h2 { flex: 1; font-size: 1.125rem; line-height: 1.75rem; font-weight: 600; }
|
|
484
|
-
.x { width: 36px; height: 36px; border: 0; border-radius: var(--
|
|
485
|
-
.x:hover { background: var(--
|
|
486
|
-
.qr { position: relative; width: 256px; max-width: 100%; aspect-ratio: 1; margin: 0 auto; border: 1px solid var(--
|
|
487
|
-
border-radius: var(--
|
|
494
|
+
.x { width: 36px; height: 36px; border: 0; border-radius: var(--_eid-radius); background: transparent; color: var(--_eid-fg-muted); cursor: pointer; font-size: 1.25rem; line-height: 1; }
|
|
495
|
+
.x:hover { background: var(--_eid-bg-muted); color: var(--_eid-fg); }
|
|
496
|
+
.qr { position: relative; width: 256px; max-width: 100%; aspect-ratio: 1; margin: 0 auto; border: 1px solid var(--_eid-border);
|
|
497
|
+
border-radius: var(--_eid-radius-lg); background: #fff; overflow: hidden; }
|
|
488
498
|
.qr svg { display: block; width: 100%; height: 100%; }
|
|
489
499
|
.qr.stale svg { opacity: 0.12; }
|
|
490
500
|
.qr-stale { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
|
|
491
501
|
color: hsl(222 47% 11%); font-weight: 500; }
|
|
492
|
-
.qr-vc { margin-top: 8px; text-align: center; font-size: 0.8125rem; color: var(--
|
|
493
|
-
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.08em; color: var(--
|
|
502
|
+
.qr-vc { margin-top: 8px; text-align: center; font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
503
|
+
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.08em; color: var(--_eid-fg-muted); }
|
|
494
504
|
.steps { margin-top: 16px; padding: 0; list-style: none; counter-reset: st; display: grid; gap: 8px; }
|
|
495
505
|
.steps li { counter-increment: st; display: flex; align-items: center; gap: 12px; }
|
|
496
|
-
.steps li::before { content: counter(st); flex: none; width: 24px; height: 24px; border-radius: 9999px; background: var(--
|
|
497
|
-
color: var(--
|
|
498
|
-
.or { display: flex; align-items: center; gap: 12px; margin: 24px 0; color: var(--
|
|
499
|
-
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--
|
|
506
|
+
.steps li::before { content: counter(st); flex: none; width: 24px; height: 24px; border-radius: 9999px; background: var(--_eid-accent-subtle);
|
|
507
|
+
color: var(--_eid-accent-subtle-fg); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 600; }
|
|
508
|
+
.or { display: flex; align-items: center; gap: 12px; margin: 24px 0; color: var(--_eid-fg-subtle); font-size: 0.8125rem; }
|
|
509
|
+
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--_eid-border); }
|
|
500
510
|
.field { display: grid; gap: 8px; }
|
|
501
511
|
.field label { font-weight: 500; }
|
|
502
|
-
.field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--
|
|
503
|
-
background: var(--
|
|
504
|
-
.field input::placeholder { color: var(--
|
|
505
|
-
.field input[aria-invalid="true"] { border-color: var(--
|
|
506
|
-
.hint { font-size: 0.8125rem; color: var(--
|
|
507
|
-
.err { font-size: 0.8125rem; color: var(--
|
|
512
|
+
.field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--_eid-border-strong); border-radius: var(--_eid-radius);
|
|
513
|
+
background: var(--_eid-bg); color: var(--_eid-fg); font-family: inherit; font-size: 1rem; line-height: 1.5rem; letter-spacing: 0.02em; text-transform: uppercase; }
|
|
514
|
+
.field input::placeholder { color: var(--_eid-fg-subtle); text-transform: none; }
|
|
515
|
+
.field input[aria-invalid="true"] { border-color: var(--_eid-danger-fg); }
|
|
516
|
+
.hint { font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
517
|
+
.err { font-size: 0.8125rem; color: var(--_eid-danger-fg); font-weight: 500; }
|
|
508
518
|
.push { margin-top: 16px; }
|
|
509
519
|
.center { text-align: center; }
|
|
510
520
|
.vc { font: 600 2.25rem/2.5rem ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.16em; padding-left: 0.16em; }
|
|
511
521
|
.vc:focus, h2:focus { outline: none; }
|
|
512
|
-
.text { margin-top: 12px; color: var(--
|
|
513
|
-
.pending { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; color: var(--
|
|
522
|
+
.text { margin-top: 12px; color: var(--_eid-fg-muted); }
|
|
523
|
+
.pending { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; color: var(--_eid-fg-muted); }
|
|
514
524
|
.end .btn, .center .btn { margin-top: 24px; }
|
|
515
525
|
.spinner { width: 16px; height: 16px; flex: none; border: 2px solid currentColor; border-right-color: transparent; border-radius: 9999px; animation: spin 0.8s linear infinite; }
|
|
516
526
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
517
|
-
.netwarn { margin-top: 16px; padding: 8px 12px; border: 1px solid var(--
|
|
518
|
-
color: var(--
|
|
519
|
-
.meta { margin-top: 16px; font-size: 0.8125rem; color: var(--
|
|
527
|
+
.netwarn { margin-top: 16px; padding: 8px 12px; border: 1px solid var(--_eid-warning-border); border-radius: var(--_eid-radius); background: var(--_eid-warning-bg);
|
|
528
|
+
color: var(--_eid-warning-fg); font-size: 0.8125rem; }
|
|
529
|
+
.meta { margin-top: 16px; font-size: 0.8125rem; color: var(--_eid-fg-subtle); }
|
|
520
530
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; }
|
|
521
531
|
.spinner { animation: none; border-right-color: currentColor; opacity: 0.6; } }
|
|
522
532
|
`;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeviceLinkError
|
|
3
|
+
} from "./chunk-TB2KQH3W.js";
|
|
4
|
+
|
|
5
|
+
// src/devicelink.ts
|
|
6
|
+
var SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
7
|
+
var VC_RE = /^[0-9]{5}$/;
|
|
8
|
+
function deviceLink(session) {
|
|
9
|
+
const base = session.deviceLinkBase?.trim();
|
|
10
|
+
if (!base) throw new DeviceLinkError("deviceLink: \u0445\u0430\u0440\u0438\u0443\u043D\u0434 deviceLinkBase \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 device-link session \u044D\u0441\u044D\u0445\u0438\u0439\u0433 \u0448\u0430\u043B\u0433\u0430");
|
|
11
|
+
let u;
|
|
12
|
+
try {
|
|
13
|
+
u = new URL(base);
|
|
14
|
+
} catch {
|
|
15
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase \u0431\u0443\u0440\u0443\u0443 URL: ${base}`);
|
|
16
|
+
}
|
|
17
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") {
|
|
18
|
+
throw new DeviceLinkError(`deviceLink: deviceLinkBase https URL \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439: ${u.protocol}`);
|
|
19
|
+
}
|
|
20
|
+
if (!SESSION_ID_RE.test(session.sessionId)) throw new DeviceLinkError("deviceLink: sessionId UUID (lowercase) \u0431\u0438\u0448");
|
|
21
|
+
if (session.vc == null || !VC_RE.test(session.vc)) throw new DeviceLinkError("deviceLink: vc 5 \u043E\u0440\u043E\u043D\u0442\u043E\u0439 \u0442\u043E\u043E \u0431\u0438\u0448");
|
|
22
|
+
u.searchParams.set("sessionId", session.sessionId);
|
|
23
|
+
u.searchParams.set("vc", session.vc);
|
|
24
|
+
return u.toString();
|
|
25
|
+
}
|
|
26
|
+
function isMobileUserAgent(nav) {
|
|
27
|
+
const n = nav ?? globalThis.navigator;
|
|
28
|
+
if (!n) return false;
|
|
29
|
+
if (n.userAgentData?.mobile === true) return true;
|
|
30
|
+
const ua = n.userAgent ?? "";
|
|
31
|
+
if (/Android|iPhone|iPod|iPad/i.test(ua)) return true;
|
|
32
|
+
return /Macintosh/.test(ua) && (n.maxTouchPoints ?? 0) > 1;
|
|
33
|
+
}
|
|
34
|
+
function openOrShowQR(session, opts) {
|
|
35
|
+
const link = deviceLink(session);
|
|
36
|
+
const mobile = typeof opts.isMobile === "function" ? opts.isMobile() : opts.isMobile ?? isMobileUserAgent();
|
|
37
|
+
if (mobile) {
|
|
38
|
+
const loc = globalThis.location;
|
|
39
|
+
if (!loc) throw new DeviceLinkError("openOrShowQR: location \u0431\u0430\u0439\u0445\u0433\u04AF\u0439 \u2014 \u0437\u04E9\u0432\u0445\u04E9\u043D \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0442");
|
|
40
|
+
loc.assign(link);
|
|
41
|
+
return "opened";
|
|
42
|
+
}
|
|
43
|
+
opts.showQR(link);
|
|
44
|
+
return "qr";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
deviceLink,
|
|
49
|
+
isMobileUserAgent,
|
|
50
|
+
openOrShowQR
|
|
51
|
+
};
|