@flow-industries/id 0.21.2 → 0.22.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 +52 -0
- package/contracts/v1/openapi.json +818 -0
- package/contracts/v1/reports.json +188 -0
- package/contracts/v1/sdk-exports.json +1165 -0
- package/dist/sdk/client/create-flow.js +2 -5
- package/dist/sdk/client/dialog-host.js +11 -6
- package/dist/sdk/client/flow-widget.js +3 -3
- package/dist/sdk/client/focus-session.d.ts +18 -0
- package/dist/sdk/client/focus-session.js +140 -0
- package/dist/sdk/client/focus.d.ts +11 -0
- package/dist/sdk/client/focus.js +30 -0
- package/dist/sdk/client/iframe-host.d.ts +2 -1
- package/dist/sdk/client/iframe-host.js +11 -1
- package/dist/sdk/client/index.d.ts +4 -1
- package/dist/sdk/client/index.js +2 -0
- package/dist/sdk/client/json-api.d.ts +1 -1
- package/dist/sdk/client/json-api.js +3 -1
- package/dist/sdk/client/open-profile.js +10 -7
- package/dist/sdk/client/profile-button.js +16 -9
- package/dist/sdk/client/reports.d.ts +9 -0
- package/dist/sdk/client/reports.js +30 -0
- package/dist/sdk/client/rooms.js +7 -26
- package/dist/sdk/client/study-search.d.ts +20 -0
- package/dist/sdk/client/study-search.js +116 -0
- package/dist/sdk/contracts/http.d.ts +155 -0
- package/dist/sdk/contracts/http.js +91 -0
- package/dist/sdk/contracts/reports.d.ts +130 -0
- package/dist/sdk/contracts/reports.js +67 -0
- package/dist/sdk/dialog/remote/Messenger.d.ts +3 -0
- package/dist/sdk/dialog/remote/Messenger.js +9 -3
- package/dist/sdk/react/use-cooldown.d.ts +1 -0
- package/dist/sdk/react/use-cooldown.js +12 -0
- package/dist/sdk/types/auth.d.ts +12 -0
- package/dist/sdk/types/dialog.d.ts +25 -0
- package/dist/sdk/types/focus.d.ts +109 -0
- package/dist/sdk/types/focus.js +0 -0
- package/dist/sdk/types/index.d.ts +8 -3
- package/dist/sdk/types/landing.d.ts +9 -0
- package/dist/sdk/types/landing.js +0 -0
- package/dist/sdk/types/otp.d.ts +20 -0
- package/dist/sdk/types/otp.js +0 -0
- package/dist/sdk/types/reports.d.ts +7 -0
- package/dist/sdk/types/reports.js +0 -0
- package/dist/sdk/types/settings.d.ts +162 -0
- package/dist/sdk/types/settings.js +0 -0
- package/dist/sdk/types/xp.d.ts +8 -0
- package/package.json +21 -9
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ActionCatalogResponse, ActionEventRequest, ActionEventResponse, ActionSubjectRef, ActiveActionResponse, CreateStudySubjectInput, FinishActionRequest, FinishActionResponse, ListStudySessionsOptions, ListStudySubjectsOptions, StartActionInput, StartActionResult, StudyCatalog, StudyCategory, StudyField, StudyRange, StudySessionPage, StudySubject, StudySubjectList, StudySubjectRemovalResponse, StudySubjectResponse, StudySummary, UpdateStudySubjectInput } from "./index";
|
|
2
|
+
/** The running session as the header pill and the panel see it: the shape of
|
|
3
|
+
* `GET /api/actions/me`, of a start's `session` and of a 409's `active`. */
|
|
4
|
+
export type ActiveAction = ActiveActionResponse;
|
|
5
|
+
/** A start as the UI requests it. The surface is not the caller's to choose:
|
|
6
|
+
* `createFocusApi` stamps every start with the injected host surface. `sessionId` may be
|
|
7
|
+
* omitted; the SDK mints the idempotency key. */
|
|
8
|
+
export type StartFocusRequest = Omit<StartActionInput, "surface">;
|
|
9
|
+
export interface FocusApi {
|
|
10
|
+
catalog(): Promise<ActionCatalogResponse>;
|
|
11
|
+
/** The caller's running session, or null when idle. */
|
|
12
|
+
active(): Promise<ActiveAction | null>;
|
|
13
|
+
/** Resolves to the 409 conflict as a value; every other refusal throws. */
|
|
14
|
+
start(request: StartFocusRequest): Promise<StartActionResult>;
|
|
15
|
+
event(request: ActionEventRequest): Promise<ActionEventResponse>;
|
|
16
|
+
finish(request: FinishActionRequest): Promise<FinishActionResponse>;
|
|
17
|
+
studyCatalog(): Promise<StudyCatalog>;
|
|
18
|
+
subjects(options?: ListStudySubjectsOptions): Promise<StudySubjectList>;
|
|
19
|
+
createSubject(request: CreateStudySubjectInput): Promise<StudySubjectResponse>;
|
|
20
|
+
/** Rename (`{ name }`), re-anchor (`{ field }`), archive or restore
|
|
21
|
+
* (`{ archived }`) a subject. Archiving is what the picker means by
|
|
22
|
+
* "remove"; the host subject-management surface also offers deletion. */
|
|
23
|
+
updateSubject(id: string, patch: UpdateStudySubjectInput): Promise<StudySubjectResponse>;
|
|
24
|
+
/** Removes a subject outright when nothing references it; auth archives it
|
|
25
|
+
* instead when sessions do, which the `outcome` reports. */
|
|
26
|
+
deleteSubject(id: string): Promise<StudySubjectRemovalResponse>;
|
|
27
|
+
/** Finished study time per subject and per category; the running session
|
|
28
|
+
* is not in it and is folded in live from the provider. */
|
|
29
|
+
summary(range: StudyRange): Promise<StudySummary>;
|
|
30
|
+
/** One subject's finished sessions, newest first, keyset-paged on
|
|
31
|
+
* `nextBefore`. */
|
|
32
|
+
sessions(options: ListStudySessionsOptions): Promise<StudySessionPage>;
|
|
33
|
+
}
|
|
34
|
+
export interface CatalogFieldRef {
|
|
35
|
+
category: StudyCategory;
|
|
36
|
+
field: StudyField;
|
|
37
|
+
}
|
|
38
|
+
export type StudySearchHit = {
|
|
39
|
+
kind: "subject";
|
|
40
|
+
id: string;
|
|
41
|
+
subject: StudySubject;
|
|
42
|
+
ref: CatalogFieldRef | null;
|
|
43
|
+
score: number;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "field";
|
|
46
|
+
id: string;
|
|
47
|
+
ref: CatalogFieldRef;
|
|
48
|
+
/** The alias that matched when the label itself did not. */
|
|
49
|
+
alias: string | null;
|
|
50
|
+
score: number;
|
|
51
|
+
};
|
|
52
|
+
export interface ClockAnchor {
|
|
53
|
+
accruedSeconds: number;
|
|
54
|
+
paused: boolean;
|
|
55
|
+
readAt: number;
|
|
56
|
+
}
|
|
57
|
+
export type FocusPhase = "unknown" | "idle" | "active";
|
|
58
|
+
/** What Stop leaves behind, shown exactly once before it is dismissed. */
|
|
59
|
+
export interface FinishedSummary {
|
|
60
|
+
source: string;
|
|
61
|
+
label: string | null;
|
|
62
|
+
subject: ActionSubjectRef | null;
|
|
63
|
+
xpGranted: number;
|
|
64
|
+
durationSeconds: number;
|
|
65
|
+
}
|
|
66
|
+
export interface FocusSessionState {
|
|
67
|
+
phase: FocusPhase;
|
|
68
|
+
active: ActiveAction | null;
|
|
69
|
+
anchor: ClockAnchor | null;
|
|
70
|
+
finished: FinishedSummary | null;
|
|
71
|
+
/** The other session a plain start ran into, awaiting "switch?". */
|
|
72
|
+
conflict: ActiveAction | null;
|
|
73
|
+
busy: boolean;
|
|
74
|
+
failed: boolean;
|
|
75
|
+
}
|
|
76
|
+
export type FocusSessionEvent = {
|
|
77
|
+
type: "read";
|
|
78
|
+
active: ActiveAction | null;
|
|
79
|
+
at: number;
|
|
80
|
+
} | {
|
|
81
|
+
type: "read-failed";
|
|
82
|
+
} | {
|
|
83
|
+
type: "request";
|
|
84
|
+
} | {
|
|
85
|
+
type: "request-failed";
|
|
86
|
+
} | {
|
|
87
|
+
type: "started";
|
|
88
|
+
session: ActiveAction;
|
|
89
|
+
at: number;
|
|
90
|
+
} | {
|
|
91
|
+
type: "conflict";
|
|
92
|
+
active: ActiveAction;
|
|
93
|
+
} | {
|
|
94
|
+
type: "paused";
|
|
95
|
+
at: number;
|
|
96
|
+
} | {
|
|
97
|
+
type: "resumed";
|
|
98
|
+
at: number;
|
|
99
|
+
} | {
|
|
100
|
+
type: "finished";
|
|
101
|
+
result: FinishActionResponse;
|
|
102
|
+
at: number;
|
|
103
|
+
} | {
|
|
104
|
+
type: "dismiss-finished";
|
|
105
|
+
} | {
|
|
106
|
+
type: "dismiss-conflict";
|
|
107
|
+
} | {
|
|
108
|
+
type: "reset";
|
|
109
|
+
};
|
|
File without changes
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
export type { AccountDeleteRequest, AccountDeleteResponse, AccountErasureCounts, AccountErasureEntry, AccountErasureFeed, AccountErasureResult, AccountExport, AccountExportAccount, AccountExportActionEvent, AccountExportActionSession, AccountExportAttendance, AccountExportAuthoredEvent, AccountExportCharacterStateTime, AccountExportFollow, AccountExportGameEvent, AccountExportOtherService, AccountExportOwnedRoom, AccountExportPasskey, AccountExportRoomEvents, AccountExportRoomMembership, AccountExportRoomPlayerState, AccountExportRoomPresence, AccountExportRoomRestriction, AccountExportRoomSettings, AccountExportRooms, AccountExportRsvp, AccountExportSettingsSurface, AccountExportStudySubject, AccountExportXpGrant, AccountExportXpSummary, } from "./account-data";
|
|
2
2
|
export type { ActionCurve, ActionEventRequest, ActionEventResponse, ActionsApi, ActiveActionState, FinishActionRequest, ListStudySessionsOptions, ListStudySubjectsOptions, StartActionInput, StartActionResult, StudyApi, StudySubjectResponse, UseActiveActionOptions, XpEstimateContext, } from "./actions";
|
|
3
|
-
export type { AccountSession, AccountSessionsResponse, AdditionalSession, AuthConfig, AuthResponse, AuthResponseWithWebAuthn, BioNormalization, BioRejection, BioWriteRefusal, BioWriteResult, FlowCredential, FlowUser, PasskeyPluginOptions, RevokeAllSessionsResponse, RevokeSessionResponse, SecurityActivityEntry, SecurityActivityResponse, SessionUser, VerifiedFlowJWT, VerifyOptions, WebAuthnSignature, } from "./auth";
|
|
3
|
+
export type { AccountRegistration, AccountSession, AccountSessionsResponse, AdditionalSession, AuthConfig, AuthResponse, AuthResponseWithWebAuthn, BioNormalization, BioRejection, BioWriteRefusal, BioWriteResult, FlowCredential, FlowUser, PasskeyEnrollment, PasskeyPluginOptions, RevokeAllSessionsResponse, RevokeSessionResponse, SecurityActivityEntry, SecurityActivityResponse, SessionUser, VerifiedFlowJWT, VerifyOptions, WebAuthnSignature, } from "./auth";
|
|
4
4
|
export type { BodyRegion, CosmeticItem, CosmeticMaterial, CosmeticPaint, CosmeticSlot, EquipConflict, EquippedCosmetic, EquippedCosmetics, EquipRegion, PaintSlot, SettingsConflict, } from "./cosmetics";
|
|
5
5
|
export { BODY_REGIONS, COSMETIC_MATERIALS } from "./cosmetics";
|
|
6
|
-
export type { BoundaryError, DialogCustomFeatures, DialogCustomLabels, DialogError, DialogReferrer, DialogState, Loadable, ProfileData, ProfileIdentity, } from "./dialog";
|
|
6
|
+
export type { AccountDataDownload, AccountDataIdentity, BoundaryError, DialogCustomFeatures, DialogCustomLabels, DialogError, DialogReferrer, DialogState, Loadable, ProfileData, ProfileIdentity, SignInWithEmailProps, SignUpProps, } from "./dialog";
|
|
7
7
|
export type { AuthErrorCode, AuthEventName, AuthEventRecord, AuthMode, AuthOutcome, BeaconBody, FunnelStep, } from "./events";
|
|
8
|
+
export type { ActiveAction, CatalogFieldRef, ClockAnchor, FinishedSummary, FocusApi, FocusPhase, FocusSessionEvent, FocusSessionState, StartFocusRequest, StudySearchHit, } from "./focus";
|
|
8
9
|
export type { GameEventReport, GameLifecycleEventName, GameLifecycleFeedEvent, GameLifecycleFeedPage, GamePlayerSession, } from "./game";
|
|
9
10
|
export { GAME_LIFECYCLE_EVENT_NAMES } from "./game";
|
|
11
|
+
export type { AccountProfileData } from "./landing";
|
|
10
12
|
export type { Bridge, BridgeParameters, FlowAccount, FlowRemote, FlowRemoteConfig, FromWindowOptions, MessageResponse, Messenger, OneOf, Payload, QueuedRequest, ReadyOptions, RemoteFlowState, RemoteState, Schema, Storage, Topic, WithReady, } from "./messenger";
|
|
13
|
+
export type { OtpVerificationFailure, OtpVerificationResult, VerificationAdapter, } from "./otp";
|
|
11
14
|
export type { Call, ConnectCapabilities, ConnectRequest, ConnectResponse, GuestRequest, GuestResponse, MethodName, MethodParams, MethodResult, RestoreResponse, RpcRequest, SendCallsParams, SendCallsRequest, SendCallsResponse, SendTransactionParams, SendTransactionRequest, SendTransactionResponse, SignMessageRequest, SignMessageResponse, SignOutRequest, SignOutResponse, SignTypedDataRequest, SignTypedDataResponse, TransactionArgs, TypedData, TypedDataDomain, TypedDataField, } from "./protocol";
|
|
12
15
|
export { getConnectCapabilities, isPersonalSignParams, isSendCallsParams, isSendTransactionParams, } from "./protocol";
|
|
16
|
+
export type { ReportOperation, ReportRequest, ReportResponse, ReportsApi, ReportTransport, } from "./reports";
|
|
13
17
|
export type { CreateRoomEventInput, RoomEventArchive, RoomEventAttendance, RoomEventFrequency, RoomEventInstance, RoomEventInterest, RoomEventInterestState, RoomEventList, RoomEventOccurrence, RoomEventRecurrence, RoomEventRoomRef, RoomEventRun, RoomEventSeries, RoomEventStatus, SetInterestInput, UpdateRoomEventInput, } from "./room-events";
|
|
14
18
|
export type { CreateRoomInput, GlobalRole, ModerationSubject, MyRooms, PlayerPositionReport, RoleChangeVerdict, RoomCapabilities, RoomCapability, RoomChannel, RoomDetail, RoomList, RoomMemberEntry, RoomMembers, RoomOccupancy, RoomOwner, RoomPlayerPosition, RoomPresenceEntry, RoomPresenceSnapshot, RoomRestrictionKind, RoomRole, RoomSummary, RoomSurfaceSettings, RoomsApi, RoomVisibility, StaffEntry, UpdateRoomInput, VerifyRoomContext, Viewer, VoiceDecisionReason, VoiceDecisionSubject, VoiceRoomDecision, } from "./rooms";
|
|
15
19
|
export type { AccessKeyOptions, AccessKeyPreparation, Address, ColorScheme, CreateDialogHostOptions, CreateFlowOptions, DialogHost, DialogOpenOptions, FinalizeAccessKeyParams, Flow, FlowConnectorParameters, FlowCookieNames, FlowIdProviderProps, FlowSessionState, FlowState, FlowWidgetHandle, FlowWidgetName, FlowWidgetProps, Listener, LoginOptions, MountFlowWidgetOptions, MountProfileOptions, OpenProfileOptions, PrepareArgsWithAuth, PrepareTransactionRequestPhase, ProfileButtonHandle, ProfileButtonProps, ProfilePosition, ResolveAccountParams, ResolvedAccessKeyOptions, RootCredential, RunLoginParams, RunLoginResult, SendCallsArgs, SendTransactionArgs, Session, SigningContext, SignMessageArgs, SignTypedDataArgs, Store, StoredAccessKey, UseOpenProfileOptions, WagmiConnectCapabilities, WagmiConnectParams, } from "./sdk";
|
|
16
20
|
export type { GracefulShutdownCleanup, GracefulShutdownOptions, GracefulShutdownServer, GracefulShutdownSignal, ResolvedFlowSession, ResolveSessionOptions, SessionRouteOptions, SessionRouteResponse, SessionRouteSession, } from "./server";
|
|
21
|
+
export type { CosmeticOffer, PaintDescriptor, SettingDescriptor, Settings, SettingsMigration, StoredSettings, SurfaceRegistry, } from "./settings";
|
|
17
22
|
export type { CreateStudySubjectInput, ListStudySessionsInput, StudyCatalog, StudyCategory, StudyCategoryTotals, StudyField, StudyRange, StudySessionEntry, StudySessionPage, StudySessionsResult, StudySubject, StudySubjectCreation, StudySubjectList, StudySubjectRefusal, StudySubjectRemoval, StudySubjectRemovalResponse, StudySubjectTotals, StudySubjectUpdate, StudySummary, UpdateStudySubjectInput, } from "./study";
|
|
18
23
|
export type { CoinAsset, IdentifiedTx, TxApprove, TxConvert, TxSend, TxSwap, } from "./tx";
|
|
19
|
-
export type { ActionCatalogEntry, ActionCatalogResponse, ActionDayContext, ActionEventKind, ActionSessionState, ActionSubjectRef, ActionSurface, ActionTransitionKind, ActiveActionResponse, ActiveSessionConflict, CurrentAction, FinishActionResponse, LevelProgress, PublicProfile, PublicProfileRefusal, PublicProfileResult, PublicProfileSignal, PublicUserProfile, StartActionResponse, StartUserSessionResult, UserActionSurface, XpGrantResult, XpMode, XpRecentGrant, XpSummary, } from "./xp";
|
|
24
|
+
export type { ActionCatalogEntry, ActionCatalogResponse, ActionDayContext, ActionDurations, ActionEventKind, ActionSessionState, ActionSubjectRef, ActionSurface, ActionTimelineEvent, ActionTransitionKind, ActiveActionResponse, ActiveSessionConflict, CurrentAction, FinishActionResponse, LevelProgress, PublicProfile, PublicProfileRefusal, PublicProfileResult, PublicProfileSignal, PublicUserProfile, StartActionResponse, StartUserSessionResult, UserActionSurface, XpGrantResult, XpMode, XpRecentGrant, XpSummary, } from "./xp";
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AuthErrorCode } from "./events";
|
|
2
|
+
export type OtpVerificationFailure = {
|
|
3
|
+
ok: false;
|
|
4
|
+
errorCode: AuthErrorCode;
|
|
5
|
+
apiCode: "INVALID_OTP" | "OTP_EXPIRED" | "TOO_MANY_ATTEMPTS";
|
|
6
|
+
status: 400 | 403;
|
|
7
|
+
message: string;
|
|
8
|
+
attemptsRemaining?: number;
|
|
9
|
+
};
|
|
10
|
+
export type OtpVerificationResult = {
|
|
11
|
+
ok: true;
|
|
12
|
+
} | OtpVerificationFailure;
|
|
13
|
+
export interface VerificationAdapter {
|
|
14
|
+
findVerificationValue(identifier: string): Promise<{
|
|
15
|
+
id: string;
|
|
16
|
+
value: string;
|
|
17
|
+
expiresAt: Date;
|
|
18
|
+
} | null | undefined>;
|
|
19
|
+
deleteVerificationValue(id: string): Promise<void>;
|
|
20
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { httpOperations } from "../contracts/http";
|
|
3
|
+
export type ReportOperation = keyof typeof httpOperations;
|
|
4
|
+
export type ReportRequest<T extends ReportOperation> = z.input<(typeof httpOperations)[T]["request"]>;
|
|
5
|
+
export type ReportResponse<T extends ReportOperation> = z.output<(typeof httpOperations)[T]["response"]>;
|
|
6
|
+
export type ReportTransport = (input: URL | RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
7
|
+
export type ReportsApi = <T extends ReportOperation>(operation: T, body: ReportRequest<T>) => Promise<ReportResponse<T>>;
|
|
File without changes
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { RawValue } from "../json";
|
|
2
|
+
import type { CosmeticItem, CosmeticMaterial, CosmeticSlot, EquipRegion, SettingsConflict } from "./cosmetics";
|
|
3
|
+
export interface PaintDescriptor {
|
|
4
|
+
key: string;
|
|
5
|
+
group: string;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
type: "paint";
|
|
9
|
+
default: string;
|
|
10
|
+
options: {
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
}[];
|
|
14
|
+
/**
|
|
15
|
+
* The item this colour lands on, and the material on it that is recoloured.
|
|
16
|
+
* Both travel on the descriptor rather than being read back out of the key: a
|
|
17
|
+
* form grouping its pickers by item, and a renderer deciding which surface a
|
|
18
|
+
* colour applies to, each want one of them, and neither should be taking a
|
|
19
|
+
* key apart to get it.
|
|
20
|
+
*/
|
|
21
|
+
cosmetic: string;
|
|
22
|
+
material: CosmeticMaterial;
|
|
23
|
+
}
|
|
24
|
+
export interface CosmeticOffer extends CosmeticItem {
|
|
25
|
+
/**
|
|
26
|
+
* Every equip region this item cannot share a body with — its own, plus
|
|
27
|
+
* everything they overlap. Another item is blocked by this one exactly when
|
|
28
|
+
* its `regions` intersect this list, so a client tests a set instead of
|
|
29
|
+
* re-implementing the rule.
|
|
30
|
+
*/
|
|
31
|
+
conflicts: readonly EquipRegion[];
|
|
32
|
+
/**
|
|
33
|
+
* The colour pickers this item brings once it is worn: the SAME descriptors
|
|
34
|
+
* {@link SurfaceRegistry.derived} emits for it, from the same builder, so a
|
|
35
|
+
* client rendering its draft and a client reading the derived list for a
|
|
36
|
+
* saved loadout draw the same rows.
|
|
37
|
+
*
|
|
38
|
+
* An offer, not a setting. A colour is a setting the player HAS only while
|
|
39
|
+
* its item is equipped — that is what {@link sanitize} prunes on — and
|
|
40
|
+
* nothing here widens the stored blob or the write path.
|
|
41
|
+
*/
|
|
42
|
+
paint: readonly PaintDescriptor[];
|
|
43
|
+
}
|
|
44
|
+
export type SettingDescriptor = {
|
|
45
|
+
key: string;
|
|
46
|
+
group: string;
|
|
47
|
+
label: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
type: "number";
|
|
50
|
+
default: number;
|
|
51
|
+
min: number;
|
|
52
|
+
max: number;
|
|
53
|
+
step: number;
|
|
54
|
+
} | {
|
|
55
|
+
key: string;
|
|
56
|
+
group: string;
|
|
57
|
+
label: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
type: "boolean";
|
|
60
|
+
default: boolean;
|
|
61
|
+
} | {
|
|
62
|
+
key: string;
|
|
63
|
+
group: string;
|
|
64
|
+
label: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
type: "enum";
|
|
67
|
+
default: string;
|
|
68
|
+
options: {
|
|
69
|
+
value: string;
|
|
70
|
+
label: string;
|
|
71
|
+
}[];
|
|
72
|
+
} | {
|
|
73
|
+
key: string;
|
|
74
|
+
group: string;
|
|
75
|
+
label: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
/** Free text with a shape, for values no fixed option list can cover —
|
|
78
|
+
* a Discord snowflake, a channel id. `pattern` is a source string (not a
|
|
79
|
+
* RegExp) so the descriptor stays JSON-serializable for the schema
|
|
80
|
+
* endpoint the settings form reads. */
|
|
81
|
+
type: "text";
|
|
82
|
+
default: string;
|
|
83
|
+
maxLength: number;
|
|
84
|
+
pattern?: string;
|
|
85
|
+
} | {
|
|
86
|
+
key: string;
|
|
87
|
+
group: string;
|
|
88
|
+
label: string;
|
|
89
|
+
description?: string;
|
|
90
|
+
/** One cosmetic slot: the stored value is a catalog cosmetic id, or ""
|
|
91
|
+
* for nothing equipped. `items` is the catalog projection the customizer
|
|
92
|
+
* reads off the schema endpoint so it can render a draft loadout with no
|
|
93
|
+
* catalog data of its own — which picks would collide, and which colour
|
|
94
|
+
* pickers a pick brings with it. UX only; the conflict rule is enforced
|
|
95
|
+
* on save, and a draft is never a claim about what may be saved.
|
|
96
|
+
*
|
|
97
|
+
* The default is an item id, not "": a player who has never dressed is
|
|
98
|
+
* wearing the starting outfit, and saying so here is what lets "" mean
|
|
99
|
+
* the one thing it should — a player who chose to wear nothing there. */
|
|
100
|
+
type: "cosmetic";
|
|
101
|
+
default: string;
|
|
102
|
+
slot: CosmeticSlot;
|
|
103
|
+
/**
|
|
104
|
+
* Whether an avatar may go with this slot empty. False is the slot a
|
|
105
|
+
* client offers a "None" chip for; true is one where `""` is refused on
|
|
106
|
+
* save. Projected here rather than restated in the customizer for the
|
|
107
|
+
* reason {@link CosmeticOffer.conflicts} is: the rule belongs to the
|
|
108
|
+
* slot, and a second hand-maintained copy of it goes quiet (AUTH-222).
|
|
109
|
+
*/
|
|
110
|
+
required: boolean;
|
|
111
|
+
items: readonly CosmeticOffer[];
|
|
112
|
+
} | PaintDescriptor;
|
|
113
|
+
export type StoredSettings = Record<string, RawValue>;
|
|
114
|
+
export type Settings = Record<string, number | boolean | string>;
|
|
115
|
+
export interface SettingsMigration {
|
|
116
|
+
to: number;
|
|
117
|
+
up: (stored: StoredSettings) => StoredSettings;
|
|
118
|
+
}
|
|
119
|
+
export interface SurfaceRegistry {
|
|
120
|
+
/**
|
|
121
|
+
* Bumped only when a setting in this surface is renamed or retyped. A stored
|
|
122
|
+
* blob stamps the version it was last normalized to; {@link normalize} walks
|
|
123
|
+
* an old blob up to this version on read, preserving the user's chosen value
|
|
124
|
+
* instead of dropping it. Adding or removing a setting does NOT bump it.
|
|
125
|
+
*/
|
|
126
|
+
version: number;
|
|
127
|
+
settings: readonly SettingDescriptor[];
|
|
128
|
+
/**
|
|
129
|
+
* The steps {@link normalize} walks an out-of-date blob up through, in
|
|
130
|
+
* ascending {@link SettingsMigration.to} order. A surface that has never
|
|
131
|
+
* renamed anything has none, and its blobs need no walk.
|
|
132
|
+
*/
|
|
133
|
+
migrations?: readonly SettingsMigration[];
|
|
134
|
+
/**
|
|
135
|
+
* Enum defaults are drawn from the option list seeded by the user id instead
|
|
136
|
+
* of the descriptor default, so every unsaved user gets their own stable
|
|
137
|
+
* random pick — identical on every read and on every surface that reads it.
|
|
138
|
+
*/
|
|
139
|
+
randomDefaults?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Cross-field rule for the whole surface, evaluated on the MERGED blob by
|
|
142
|
+
* the one settings write path. Per-descriptor {@link sanitize} cannot
|
|
143
|
+
* express it: an equip-region collision is a relation between two keys, not
|
|
144
|
+
* a property of either. Living on the surface rather than in a route is what
|
|
145
|
+
* makes it impossible for a second write path to skip.
|
|
146
|
+
*/
|
|
147
|
+
validate?: (settings: Settings) => SettingsConflict | null;
|
|
148
|
+
/**
|
|
149
|
+
* The settings this surface has only because of what is stored in it — the
|
|
150
|
+
* appearance surface's colour pickers for the cosmetics a player is
|
|
151
|
+
* currently wearing.
|
|
152
|
+
*
|
|
153
|
+
* Derived rather than fixed is the whole mechanism: a setting that exists
|
|
154
|
+
* only while its cosmetic is equipped is dropped by {@link sanitize} the
|
|
155
|
+
* moment the cosmetic is not, so unequipping an item takes its colour with
|
|
156
|
+
* it and re-equipping cannot resurrect a colour the player never chose.
|
|
157
|
+
*
|
|
158
|
+
* Reads the surface's FIXED settings only, never its own output, so the
|
|
159
|
+
* descriptor list is resolved in one pass and cannot recurse.
|
|
160
|
+
*/
|
|
161
|
+
derived?: (settings: Settings) => readonly SettingDescriptor[];
|
|
162
|
+
}
|
|
File without changes
|
package/dist/sdk/types/xp.d.ts
CHANGED
|
@@ -212,3 +212,11 @@ export interface CurrentAction {
|
|
|
212
212
|
since: string;
|
|
213
213
|
subject?: string;
|
|
214
214
|
}
|
|
215
|
+
export interface ActionTimelineEvent {
|
|
216
|
+
kind: ActionEventKind;
|
|
217
|
+
at: Date;
|
|
218
|
+
}
|
|
219
|
+
export interface ActionDurations {
|
|
220
|
+
accruedSeconds: number;
|
|
221
|
+
focusedSeconds: number;
|
|
222
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flow-industries/id",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -50,10 +50,18 @@
|
|
|
50
50
|
"./start/server": {
|
|
51
51
|
"types": "./dist/sdk/start/server.d.ts",
|
|
52
52
|
"import": "./dist/sdk/start/server.js"
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
|
+
"./focus": {
|
|
55
|
+
"types": "./dist/sdk/client/focus.d.ts",
|
|
56
|
+
"import": "./dist/sdk/client/focus.js"
|
|
57
|
+
},
|
|
58
|
+
"./contracts/v1/reports.json": "./contracts/v1/reports.json",
|
|
59
|
+
"./contracts/v1/openapi.json": "./contracts/v1/openapi.json",
|
|
60
|
+
"./contracts/v1/sdk-exports.json": "./contracts/v1/sdk-exports.json"
|
|
54
61
|
},
|
|
55
62
|
"files": [
|
|
56
|
-
"dist/sdk"
|
|
63
|
+
"dist/sdk",
|
|
64
|
+
"contracts"
|
|
57
65
|
],
|
|
58
66
|
"scripts": {
|
|
59
67
|
"dev": "./dev.sh",
|
|
@@ -67,7 +75,7 @@
|
|
|
67
75
|
"worker": "bun run src/worker.ts",
|
|
68
76
|
"db:generate": "bunx @better-auth/cli generate",
|
|
69
77
|
"db:migrate:gen": "bunx drizzle-kit generate",
|
|
70
|
-
"db:migrate": "
|
|
78
|
+
"db:migrate": "bun scripts/db-migrate.ts",
|
|
71
79
|
"db:push": "bunx drizzle-kit push",
|
|
72
80
|
"db:studio": "bunx drizzle-kit studio",
|
|
73
81
|
"usernames:refresh": "bun run scripts/generate-reserved-usernames.ts",
|
|
@@ -76,7 +84,11 @@
|
|
|
76
84
|
"test:sdk-package": "bash scripts/test-sdk-package.sh",
|
|
77
85
|
"format": "biome format --write",
|
|
78
86
|
"check": "biome check --write",
|
|
79
|
-
"typecheck": "tsr generate && tsc --noEmit"
|
|
87
|
+
"typecheck": "tsr generate && tsc --noEmit",
|
|
88
|
+
"contracts:generate": "bun scripts/generate-contracts.ts",
|
|
89
|
+
"contracts:check": "bun scripts/generate-contracts.ts --check && bun scripts/check-contract-compatibility.ts",
|
|
90
|
+
"db:check": "bun scripts/db-check.ts",
|
|
91
|
+
"test:migrations": "bun test scripts/migrations.test.ts scripts/migration-drift.test.ts"
|
|
80
92
|
},
|
|
81
93
|
"peerDependencies": {
|
|
82
94
|
"viem": ">=2.47.10",
|
|
@@ -118,7 +130,9 @@
|
|
|
118
130
|
"tailwindcss": "^4.1.18",
|
|
119
131
|
"tw-animate-css": "^1.4.0",
|
|
120
132
|
"typescript": "^5",
|
|
121
|
-
"vite": "^7.3.1"
|
|
133
|
+
"vite": "^7.3.1",
|
|
134
|
+
"react": "^19.2.4",
|
|
135
|
+
"react-dom": "^19.2.4"
|
|
122
136
|
},
|
|
123
137
|
"trustedDependencies": [
|
|
124
138
|
"esbuild",
|
|
@@ -126,7 +140,7 @@
|
|
|
126
140
|
],
|
|
127
141
|
"dependencies": {
|
|
128
142
|
"@aws-sdk/client-s3": "^3.1073.0",
|
|
129
|
-
"@flow-industries/ui": "^0.21.
|
|
143
|
+
"@flow-industries/ui": "^0.21.1",
|
|
130
144
|
"@hono/otel": "^1.1.2",
|
|
131
145
|
"@openobserve/browser-logs": "^0.3.1",
|
|
132
146
|
"@openobserve/browser-rum": "^0.3.1",
|
|
@@ -151,8 +165,6 @@
|
|
|
151
165
|
"motion": "^12.33.0",
|
|
152
166
|
"pino": "^10.3.1",
|
|
153
167
|
"postgres": "^3.4.8",
|
|
154
|
-
"react": "^19.2.4",
|
|
155
|
-
"react-dom": "^19.2.4",
|
|
156
168
|
"react-intersection-observer": "^10.0.2",
|
|
157
169
|
"sharp": "^0.35.2",
|
|
158
170
|
"tempo.ts": "^0.14.2",
|