@oxyhq/core 3.18.0 → 4.0.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.
Files changed (42) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/OxyServices.js +3 -2
  3. package/dist/cjs/mixins/OxyServices.accounts.js +480 -0
  4. package/dist/cjs/mixins/OxyServices.connectedApps.js +73 -0
  5. package/dist/cjs/mixins/OxyServices.utility.js +3 -2
  6. package/dist/cjs/mixins/index.js +9 -6
  7. package/dist/esm/.tsbuildinfo +1 -1
  8. package/dist/esm/OxyServices.js +3 -2
  9. package/dist/esm/mixins/OxyServices.accounts.js +477 -0
  10. package/dist/esm/mixins/OxyServices.connectedApps.js +70 -0
  11. package/dist/esm/mixins/OxyServices.utility.js +3 -2
  12. package/dist/esm/mixins/index.js +9 -6
  13. package/dist/types/.tsbuildinfo +1 -1
  14. package/dist/types/OxyServices.d.ts +3 -2
  15. package/dist/types/index.d.ts +2 -3
  16. package/dist/types/mixins/OxyServices.accounts.d.ts +642 -0
  17. package/dist/types/mixins/OxyServices.auth.d.ts +1 -1
  18. package/dist/types/mixins/OxyServices.connectedApps.d.ts +168 -0
  19. package/dist/types/mixins/OxyServices.utility.d.ts +6 -3
  20. package/dist/types/mixins/index.d.ts +3 -4
  21. package/package.json +2 -2
  22. package/src/OxyServices.ts +3 -2
  23. package/src/index.ts +33 -34
  24. package/src/mixins/OxyServices.accounts.ts +1079 -0
  25. package/src/mixins/OxyServices.auth.ts +1 -1
  26. package/src/mixins/OxyServices.connectedApps.ts +165 -0
  27. package/src/mixins/OxyServices.utility.ts +7 -4
  28. package/src/mixins/__tests__/accounts.test.ts +667 -0
  29. package/src/mixins/__tests__/connectedApps.test.ts +1 -1
  30. package/src/mixins/index.ts +11 -9
  31. package/dist/cjs/mixins/OxyServices.applications.js +0 -350
  32. package/dist/cjs/mixins/OxyServices.managedAccounts.js +0 -143
  33. package/dist/cjs/mixins/OxyServices.workspaces.js +0 -181
  34. package/dist/esm/mixins/OxyServices.applications.js +0 -347
  35. package/dist/esm/mixins/OxyServices.managedAccounts.js +0 -140
  36. package/dist/esm/mixins/OxyServices.workspaces.js +0 -178
  37. package/dist/types/mixins/OxyServices.applications.d.ts +0 -496
  38. package/dist/types/mixins/OxyServices.managedAccounts.d.ts +0 -145
  39. package/dist/types/mixins/OxyServices.workspaces.d.ts +0 -219
  40. package/src/mixins/OxyServices.applications.ts +0 -773
  41. package/src/mixins/OxyServices.managedAccounts.ts +0 -173
  42. package/src/mixins/OxyServices.workspaces.ts +0 -351
@@ -82,8 +82,9 @@ import { composeOxyServices } from './mixins';
82
82
  * - **Payment**: Payment processing
83
83
  * - **Reputation**: Reputation system (Oxy Trust)
84
84
  * - **Assets**: File upload and asset management
85
- * - **Applications**: Application, membership, and credential management
86
- * - **Workspaces**: Workspace and membership management
85
+ * - **Accounts**: Unified account graph (tree, members, roles, bot credentials)
86
+ * and the applications owned within it (Application = OAuth client)
87
+ * - **Connected apps**: OAuth-consent surface (public app identity, grants)
87
88
  * - **Location**: Location-based features
88
89
  * - **Analytics**: Analytics tracking
89
90
  * - **Devices**: Device management
@@ -33,7 +33,6 @@ export { ServiceCredentialMismatchError } from './mixins/OxyServices.auth';
33
33
  export type { ServiceTokenResponse } from './mixins/OxyServices.auth';
34
34
  export type { CommonsSignInHandle, CommonsSignInStatus, CommonsApprovalInfo, CommonsSignInActionResult, } from './mixins/OxyServices.auth';
35
35
  export type { ServiceApp, ServiceActingAsVerification } from './mixins/OxyServices.utility';
36
- export type { CreateManagedAccountInput, ManagedAccountManager, ManagedAccount, } from './mixins/OxyServices.managedAccounts';
37
36
  export type { ContactDiscoveryMatch, ContactDiscoveryResponse, } from './mixins/OxyServices.contacts';
38
37
  export type { BulkFollowEntry, BulkFollowResult, BulkUnfollowEntry, BulkUnfollowResult, } from './mixins/OxyServices.user';
39
38
  export { OxyAppDataIdentifierError } from './mixins/OxyServices.appData';
@@ -42,8 +41,8 @@ export { getCanonicalUserHandle, getNormalizedUserHandle, } from './utils/userHa
42
41
  export type { CanonicalUserHandleInput, UserHandleInput } from './utils/userHandle';
43
42
  export { normalizeProfileLinks } from './utils/profileLinks';
44
43
  export type { ProfileLink, ProfileLinkMetadata } from './utils/profileLinks';
45
- export type { Application, PublicApplication, ConnectedApp, ApplicationMember, ApplicationCredential, ApplicationRole, ApplicationType, ApplicationStatus, ApplicationMemberStatus, ApplicationCredentialType, ApplicationCredentialStatus, ApplicationEnvironment, CreateApplicationInput, UpdateApplicationInput, InviteApplicationMemberInput, UpdateApplicationMemberInput, TransferApplicationOwnershipInput, CreateApplicationCredentialInput, ApplicationCredentialWithSecret, RotateApplicationCredentialResult, ApplicationUsagePeriod, ApplicationUsageSummary, ApplicationUsageByDay, ApplicationUsageByEndpoint, ApplicationUsageStats, ApplicationSuccessResult, } from './mixins/OxyServices.applications';
46
- export type { Workspace, WorkspaceMember, WorkspaceRole, WorkspaceType, WorkspaceStatus, WorkspaceMemberStatus, CreateWorkspaceInput, UpdateWorkspaceInput, InviteWorkspaceMemberInput, UpdateWorkspaceMemberInput, TransferWorkspaceOwnershipInput, WorkspaceSuccessResult, } from './mixins/OxyServices.workspaces';
44
+ export type { PublicApplication, ConnectedApp, } from './mixins/OxyServices.connectedApps';
45
+ export type { AccountKind, AccountRelationship, AccountRole, AccountMemberStatus, AccountMemberSource, AccountMember, AccountNode, AccountCredentialType, AccountCredentialEnvironment, AccountCredentialStatus, AccountCredential, AccountCredentialWithSecret, RotateAccountCredentialResult, ListAccountsOptions, CreateAccountInput, UpdateAccountInput, InviteAccountMemberInput, UpdateAccountMemberInput, TransferAccountOwnershipInput, CreateAccountCredentialInput, AccountSuccessResult, Application, ApplicationType, ApplicationStatus, ApplicationCredential, ApplicationCredentialType, ApplicationCredentialStatus, ApplicationEnvironment, CreateApplicationInput, UpdateApplicationInput, CreateApplicationCredentialInput, ApplicationCredentialWithSecret, RotateApplicationCredentialResult, ApplicationUsagePeriod, ApplicationUsageSummary, ApplicationUsageByDay, ApplicationUsageByEndpoint, ApplicationUsageStats, } from './mixins/OxyServices.accounts';
47
46
  export type { ReputationCategory, TrustTier, ReputationTransactionStatus, ReputationTargetEntityType, ReputationDisputeStatus, ReputationInfluenceContext, ReputationTransaction, ReputationBalanceBreakdown, ReputationInfluence, ReputationReliability, ReputationBalance, ReputationDispute, ReputationRule, ReputationLeaderboardEntry, ReputationInfluenceResult, ReverseReputationTransactionResult, AwardReputationInput, CreateReputationDisputeInput, ResolveReputationDisputeInput, UpsertReputationRuleInput, ReverseReputationTransactionInput, } from './mixins/OxyServices.reputation';
48
47
  export { buildUserDid } from './mixins/OxyServices.identity';
49
48
  export type { IdentityRecordType, UnlinkableAuthMethodType, LinkAuthMethodResult, PublishRecordResult, VerifyRecordResult, VerifyDomainResult, RemoveDomainResult, } from './mixins/OxyServices.identity';
@@ -0,0 +1,642 @@
1
+ /**
2
+ * Accounts Methods Mixin
3
+ *
4
+ * The single client surface for the unified Oxy **account graph** (`/accounts`)
5
+ * and the **applications** owned within it (`/applications`).
6
+ *
7
+ * An account is a relational, tree-structured principal (the `User` document
8
+ * generalised): a `personal` account is a human login at the root of its tree;
9
+ * `organization` / `project` / `bot` accounts are non-login principals operated
10
+ * through membership. Accounts form a tree (`parentAccountId`), own
11
+ * applications/bots, and expose a single membership model (`AccountMember`) with
12
+ * a unified role set and an explicit-but-inheritable cascade down the subtree.
13
+ *
14
+ * This mixin is the clean-cut replacement for the former `managedAccounts`,
15
+ * `workspaces`, and `applications` (account-management) mixins. Applications are
16
+ * now owned by an account (`Application.ownerAccountId`) and their access derives
17
+ * from the caller's `AccountMember` on that owning account — there is no separate
18
+ * application-membership surface. The OAuth-consent surface a user sees for
19
+ * THIRD-PARTY apps they authorized (`getPublicApplication`, `listConnectedApps`,
20
+ * `revokeAppGrant`) is unrelated to account ownership and lives in
21
+ * `OxyServices.connectedApps.ts`.
22
+ *
23
+ * Reference accounts by their Mongo `_id` (`accountId`, the underlying
24
+ * `User._id`), applications by their `_id` (`applicationId`), members by their
25
+ * member `_id`, and credentials by their `credentialId`. Never by name, slug, or
26
+ * handle.
27
+ *
28
+ * NOTE: acting-as (delegated identity) is NOT part of this mixin — `setActingAs`
29
+ * / `getActingAs` live on `OxyServices.base` and `verifyActingAs` on the utility
30
+ * mixin (it verifies against `GET /accounts/verify-acting-as`).
31
+ */
32
+ import type { User } from '../models/interfaces';
33
+ import type { OxyServicesBase } from '../OxyServices.base';
34
+ /**
35
+ * Account classification, orthogonal to the federation `type`
36
+ * (`local|federated|agent|automated`). `personal` accounts have a direct login;
37
+ * `organization` / `project` / `bot` accounts are operated via `AccountMember`
38
+ * and have no direct login.
39
+ */
40
+ export type AccountKind = 'personal' | 'organization' | 'project' | 'bot';
41
+ /**
42
+ * The calling user's relationship to an account node, as resolved by the API:
43
+ * - `self` — the caller's own personal (root) account.
44
+ * - `owner` — an account the caller owns (e.g. an org/project/bot they created).
45
+ * - `member` — an account shared with the caller via membership (including
46
+ * external organisations).
47
+ */
48
+ export type AccountRelationship = 'self' | 'owner' | 'member';
49
+ /** Role a member holds within an account. The unified account role set. */
50
+ export type AccountRole = 'owner' | 'admin' | 'editor' | 'developer' | 'billing' | 'viewer';
51
+ /** Membership lifecycle status. */
52
+ export type AccountMemberStatus = 'active' | 'invited' | 'removed';
53
+ /**
54
+ * Origin of a resolved membership. `direct` is a membership row on the account
55
+ * itself; `inherited` is resolved from the nearest ancestor account whose
56
+ * membership row has `inherit: true` (role inheritance cascades down the tree).
57
+ */
58
+ export type AccountMemberSource = 'direct' | 'inherited';
59
+ /**
60
+ * Client-facing AccountMember shape. `permissions` is derived from `role` on the
61
+ * server at write time.
62
+ */
63
+ export interface AccountMember {
64
+ _id: string;
65
+ /** The account this membership grants access to (account `_id`). */
66
+ accountId: string;
67
+ /** The member's personal-account `User._id`. */
68
+ memberUserId: string;
69
+ role: AccountRole;
70
+ permissions: string[];
71
+ /**
72
+ * Whether this membership cascades to the account's subtree. `true` (default)
73
+ * lets descendants inherit this role unless a nearer row overrides it; `false`
74
+ * opts this row out of inheritance (it applies to this account only).
75
+ */
76
+ inherit: boolean;
77
+ status: AccountMemberStatus;
78
+ /**
79
+ * Origin of the membership when the API resolves an effective role. Present on
80
+ * a resolved `callerMembership` to indicate whether the caller's access is
81
+ * `direct` on the account or `inherited` from an ancestor. Absent on plain
82
+ * member-list rows (which are always direct rows on the account).
83
+ */
84
+ source?: AccountMemberSource;
85
+ invitedByUserId?: string | null;
86
+ joinedAt?: string | null;
87
+ createdAt: string;
88
+ updatedAt: string;
89
+ }
90
+ /**
91
+ * A node in the account graph as returned by the `/accounts` API. `account` is
92
+ * the underlying generalised `User` document; `relationship` and
93
+ * `callerMembership` describe the caller's access. On a flat list every node
94
+ * carries `parentAccountId`; with `tree:true`, `children` is populated and
95
+ * `childCount` reflects the number of direct children.
96
+ */
97
+ export interface AccountNode {
98
+ /** The account's Mongo `_id` (the underlying `User._id`). */
99
+ accountId: string;
100
+ kind: AccountKind;
101
+ /** Parent account `_id`, or `null` for a root (personal) account. */
102
+ parentAccountId: string | null;
103
+ /** The generalised `User` document backing this account. */
104
+ account: User;
105
+ relationship: AccountRelationship;
106
+ /**
107
+ * The caller's effective membership in this account (direct or inherited), or
108
+ * `null` when the caller has no membership (e.g. their own `self` root, where
109
+ * ownership is implicit). Use `callerMembership.permissions` to gate UI.
110
+ */
111
+ callerMembership: AccountMember | null;
112
+ /** Number of direct child accounts (present when the API computes it). */
113
+ childCount?: number;
114
+ /** Direct children, populated when the list is requested with `tree:true`. */
115
+ children?: AccountNode[];
116
+ }
117
+ /** Options accepted by `listAccounts`. */
118
+ export interface ListAccountsOptions {
119
+ /**
120
+ * When `true`, request the nested tree representation: each returned node has
121
+ * its `children` populated instead of a flat list keyed by `parentAccountId`.
122
+ */
123
+ tree?: boolean;
124
+ }
125
+ /** Input accepted by `createAccount`. */
126
+ export interface CreateAccountInput {
127
+ /** Classification of the new account. `personal` accounts are not created here. */
128
+ kind: AccountKind;
129
+ /**
130
+ * Parent account `_id` to nest the new account under. Omitted → the API roots
131
+ * it under the caller's personal account.
132
+ */
133
+ parentAccountId?: string;
134
+ /** Unique handle for the account (shares the `User.username` unique index). */
135
+ username: string;
136
+ name?: {
137
+ first?: string;
138
+ last?: string;
139
+ };
140
+ bio?: string;
141
+ avatar?: string;
142
+ }
143
+ /** Input accepted by `updateAccount`. Tree placement changes go through `/move`. */
144
+ export interface UpdateAccountInput {
145
+ username?: string;
146
+ name?: {
147
+ first?: string;
148
+ last?: string;
149
+ };
150
+ bio?: string | null;
151
+ avatar?: string | null;
152
+ }
153
+ /** Input accepted by `inviteAccountMember`. The owner role cannot be invited. */
154
+ export interface InviteAccountMemberInput {
155
+ /**
156
+ * The username or email of the user to invite. Resolved to a personal account
157
+ * server-side; an unknown value yields a 404 "User not found".
158
+ */
159
+ usernameOrEmail: string;
160
+ role: Exclude<AccountRole, 'owner'>;
161
+ }
162
+ /** Input accepted by `updateAccountMember`. The owner role cannot be assigned. */
163
+ export interface UpdateAccountMemberInput {
164
+ role: Exclude<AccountRole, 'owner'>;
165
+ }
166
+ /** Input accepted by `transferAccountOwnership`. */
167
+ export interface TransferAccountOwnershipInput {
168
+ userId: string;
169
+ }
170
+ /** Credential kind. Account (bot) credentials are always `service` tokens. */
171
+ export type AccountCredentialType = 'service';
172
+ /** Deployment environment a bot credential is scoped to. */
173
+ export type AccountCredentialEnvironment = 'development' | 'staging' | 'production';
174
+ /** Bot credential lifecycle status. */
175
+ export type AccountCredentialStatus = 'active' | 'deprecated' | 'revoked';
176
+ /** Input accepted by `createAccountCredential`. Credential `type` is always `service`. */
177
+ export interface CreateAccountCredentialInput {
178
+ name: string;
179
+ environment: AccountCredentialEnvironment;
180
+ scopes?: string[];
181
+ }
182
+ /**
183
+ * Client-facing AccountCredential shape (a bot account's service token). The raw
184
+ * secret is NEVER part of this shape — it is returned exactly once, separately,
185
+ * at creation/rotation.
186
+ */
187
+ export interface AccountCredential {
188
+ _id: string;
189
+ /** The bot account this credential authenticates as (account `_id`). */
190
+ accountId: string;
191
+ name: string;
192
+ publicKey: string;
193
+ type: AccountCredentialType;
194
+ environment: AccountCredentialEnvironment;
195
+ scopes: string[];
196
+ status: AccountCredentialStatus;
197
+ lastUsedAt?: string;
198
+ expiresAt?: string;
199
+ /**
200
+ * Audit link to the credential this one was rotated FROM. Populated on
201
+ * credentials created via rotation; absent on original credentials.
202
+ */
203
+ rotatedFromCredentialId?: string;
204
+ createdByUserId: string;
205
+ createdAt: string;
206
+ updatedAt: string;
207
+ }
208
+ /** Result of creating a bot credential — `secret` is returned ONCE. */
209
+ export interface AccountCredentialWithSecret {
210
+ credential: AccountCredential;
211
+ secret: string;
212
+ }
213
+ /**
214
+ * Result of rotating a bot credential. Extends the create result with audit
215
+ * fields: the new plaintext `secret` is returned ONCE, plus `rotatedFrom` (the
216
+ * previous credential's `credentialId`) and `graceExpiresAt` (ISO string marking
217
+ * when the old credential stops being honoured during the rotation grace window).
218
+ */
219
+ export interface RotateAccountCredentialResult extends AccountCredentialWithSecret {
220
+ /** The previous credential's `credentialId` that this rotation supersedes. */
221
+ rotatedFrom: string;
222
+ /** ISO timestamp at which the rotated-from credential's grace window ends. */
223
+ graceExpiresAt: string;
224
+ }
225
+ /**
226
+ * Application classification. Set only by Oxy platform staff — never editable
227
+ * through the normal member-facing update path.
228
+ */
229
+ export type ApplicationType = 'first_party' | 'third_party' | 'internal' | 'system';
230
+ /** Lifecycle status of an application. */
231
+ export type ApplicationStatus = 'active' | 'suspended' | 'deleted' | 'pending_review';
232
+ /** OAuth credential kind. `service` credentials mint service tokens. */
233
+ export type ApplicationCredentialType = 'public' | 'confidential' | 'service';
234
+ /** Deployment environment an application credential is scoped to. */
235
+ export type ApplicationEnvironment = 'development' | 'staging' | 'production';
236
+ /** Application credential lifecycle status. */
237
+ export type ApplicationCredentialStatus = 'active' | 'deprecated' | 'revoked';
238
+ /**
239
+ * Client-facing Application shape returned by the `/applications` API. An
240
+ * application is the OAuth client; it is OWNED by an account
241
+ * (`ownerAccountId`), and the caller's access derives from their `AccountMember`
242
+ * on that owning account (with inheritance).
243
+ */
244
+ export interface Application {
245
+ _id: string;
246
+ name: string;
247
+ description?: string;
248
+ websiteUrl?: string;
249
+ icon?: string;
250
+ type: ApplicationType;
251
+ status: ApplicationStatus;
252
+ isOfficial: boolean;
253
+ isInternal: boolean;
254
+ capabilities: string[];
255
+ redirectUris: string[];
256
+ scopes: string[];
257
+ webhookUrl?: string;
258
+ devWebhookUrl?: string;
259
+ createdByUserId: string;
260
+ /**
261
+ * The account that owns this application (account `_id`). Access to the
262
+ * application derives from the caller's `AccountMember` on this account, with
263
+ * inheritance up the account tree.
264
+ */
265
+ ownerAccountId: string;
266
+ createdAt: string;
267
+ updatedAt: string;
268
+ /**
269
+ * The caller's effective membership in the OWNING account (direct or
270
+ * inherited), embedded by the API on list/detail responses, or `null` when the
271
+ * caller has no membership. Use `callerMembership.permissions` to gate UI.
272
+ */
273
+ callerMembership?: AccountMember | null;
274
+ }
275
+ /**
276
+ * Client-facing ApplicationCredential shape (an application's OAuth client
277
+ * credentials). The raw secret is NEVER part of this shape — it is returned
278
+ * exactly once, separately, at creation/rotation.
279
+ */
280
+ export interface ApplicationCredential {
281
+ _id: string;
282
+ applicationId: string;
283
+ name: string;
284
+ publicKey: string;
285
+ type: ApplicationCredentialType;
286
+ environment: ApplicationEnvironment;
287
+ scopes: string[];
288
+ status: ApplicationCredentialStatus;
289
+ lastUsedAt?: string;
290
+ expiresAt?: string;
291
+ /**
292
+ * Audit link to the credential this one was rotated FROM. Populated on
293
+ * credentials created via rotation; absent on original credentials.
294
+ */
295
+ rotatedFromCredentialId?: string;
296
+ createdByUserId: string;
297
+ createdAt: string;
298
+ updatedAt: string;
299
+ }
300
+ /** Input accepted by `createApp`. Staff-only fields are not settable here. */
301
+ export interface CreateApplicationInput {
302
+ name: string;
303
+ description?: string;
304
+ websiteUrl?: string;
305
+ icon?: string;
306
+ redirectUris?: string[];
307
+ scopes?: string[];
308
+ /**
309
+ * Owning account `_id`. Omitted → the API defaults to the caller's personal
310
+ * account.
311
+ */
312
+ ownerAccountId?: string;
313
+ }
314
+ /** Input accepted by `updateApp`. Staff-only fields are not settable here. */
315
+ export interface UpdateApplicationInput {
316
+ name?: string;
317
+ description?: string;
318
+ websiteUrl?: string;
319
+ icon?: string;
320
+ redirectUris?: string[];
321
+ scopes?: string[];
322
+ webhookUrl?: string;
323
+ devWebhookUrl?: string;
324
+ status?: ApplicationStatus;
325
+ }
326
+ /** Input accepted by `createAppCredential`. */
327
+ export interface CreateApplicationCredentialInput {
328
+ name: string;
329
+ type: ApplicationCredentialType;
330
+ environment: ApplicationEnvironment;
331
+ scopes?: string[];
332
+ }
333
+ /** Result of creating an application credential — `secret` is returned ONCE. */
334
+ export interface ApplicationCredentialWithSecret {
335
+ credential: ApplicationCredential;
336
+ secret: string;
337
+ }
338
+ /**
339
+ * Result of rotating an application credential. Extends the create result with
340
+ * audit fields: the new plaintext `secret` is returned ONCE, plus `rotatedFrom`
341
+ * (the previous credential's `credentialId`) and `graceExpiresAt` (ISO string
342
+ * marking when the old credential stops being honoured during the grace window).
343
+ */
344
+ export interface RotateApplicationCredentialResult extends ApplicationCredentialWithSecret {
345
+ /** The previous credential's `credentialId` that this rotation supersedes. */
346
+ rotatedFrom: string;
347
+ /** ISO timestamp at which the rotated-from credential's grace window ends. */
348
+ graceExpiresAt: string;
349
+ }
350
+ /** Time window for application usage statistics. */
351
+ export type ApplicationUsagePeriod = '24h' | '7d' | '30d' | '90d';
352
+ /** Aggregate totals for an application over the requested period. */
353
+ export interface ApplicationUsageSummary {
354
+ totalRequests: number;
355
+ totalTokens: number;
356
+ totalCredits: number;
357
+ avgResponseTime: number;
358
+ successfulRequests: number;
359
+ errorRequests: number;
360
+ }
361
+ /** Per-day usage bucket. `_id` is the day key (e.g. `YYYY-MM-DD`). */
362
+ export interface ApplicationUsageByDay {
363
+ _id: string;
364
+ requests: number;
365
+ tokens: number;
366
+ credits: number;
367
+ }
368
+ /** Per-endpoint usage bucket. `_id` is the endpoint identifier. */
369
+ export interface ApplicationUsageByEndpoint {
370
+ _id: string;
371
+ requests: number;
372
+ tokens: number;
373
+ }
374
+ /** Usage statistics for an application over a period. */
375
+ export interface ApplicationUsageStats {
376
+ summary: ApplicationUsageSummary;
377
+ byDay: ApplicationUsageByDay[];
378
+ byEndpoint: ApplicationUsageByEndpoint[];
379
+ }
380
+ /** Result of an archive/remove/revoke/transfer/delete operation. */
381
+ export interface AccountSuccessResult {
382
+ success: boolean;
383
+ }
384
+ export declare function OxyServicesAccountsMixin<T extends typeof OxyServicesBase>(Base: T): {
385
+ new (...args: any[]): {
386
+ /**
387
+ * List the accounts the caller can access: their own personal (root)
388
+ * account, accounts they own, and accounts shared with them (including
389
+ * external organisations), plus the reachable subtree of each.
390
+ *
391
+ * @param opts - `{ tree: true }` requests the nested tree representation
392
+ * (`children` populated) instead of a flat list. The flag is appended to
393
+ * the path as `?tree=true`, so the response cache keys on it automatically —
394
+ * the flat and tree variants never collide.
395
+ */
396
+ listAccounts(opts?: ListAccountsOptions): Promise<AccountNode[]>;
397
+ /**
398
+ * Fetch a single account node by id.
399
+ * @param accountId - The account's Mongo `_id`.
400
+ */
401
+ getAccount(accountId: string): Promise<AccountNode>;
402
+ /**
403
+ * Create a new (non-personal) account. The caller becomes its `owner`.
404
+ * @param data - Account configuration: kind, optional parent, and profile.
405
+ */
406
+ createAccount(data: CreateAccountInput): Promise<AccountNode>;
407
+ /**
408
+ * Update an account's mutable profile fields. Tree placement changes
409
+ * (reparenting) go through the dedicated move endpoint, not here.
410
+ * @param accountId - The account's Mongo `_id`.
411
+ * @param data - Subset of updatable profile fields.
412
+ */
413
+ updateAccount(accountId: string, data: UpdateAccountInput): Promise<AccountNode>;
414
+ /**
415
+ * Archive an account (soft delete). Named `archiveAccount` — NOT
416
+ * `deleteAccount`, which is reserved for the GDPR self-deletion flow on the
417
+ * user mixin (`OxyServices.user.ts`).
418
+ * @param accountId - The account's Mongo `_id`.
419
+ */
420
+ archiveAccount(accountId: string): Promise<AccountSuccessResult>;
421
+ /**
422
+ * List the direct child accounts of an account.
423
+ * @param accountId - The parent account's Mongo `_id`.
424
+ */
425
+ listChildAccounts(accountId: string): Promise<AccountNode[]>;
426
+ /**
427
+ * List members of an account (direct membership rows on the account).
428
+ * @param accountId - The account's Mongo `_id`.
429
+ */
430
+ listAccountMembers(accountId: string): Promise<AccountMember[]>;
431
+ /**
432
+ * Add a member to an account.
433
+ * @param accountId - The account's Mongo `_id`.
434
+ * @param data - Target user's username or email and role (never `owner`).
435
+ * The server resolves `usernameOrEmail` to a personal account; an unknown
436
+ * value yields a 404 "User not found".
437
+ */
438
+ inviteAccountMember(accountId: string, data: InviteAccountMemberInput): Promise<AccountMember>;
439
+ /**
440
+ * Change a member's role.
441
+ * @param accountId - The account's Mongo `_id`.
442
+ * @param memberId - The member's Mongo `_id`.
443
+ * @param data - New role (never `owner`).
444
+ */
445
+ updateAccountMember(accountId: string, memberId: string, data: UpdateAccountMemberInput): Promise<AccountMember>;
446
+ /**
447
+ * Remove a member from an account.
448
+ * @param accountId - The account's Mongo `_id`.
449
+ * @param memberId - The member's Mongo `_id`.
450
+ */
451
+ removeAccountMember(accountId: string, memberId: string): Promise<AccountSuccessResult>;
452
+ /**
453
+ * Transfer ownership of an account to another member (owner only).
454
+ * @param accountId - The account's Mongo `_id`.
455
+ * @param data - Target user id.
456
+ */
457
+ transferAccountOwnership(accountId: string, data: TransferAccountOwnershipInput): Promise<AccountSuccessResult>;
458
+ /**
459
+ * List a bot account's service credentials. The response NEVER includes
460
+ * secrets.
461
+ * @param accountId - The account's Mongo `_id`.
462
+ */
463
+ listAccountCredentials(accountId: string): Promise<AccountCredential[]>;
464
+ /**
465
+ * Create a service credential for a bot account. The plaintext `secret` is
466
+ * returned exactly ONCE; the server stores only a hash and will never return
467
+ * it again.
468
+ * @param accountId - The account's Mongo `_id`.
469
+ * @param data - Credential configuration (`type` is always `service`).
470
+ */
471
+ createAccountCredential(accountId: string, data: CreateAccountCredentialInput): Promise<AccountCredentialWithSecret>;
472
+ /**
473
+ * Rotate a bot credential's secret. The new plaintext `secret` is returned
474
+ * exactly ONCE, along with audit fields: `rotatedFrom` (the previous
475
+ * credentialId) and `graceExpiresAt` (ISO string for the grace window during
476
+ * which the old credential is still honoured).
477
+ * @param accountId - The account's Mongo `_id`.
478
+ * @param credentialId - The credential's Mongo `_id`.
479
+ */
480
+ rotateAccountCredential(accountId: string, credentialId: string): Promise<RotateAccountCredentialResult>;
481
+ /**
482
+ * Revoke a bot credential (`status='revoked'`). Revoked credentials can no
483
+ * longer authenticate.
484
+ * @param accountId - The account's Mongo `_id`.
485
+ * @param credentialId - The credential's Mongo `_id`.
486
+ */
487
+ revokeAccountCredential(accountId: string, credentialId: string): Promise<AccountSuccessResult>;
488
+ /**
489
+ * List the applications owned by an account. Backed by
490
+ * `GET /applications?ownerAccountId=<id>`.
491
+ * @param accountId - The owning account's Mongo `_id`.
492
+ */
493
+ listAccountApps(accountId: string): Promise<Application[]>;
494
+ /**
495
+ * Create a new application owned by an account.
496
+ * @param data - Application configuration. `ownerAccountId` defaults to the
497
+ * caller's personal account when omitted. Staff-only fields are ignored.
498
+ */
499
+ createApp(data: CreateApplicationInput): Promise<Application>;
500
+ /**
501
+ * Fetch a single application by id.
502
+ * @param applicationId - The application's Mongo `_id`.
503
+ */
504
+ getApp(applicationId: string): Promise<Application>;
505
+ /**
506
+ * Update an application's mutable fields.
507
+ * @param applicationId - The application's Mongo `_id`.
508
+ * @param data - Subset of updatable fields. Staff-only fields are ignored.
509
+ */
510
+ updateApp(applicationId: string, data: UpdateApplicationInput): Promise<Application>;
511
+ /**
512
+ * Soft-delete an application.
513
+ * @param applicationId - The application's Mongo `_id`.
514
+ */
515
+ deleteApp(applicationId: string): Promise<AccountSuccessResult>;
516
+ /**
517
+ * List an application's OAuth credentials. The response NEVER includes
518
+ * secrets.
519
+ * @param applicationId - The application's Mongo `_id`.
520
+ */
521
+ listAppCredentials(applicationId: string): Promise<ApplicationCredential[]>;
522
+ /**
523
+ * Create an application credential. The plaintext `secret` is returned
524
+ * exactly ONCE; the server stores only a hash and will never return it again.
525
+ * @param applicationId - The application's Mongo `_id`.
526
+ * @param data - Credential configuration.
527
+ */
528
+ createAppCredential(applicationId: string, data: CreateApplicationCredentialInput): Promise<ApplicationCredentialWithSecret>;
529
+ /**
530
+ * Rotate an application credential's secret. The new plaintext `secret` is
531
+ * returned exactly ONCE, along with audit fields: `rotatedFrom` (the previous
532
+ * credentialId) and `graceExpiresAt` (ISO string for the grace window during
533
+ * which the old credential is still honoured).
534
+ * @param applicationId - The application's Mongo `_id`.
535
+ * @param credentialId - The credential's Mongo `_id`.
536
+ */
537
+ rotateAppCredential(applicationId: string, credentialId: string): Promise<RotateApplicationCredentialResult>;
538
+ /**
539
+ * Revoke an application credential (`status='revoked'`). Revoked credentials
540
+ * can no longer authenticate.
541
+ * @param applicationId - The application's Mongo `_id`.
542
+ * @param credentialId - The credential's Mongo `_id`.
543
+ */
544
+ revokeAppCredential(applicationId: string, credentialId: string): Promise<AccountSuccessResult>;
545
+ /**
546
+ * Fetch usage statistics for an application.
547
+ * @param applicationId - The application's Mongo `_id`.
548
+ * @param period - Time window (defaults to the server default).
549
+ */
550
+ getAppUsage(applicationId: string, period?: ApplicationUsagePeriod): Promise<ApplicationUsageStats>;
551
+ /**
552
+ * Bust every cached account list. `listAccounts({tree?})` keys the flat list
553
+ * as `GET:/accounts` and the tree variant as `GET:/accounts?tree=true` (the
554
+ * query string is part of the URL path). A change to the accessible forest
555
+ * (create/archive/ownership transfer) invalidates both, so we clear the
556
+ * unscoped entry plus every `?`-query variant via a prefix sweep. The prefix
557
+ * `GET:/accounts?` matches only the query-string list variants, never the
558
+ * `GET:/accounts/<id>…` detail/sub-resource keys.
559
+ *
560
+ * Internal helper (leading underscore); not part of the supported public
561
+ * surface. Public rather than `private` because mixins compose into an
562
+ * exported anonymous class, where TypeScript cannot represent a private
563
+ * member in the emitted declaration file (TS4094).
564
+ */
565
+ _invalidateAccountLists(): void;
566
+ /**
567
+ * Bust the cached member list and detail for an account after a membership
568
+ * mutation. The member list (`listAccountMembers`) and the detail
569
+ * (`getAccount`, which can embed the caller's membership) both go stale when
570
+ * the member set or a member's role changes.
571
+ *
572
+ * Internal helper (leading underscore); see `_invalidateAccountLists` for why
573
+ * this is public rather than `private`.
574
+ */
575
+ _invalidateAccountMembership(accountId: string): void;
576
+ /**
577
+ * Bust every cached application list. `listAccountApps(accountId)` keys each
578
+ * owner-scoped list as `GET:/applications?ownerAccountId=<id>` (the query
579
+ * string is part of the URL path). A change to any list (create/delete)
580
+ * invalidates them all, so we clear the unscoped entry plus every `?`-query
581
+ * variant via a prefix sweep. The prefix `GET:/applications?` matches only the
582
+ * query-string list variants, never the `GET:/applications/<id>…`
583
+ * detail/sub-resource keys.
584
+ *
585
+ * Internal helper (leading underscore); see `_invalidateAccountLists` for why
586
+ * this is public rather than `private`.
587
+ */
588
+ _invalidateAppLists(): void;
589
+ httpService: import("../HttpService").HttpService;
590
+ cloudURL: string;
591
+ config: import("../OxyServices.base").OxyConfig;
592
+ __resetTokensForTests(): void;
593
+ makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
594
+ getBaseURL(): string;
595
+ getSessionBaseUrl(): string;
596
+ getClient(): import("../HttpService").HttpService;
597
+ createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
598
+ getMetrics(): {
599
+ totalRequests: number;
600
+ successfulRequests: number;
601
+ failedRequests: number;
602
+ cacheHits: number;
603
+ cacheMisses: number;
604
+ averageResponseTime: number;
605
+ };
606
+ clearCache(): void;
607
+ clearCacheEntry(key: string): void;
608
+ clearCacheByPrefix(prefix: string): number;
609
+ getCacheStats(): {
610
+ size: number;
611
+ hits: number;
612
+ misses: number;
613
+ hitRate: number;
614
+ };
615
+ getCloudURL(): string;
616
+ setTokens(accessToken: string): void;
617
+ clearTokens(): void;
618
+ onTokensChanged(listener: (accessToken: string | null) => void): () => void;
619
+ _cachedUserId: string | null | undefined;
620
+ _cachedAccessToken: string | null;
621
+ getCurrentUserId(): string | null;
622
+ hasValidToken(): boolean;
623
+ getAccessToken(): string | null;
624
+ getAccessTokenExpiry(): number | null;
625
+ setActingAs(userId: string | null): void;
626
+ getActingAs(): string | null;
627
+ waitForAuth(timeoutMs?: number): Promise<boolean>;
628
+ withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
629
+ maxRetries?: number;
630
+ retryDelay?: number;
631
+ authTimeoutMs?: number;
632
+ }): Promise<T_1>;
633
+ validate(): Promise<boolean>;
634
+ handleError(error: unknown): Error;
635
+ healthCheck(): Promise<{
636
+ status: string;
637
+ users?: number;
638
+ timestamp?: string;
639
+ [key: string]: any;
640
+ }>;
641
+ };
642
+ } & T;