@oxy.so/core 4.6.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/OxyServices.js +12 -0
- package/dist/cjs/api/organizations.js +94 -0
- package/dist/cjs/api/safety.js +26 -0
- package/dist/cjs/i18n/locales/en-US.js +61 -0
- package/dist/cjs/i18n/locales/es-ES.js +61 -0
- package/dist/esm/OxyServices.js +12 -0
- package/dist/esm/api/organizations.js +90 -0
- package/dist/esm/api/safety.js +22 -0
- package/dist/esm/i18n/locales/en-US.js +61 -0
- package/dist/esm/i18n/locales/es-ES.js +61 -0
- package/dist/types/OxyServices.d.ts +6 -0
- package/dist/types/api/accounts.d.ts +3 -0
- package/dist/types/api/organizations.d.ts +246 -0
- package/dist/types/api/safety.d.ts +14 -0
- package/dist/types/i18n/locales/en-US.d.ts +61 -0
- package/dist/types/i18n/locales/es-ES.d.ts +61 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/server/requesterAssertion.d.ts +2 -2
- package/package.json +3 -3
- package/src/OxyServices.ts +14 -0
- package/src/api/accounts.ts +3 -0
- package/src/api/organizations.ts +180 -0
- package/src/api/safety.ts +33 -0
- package/src/i18n/locales/en-US.ts +68 -0
- package/src/i18n/locales/es-ES.ts +68 -0
- package/src/index.ts +11 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { type OrganizationCuration, type OrganizationImportBatch, type OrganizationClaimListQuery, type CreateOrganization, type OrganizationSearch, type UpdateOrganization, type OrganizationClaimInput, type OrganizationClaimReview, type OrganizationExternalInput, type OrganizationMerge } from '@oxy.so/contracts';
|
|
2
|
+
import type { OxyContext } from '../client/context';
|
|
3
|
+
/** The public canonical organization directory. Claiming changes authority, never identity. */
|
|
4
|
+
export declare class OrganizationsApi {
|
|
5
|
+
private readonly ctx;
|
|
6
|
+
constructor(ctx: OxyContext);
|
|
7
|
+
search(input: OrganizationSearch): Promise<{
|
|
8
|
+
items: {
|
|
9
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
10
|
+
name: string;
|
|
11
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
12
|
+
legalName: string | null;
|
|
13
|
+
websiteUrl: string | null;
|
|
14
|
+
countryCode: string | null;
|
|
15
|
+
aliases: {
|
|
16
|
+
alias: string;
|
|
17
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
18
|
+
language?: string | undefined;
|
|
19
|
+
}[];
|
|
20
|
+
accountId: string;
|
|
21
|
+
username: string | null;
|
|
22
|
+
avatar: string | null;
|
|
23
|
+
verifiedDomains: string[];
|
|
24
|
+
claimStatus: "unclaimed" | "claimed";
|
|
25
|
+
mergedIntoAccountId: string | null;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
}[];
|
|
29
|
+
nextCursor: string | null;
|
|
30
|
+
}>;
|
|
31
|
+
get(accountId: string): Promise<{
|
|
32
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
33
|
+
name: string;
|
|
34
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
35
|
+
legalName: string | null;
|
|
36
|
+
websiteUrl: string | null;
|
|
37
|
+
countryCode: string | null;
|
|
38
|
+
aliases: {
|
|
39
|
+
alias: string;
|
|
40
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
41
|
+
language?: string | undefined;
|
|
42
|
+
}[];
|
|
43
|
+
accountId: string;
|
|
44
|
+
username: string | null;
|
|
45
|
+
avatar: string | null;
|
|
46
|
+
verifiedDomains: string[];
|
|
47
|
+
claimStatus: "unclaimed" | "claimed";
|
|
48
|
+
mergedIntoAccountId: string | null;
|
|
49
|
+
createdAt: string;
|
|
50
|
+
updatedAt: string;
|
|
51
|
+
}>;
|
|
52
|
+
batch(input: {
|
|
53
|
+
ids: string[];
|
|
54
|
+
}): Promise<{
|
|
55
|
+
items: {
|
|
56
|
+
requestedAccountId: string;
|
|
57
|
+
organization: {
|
|
58
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
59
|
+
name: string;
|
|
60
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
61
|
+
legalName: string | null;
|
|
62
|
+
websiteUrl: string | null;
|
|
63
|
+
countryCode: string | null;
|
|
64
|
+
aliases: {
|
|
65
|
+
alias: string;
|
|
66
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
67
|
+
language?: string | undefined;
|
|
68
|
+
}[];
|
|
69
|
+
accountId: string;
|
|
70
|
+
username: string | null;
|
|
71
|
+
avatar: string | null;
|
|
72
|
+
verifiedDomains: string[];
|
|
73
|
+
claimStatus: "unclaimed" | "claimed";
|
|
74
|
+
mergedIntoAccountId: string | null;
|
|
75
|
+
createdAt: string;
|
|
76
|
+
updatedAt: string;
|
|
77
|
+
};
|
|
78
|
+
}[];
|
|
79
|
+
missingIds: string[];
|
|
80
|
+
}>;
|
|
81
|
+
create(input: CreateOrganization): Promise<{
|
|
82
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
83
|
+
name: string;
|
|
84
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
85
|
+
legalName: string | null;
|
|
86
|
+
websiteUrl: string | null;
|
|
87
|
+
countryCode: string | null;
|
|
88
|
+
aliases: {
|
|
89
|
+
alias: string;
|
|
90
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
91
|
+
language?: string | undefined;
|
|
92
|
+
}[];
|
|
93
|
+
accountId: string;
|
|
94
|
+
username: string | null;
|
|
95
|
+
avatar: string | null;
|
|
96
|
+
verifiedDomains: string[];
|
|
97
|
+
claimStatus: "unclaimed" | "claimed";
|
|
98
|
+
mergedIntoAccountId: string | null;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
updatedAt: string;
|
|
101
|
+
}>;
|
|
102
|
+
update(accountId: string, input: UpdateOrganization): Promise<{
|
|
103
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
104
|
+
name: string;
|
|
105
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
106
|
+
legalName: string | null;
|
|
107
|
+
websiteUrl: string | null;
|
|
108
|
+
countryCode: string | null;
|
|
109
|
+
aliases: {
|
|
110
|
+
alias: string;
|
|
111
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
112
|
+
language?: string | undefined;
|
|
113
|
+
}[];
|
|
114
|
+
accountId: string;
|
|
115
|
+
username: string | null;
|
|
116
|
+
avatar: string | null;
|
|
117
|
+
verifiedDomains: string[];
|
|
118
|
+
claimStatus: "unclaimed" | "claimed";
|
|
119
|
+
mergedIntoAccountId: string | null;
|
|
120
|
+
createdAt: string;
|
|
121
|
+
updatedAt: string;
|
|
122
|
+
}>;
|
|
123
|
+
claim(accountId: string, input: OrganizationClaimInput): Promise<{
|
|
124
|
+
status: "pending" | "approved" | "rejected";
|
|
125
|
+
accountId: string;
|
|
126
|
+
createdAt: string;
|
|
127
|
+
id: string;
|
|
128
|
+
claimantUserId: string;
|
|
129
|
+
}>;
|
|
130
|
+
myClaims(input?: OrganizationClaimListQuery): Promise<{
|
|
131
|
+
items: {
|
|
132
|
+
status: "pending" | "approved" | "rejected";
|
|
133
|
+
accountId: string;
|
|
134
|
+
createdAt: string;
|
|
135
|
+
evidenceReference: string;
|
|
136
|
+
id: string;
|
|
137
|
+
claimantUserId: string;
|
|
138
|
+
reviewEvidenceReference: string | null;
|
|
139
|
+
reviewedAt: string | null;
|
|
140
|
+
}[];
|
|
141
|
+
nextCursor: string | null;
|
|
142
|
+
}>;
|
|
143
|
+
myClaim(claimId: string): Promise<{
|
|
144
|
+
status: "pending" | "approved" | "rejected";
|
|
145
|
+
accountId: string;
|
|
146
|
+
createdAt: string;
|
|
147
|
+
evidenceReference: string;
|
|
148
|
+
id: string;
|
|
149
|
+
claimantUserId: string;
|
|
150
|
+
reviewEvidenceReference: string | null;
|
|
151
|
+
reviewedAt: string | null;
|
|
152
|
+
}>;
|
|
153
|
+
reviewClaims(input?: OrganizationClaimListQuery): Promise<{
|
|
154
|
+
items: {
|
|
155
|
+
status: "pending" | "approved" | "rejected";
|
|
156
|
+
accountId: string;
|
|
157
|
+
createdAt: string;
|
|
158
|
+
evidenceReference: string;
|
|
159
|
+
id: string;
|
|
160
|
+
claimantUserId: string;
|
|
161
|
+
reviewEvidenceReference: string | null;
|
|
162
|
+
reviewedAt: string | null;
|
|
163
|
+
}[];
|
|
164
|
+
nextCursor: string | null;
|
|
165
|
+
}>;
|
|
166
|
+
reviewClaimDetail(claimId: string): Promise<{
|
|
167
|
+
status: "pending" | "approved" | "rejected";
|
|
168
|
+
accountId: string;
|
|
169
|
+
createdAt: string;
|
|
170
|
+
evidenceReference: string;
|
|
171
|
+
id: string;
|
|
172
|
+
claimantUserId: string;
|
|
173
|
+
reviewEvidenceReference: string | null;
|
|
174
|
+
reviewedAt: string | null;
|
|
175
|
+
}>;
|
|
176
|
+
reviewClaim(claimId: string, input: OrganizationClaimReview): Promise<{
|
|
177
|
+
status: "pending" | "approved" | "rejected";
|
|
178
|
+
accountId: string;
|
|
179
|
+
createdAt: string;
|
|
180
|
+
id: string;
|
|
181
|
+
claimantUserId: string;
|
|
182
|
+
}>;
|
|
183
|
+
importBatch(input: OrganizationImportBatch): Promise<{
|
|
184
|
+
items: {
|
|
185
|
+
accountId: string;
|
|
186
|
+
externalId: string;
|
|
187
|
+
created: boolean;
|
|
188
|
+
}[];
|
|
189
|
+
}>;
|
|
190
|
+
importExternal(input: OrganizationExternalInput): Promise<{
|
|
191
|
+
accountId: string;
|
|
192
|
+
created: boolean;
|
|
193
|
+
}>;
|
|
194
|
+
resolveExternal(input: {
|
|
195
|
+
namespace: string;
|
|
196
|
+
externalId: string;
|
|
197
|
+
}): Promise<{
|
|
198
|
+
accountId: string;
|
|
199
|
+
}>;
|
|
200
|
+
curate(accountId: string, input: OrganizationCuration): Promise<{
|
|
201
|
+
status: "active" | "inactive" | "suppressed";
|
|
202
|
+
accountId: string;
|
|
203
|
+
}>;
|
|
204
|
+
merge(accountId: string, input: OrganizationMerge): Promise<{
|
|
205
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
206
|
+
name: string;
|
|
207
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
208
|
+
legalName: string | null;
|
|
209
|
+
websiteUrl: string | null;
|
|
210
|
+
countryCode: string | null;
|
|
211
|
+
aliases: {
|
|
212
|
+
alias: string;
|
|
213
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
214
|
+
language?: string | undefined;
|
|
215
|
+
}[];
|
|
216
|
+
accountId: string;
|
|
217
|
+
username: string | null;
|
|
218
|
+
avatar: string | null;
|
|
219
|
+
verifiedDomains: string[];
|
|
220
|
+
claimStatus: "unclaimed" | "claimed";
|
|
221
|
+
mergedIntoAccountId: string | null;
|
|
222
|
+
createdAt: string;
|
|
223
|
+
updatedAt: string;
|
|
224
|
+
}>;
|
|
225
|
+
iterate(input: OrganizationSearch): AsyncGenerator<{
|
|
226
|
+
status: "active" | "inactive" | "merged" | "suppressed";
|
|
227
|
+
name: string;
|
|
228
|
+
organizationType: "business" | "nonprofit" | "public_body" | "community" | "other";
|
|
229
|
+
legalName: string | null;
|
|
230
|
+
websiteUrl: string | null;
|
|
231
|
+
countryCode: string | null;
|
|
232
|
+
aliases: {
|
|
233
|
+
alias: string;
|
|
234
|
+
kind: "name_variant" | "former_name" | "localized_name" | "marketing_name" | "misspelling";
|
|
235
|
+
language?: string | undefined;
|
|
236
|
+
}[];
|
|
237
|
+
accountId: string;
|
|
238
|
+
username: string | null;
|
|
239
|
+
avatar: string | null;
|
|
240
|
+
verifiedDomains: string[];
|
|
241
|
+
claimStatus: "unclaimed" | "claimed";
|
|
242
|
+
mergedIntoAccountId: string | null;
|
|
243
|
+
createdAt: string;
|
|
244
|
+
updatedAt: string;
|
|
245
|
+
}, void, unknown>;
|
|
246
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ProfileAccessInput } from '@oxy.so/contracts';
|
|
2
|
+
import type { OxyContext } from '../client/context';
|
|
3
|
+
export declare class SafetyApi {
|
|
4
|
+
private readonly ctx;
|
|
5
|
+
constructor(ctx: OxyContext);
|
|
6
|
+
/** Server callers must explicitly supply the incoming user bearer or null for anonymous access. */
|
|
7
|
+
profileAccess(input: ProfileAccessInput, options?: {
|
|
8
|
+
accessToken: string | null;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
reason: "public" | "owner" | "private" | "blocked" | "unavailable";
|
|
12
|
+
policyVersion: "1";
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
@@ -1,4 +1,65 @@
|
|
|
1
1
|
declare const dict: {
|
|
2
|
+
organizationDirectory: {
|
|
3
|
+
invalidName: string;
|
|
4
|
+
review: {
|
|
5
|
+
title: string;
|
|
6
|
+
forbidden: string;
|
|
7
|
+
empty: string;
|
|
8
|
+
hint: string;
|
|
9
|
+
independent: string;
|
|
10
|
+
evidence: string;
|
|
11
|
+
approved: string;
|
|
12
|
+
rejected: string;
|
|
13
|
+
conflict: string;
|
|
14
|
+
failed: string;
|
|
15
|
+
};
|
|
16
|
+
title: string;
|
|
17
|
+
search: string;
|
|
18
|
+
searchHint: string;
|
|
19
|
+
empty: string;
|
|
20
|
+
retry: string;
|
|
21
|
+
loadMore: string;
|
|
22
|
+
failed: string;
|
|
23
|
+
unclaimed: string;
|
|
24
|
+
claimed: string;
|
|
25
|
+
inactive: string;
|
|
26
|
+
newAccount: string;
|
|
27
|
+
newAccountHint: string;
|
|
28
|
+
addDirectory: string;
|
|
29
|
+
directoryHint: string;
|
|
30
|
+
added: string;
|
|
31
|
+
back: string;
|
|
32
|
+
type: string;
|
|
33
|
+
types: {
|
|
34
|
+
business: string;
|
|
35
|
+
nonprofit: string;
|
|
36
|
+
public_body: string;
|
|
37
|
+
community: string;
|
|
38
|
+
other: string;
|
|
39
|
+
};
|
|
40
|
+
name: string;
|
|
41
|
+
legalName: string;
|
|
42
|
+
website: string;
|
|
43
|
+
country: string;
|
|
44
|
+
save: string;
|
|
45
|
+
saved: string;
|
|
46
|
+
invalid: string;
|
|
47
|
+
saveFailed: string;
|
|
48
|
+
claim: string;
|
|
49
|
+
claimHint: string;
|
|
50
|
+
evidence: string;
|
|
51
|
+
evidenceHint: string;
|
|
52
|
+
claimSent: string;
|
|
53
|
+
claimFailed: string;
|
|
54
|
+
claimedHint: string;
|
|
55
|
+
requests: string;
|
|
56
|
+
pending: string;
|
|
57
|
+
approved: string;
|
|
58
|
+
rejected: string;
|
|
59
|
+
requestError: string;
|
|
60
|
+
view: string;
|
|
61
|
+
readonly: string;
|
|
62
|
+
};
|
|
2
63
|
signin: {
|
|
3
64
|
title: string;
|
|
4
65
|
subtitle: string;
|
|
@@ -1,4 +1,65 @@
|
|
|
1
1
|
declare const dict: {
|
|
2
|
+
organizationDirectory: {
|
|
3
|
+
invalidName: string;
|
|
4
|
+
review: {
|
|
5
|
+
title: string;
|
|
6
|
+
forbidden: string;
|
|
7
|
+
empty: string;
|
|
8
|
+
hint: string;
|
|
9
|
+
independent: string;
|
|
10
|
+
evidence: string;
|
|
11
|
+
approved: string;
|
|
12
|
+
rejected: string;
|
|
13
|
+
conflict: string;
|
|
14
|
+
failed: string;
|
|
15
|
+
};
|
|
16
|
+
title: string;
|
|
17
|
+
search: string;
|
|
18
|
+
searchHint: string;
|
|
19
|
+
empty: string;
|
|
20
|
+
retry: string;
|
|
21
|
+
loadMore: string;
|
|
22
|
+
failed: string;
|
|
23
|
+
unclaimed: string;
|
|
24
|
+
claimed: string;
|
|
25
|
+
inactive: string;
|
|
26
|
+
newAccount: string;
|
|
27
|
+
newAccountHint: string;
|
|
28
|
+
addDirectory: string;
|
|
29
|
+
directoryHint: string;
|
|
30
|
+
added: string;
|
|
31
|
+
back: string;
|
|
32
|
+
type: string;
|
|
33
|
+
types: {
|
|
34
|
+
business: string;
|
|
35
|
+
nonprofit: string;
|
|
36
|
+
public_body: string;
|
|
37
|
+
community: string;
|
|
38
|
+
other: string;
|
|
39
|
+
};
|
|
40
|
+
name: string;
|
|
41
|
+
legalName: string;
|
|
42
|
+
website: string;
|
|
43
|
+
country: string;
|
|
44
|
+
save: string;
|
|
45
|
+
saved: string;
|
|
46
|
+
invalid: string;
|
|
47
|
+
saveFailed: string;
|
|
48
|
+
claim: string;
|
|
49
|
+
claimHint: string;
|
|
50
|
+
evidence: string;
|
|
51
|
+
evidenceHint: string;
|
|
52
|
+
claimSent: string;
|
|
53
|
+
claimFailed: string;
|
|
54
|
+
claimedHint: string;
|
|
55
|
+
requests: string;
|
|
56
|
+
pending: string;
|
|
57
|
+
approved: string;
|
|
58
|
+
rejected: string;
|
|
59
|
+
requestError: string;
|
|
60
|
+
view: string;
|
|
61
|
+
readonly: string;
|
|
62
|
+
};
|
|
2
63
|
signin: {
|
|
3
64
|
title: string;
|
|
4
65
|
subtitle: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -99,3 +99,5 @@ export { AUTH_WEB_ORIGIN, CENTRAL_IDP_APEX } from './utils/authWebUrl';
|
|
|
99
99
|
export { buildOAuthAuthorizeUrl, computeCodeChallenge, generateOAuthState, generatePkcePair, DEFAULT_OAUTH_SCOPE, OXY_AUTHORIZE_URL, OXY_OAUTH_STATE_STORAGE_KEY, OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY, OXY_OAUTH_REDIRECT_URI_STORAGE_KEY, OXY_OAUTH_RETURN_PATH_STORAGE_KEY, normalizeOAuthRedirectUri, canonicalizeOAuthRedirectUri, persistOAuthHandshake, readOAuthHandshake, clearOAuthHandshake, persistOAuthReturnPath, consumeOAuthReturnPath, } from './utils/oauthPkce';
|
|
100
100
|
export type { PkcePair, BuildOAuthAuthorizeUrlParams, OxyAuthScreen } from './utils/oauthPkce';
|
|
101
101
|
export { packageInfo } from './constants/version';
|
|
102
|
+
export type { Organization, OrganizationType, CreateOrganization, UpdateOrganization, OrganizationSearch, OrganizationClaim, } from '@oxy.so/contracts';
|
|
103
|
+
export type { ProfileAccessInput, ProfileAccessDecision } from '@oxy.so/contracts';
|
|
@@ -36,8 +36,8 @@ export declare const oxyRequesterAssertionClaimsSchema: z.ZodObject<{
|
|
|
36
36
|
/** The one native agent this requester may reach with it. */
|
|
37
37
|
agentId: z.ZodString;
|
|
38
38
|
}, "strict", z.ZodTypeAny, {
|
|
39
|
-
exp: number;
|
|
40
39
|
sub: string;
|
|
40
|
+
exp: number;
|
|
41
41
|
aud: string;
|
|
42
42
|
iss: string;
|
|
43
43
|
jti: string;
|
|
@@ -46,8 +46,8 @@ export declare const oxyRequesterAssertionClaimsSchema: z.ZodObject<{
|
|
|
46
46
|
cid: string;
|
|
47
47
|
agentId: string;
|
|
48
48
|
}, {
|
|
49
|
-
exp: number;
|
|
50
49
|
sub: string;
|
|
50
|
+
exp: number;
|
|
51
51
|
aud: string;
|
|
52
52
|
iss: string;
|
|
53
53
|
jti: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxy.so/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.0",
|
|
4
4
|
"description": "OxyHQ SDK Foundation — API client, authentication, cryptographic identity, and shared utilities",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -176,11 +176,11 @@
|
|
|
176
176
|
}
|
|
177
177
|
},
|
|
178
178
|
"dependencies": {
|
|
179
|
-
"@oxy.so/telemetry": "^1.2.0",
|
|
180
179
|
"@noble/ciphers": "^1.3.0",
|
|
181
180
|
"@noble/hashes": "^1.8.0",
|
|
182
|
-
"@oxy.so/contracts": "4.
|
|
181
|
+
"@oxy.so/contracts": "4.14.0",
|
|
183
182
|
"@oxy.so/protocol": "^1.2.2",
|
|
183
|
+
"@oxy.so/telemetry": "^1.2.0",
|
|
184
184
|
"@scure/bip39": "^1.6.0",
|
|
185
185
|
"buffer": "^6.0.3",
|
|
186
186
|
"express-rate-limit": "^8.6.0",
|
package/src/OxyServices.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SafetyApi } from './api/safety';
|
|
1
2
|
/**
|
|
2
3
|
* `OxyServices` — the Oxy API client.
|
|
3
4
|
*
|
|
@@ -32,6 +33,7 @@ import { PrivacyApi } from './api/privacy';
|
|
|
32
33
|
import { NotificationsApi } from './api/notifications';
|
|
33
34
|
import { AssetsApi } from './api/assets';
|
|
34
35
|
import { IdentityApi } from './api/identity';
|
|
36
|
+
import { OrganizationsApi } from './api/organizations';
|
|
35
37
|
import { AccountsApi } from './api/accounts';
|
|
36
38
|
import { AppsApi } from './api/apps';
|
|
37
39
|
import { LinkedAccountsApi } from './api/linkedAccounts';
|
|
@@ -191,6 +193,8 @@ export class OxyServices {
|
|
|
191
193
|
private _assets?: AssetsApi;
|
|
192
194
|
private _identity?: IdentityApi;
|
|
193
195
|
private _accounts?: AccountsApi;
|
|
196
|
+
private _organizations?: OrganizationsApi;
|
|
197
|
+
private _safety?: SafetyApi;
|
|
194
198
|
private _apps?: AppsApi;
|
|
195
199
|
private _linkedAccounts?: LinkedAccountsApi;
|
|
196
200
|
private _agency?: AgencyApi;
|
|
@@ -245,6 +249,16 @@ export class OxyServices {
|
|
|
245
249
|
return this._identity;
|
|
246
250
|
}
|
|
247
251
|
/** The account graph: accounts and their members. */
|
|
252
|
+
get safety(): SafetyApi {
|
|
253
|
+
if (!this._safety) this._safety = new SafetyApi(this.context);
|
|
254
|
+
return this._safety;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
get organizations(): OrganizationsApi {
|
|
258
|
+
if (!this._organizations) this._organizations = new OrganizationsApi(this.context);
|
|
259
|
+
return this._organizations;
|
|
260
|
+
}
|
|
261
|
+
|
|
248
262
|
get accounts(): AccountsApi {
|
|
249
263
|
if (!this._accounts) this._accounts = new AccountsApi(this.context);
|
|
250
264
|
return this._accounts;
|
package/src/api/accounts.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OrganizationType } from '@oxy.so/contracts';
|
|
1
2
|
/**
|
|
2
3
|
* `oxy.accounts` — the unified account graph (`/accounts`).
|
|
3
4
|
*
|
|
@@ -236,6 +237,7 @@ export interface CreateAccountInput {
|
|
|
236
237
|
* keep working. At most `MAX_ACCOUNT_CATEGORIES`, no duplicates.
|
|
237
238
|
*/
|
|
238
239
|
accountCategories?: AccountCategoryId[];
|
|
240
|
+
organizationType?: OrganizationType;
|
|
239
241
|
/**
|
|
240
242
|
* Create the account already opted OUT of discovery — kept out of people
|
|
241
243
|
* search, the follow-graph lists, `/similar` and the recommendation pools,
|
|
@@ -301,6 +303,7 @@ export interface UpdateAccountInput {
|
|
|
301
303
|
* every other field here (`account:update`).
|
|
302
304
|
*/
|
|
303
305
|
character?: AvatarCharacter;
|
|
306
|
+
organizationType?: OrganizationType;
|
|
304
307
|
}
|
|
305
308
|
|
|
306
309
|
/** Input accepted by `accounts.members.invite`. The owner role cannot be invited. */
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import {
|
|
2
|
+
organizationSchema,
|
|
3
|
+
organizationListSchema,
|
|
4
|
+
organizationBatchSchema,
|
|
5
|
+
organizationClaimSchema,
|
|
6
|
+
organizationExternalSchema,
|
|
7
|
+
organizationExternalResolutionSchema,
|
|
8
|
+
organizationImportBatchResultSchema,
|
|
9
|
+
organizationCurationResultSchema,
|
|
10
|
+
type OrganizationCuration,
|
|
11
|
+
type OrganizationImportBatch,
|
|
12
|
+
organizationClaimListSchema,
|
|
13
|
+
organizationClaimDetailSchema,
|
|
14
|
+
type OrganizationClaimListQuery,
|
|
15
|
+
type CreateOrganization,
|
|
16
|
+
type OrganizationSearch,
|
|
17
|
+
type UpdateOrganization,
|
|
18
|
+
type OrganizationClaimInput,
|
|
19
|
+
type OrganizationClaimReview,
|
|
20
|
+
type OrganizationExternalInput,
|
|
21
|
+
type OrganizationMerge,
|
|
22
|
+
} from '@oxy.so/contracts';
|
|
23
|
+
import type { OxyContext } from '../client/context';
|
|
24
|
+
import { evictOxyIdentityCache } from '../utils/identityCacheSweep';
|
|
25
|
+
|
|
26
|
+
/** The public canonical organization directory. Claiming changes authority, never identity. */
|
|
27
|
+
export class OrganizationsApi {
|
|
28
|
+
constructor(private readonly ctx: OxyContext) {}
|
|
29
|
+
async search(input: OrganizationSearch) {
|
|
30
|
+
return organizationListSchema.parse(
|
|
31
|
+
await this.ctx.request('GET', '/organizations', input, { cache: false, skipAuth: true }),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
async get(accountId: string) {
|
|
35
|
+
return organizationSchema.parse(
|
|
36
|
+
await this.ctx.request('GET', `/organizations/${encodeURIComponent(accountId)}`, undefined, {
|
|
37
|
+
cache: false,
|
|
38
|
+
skipAuth: true,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
async batch(input: { ids: string[] }) {
|
|
43
|
+
return organizationBatchSchema.parse(
|
|
44
|
+
await this.ctx.request('POST', '/organizations/batch', input, {
|
|
45
|
+
cache: false,
|
|
46
|
+
skipAuth: true,
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
async create(input: CreateOrganization) {
|
|
51
|
+
return organizationSchema.parse(
|
|
52
|
+
await this.ctx.request('POST', '/organizations', input, { cache: false }),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
async update(accountId: string, input: UpdateOrganization) {
|
|
56
|
+
const result = organizationSchema.parse(
|
|
57
|
+
await this.ctx.request('PATCH', `/organizations/${encodeURIComponent(accountId)}`, input, {
|
|
58
|
+
cache: false,
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
evictOxyIdentityCache(this.ctx.http, accountId);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
async claim(accountId: string, input: OrganizationClaimInput) {
|
|
66
|
+
return organizationClaimSchema.parse(
|
|
67
|
+
await this.ctx.request(
|
|
68
|
+
'POST',
|
|
69
|
+
`/organizations/${encodeURIComponent(accountId)}/claims`,
|
|
70
|
+
input,
|
|
71
|
+
{ cache: false },
|
|
72
|
+
),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
async myClaims(input: OrganizationClaimListQuery = {}) {
|
|
76
|
+
return organizationClaimListSchema.parse(
|
|
77
|
+
await this.ctx.request('GET', '/organizations/claims/mine', input, { cache: false }),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
async myClaim(claimId: string) {
|
|
81
|
+
return organizationClaimDetailSchema.parse(
|
|
82
|
+
await this.ctx.request(
|
|
83
|
+
'GET',
|
|
84
|
+
`/organizations/claims/mine/${encodeURIComponent(claimId)}`,
|
|
85
|
+
undefined,
|
|
86
|
+
{ cache: false },
|
|
87
|
+
),
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
async reviewClaims(input: OrganizationClaimListQuery = {}) {
|
|
91
|
+
return organizationClaimListSchema.parse(
|
|
92
|
+
await this.ctx.request('GET', '/organizations/claims/review', input, { cache: false }),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
async reviewClaimDetail(claimId: string) {
|
|
96
|
+
return organizationClaimDetailSchema.parse(
|
|
97
|
+
await this.ctx.request(
|
|
98
|
+
'GET',
|
|
99
|
+
`/organizations/claims/review/${encodeURIComponent(claimId)}`,
|
|
100
|
+
undefined,
|
|
101
|
+
{ cache: false },
|
|
102
|
+
),
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
async reviewClaim(claimId: string, input: OrganizationClaimReview) {
|
|
106
|
+
const result = organizationClaimSchema.parse(
|
|
107
|
+
await this.ctx.request(
|
|
108
|
+
'POST',
|
|
109
|
+
`/organizations/claims/${encodeURIComponent(claimId)}/review`,
|
|
110
|
+
input,
|
|
111
|
+
{ cache: false },
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
evictOxyIdentityCache(this.ctx.http, result.accountId);
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
async importBatch(input: OrganizationImportBatch) {
|
|
119
|
+
if (!this.ctx.service?.available)
|
|
120
|
+
throw new Error('Organization batch import requires an OxyServer service identity');
|
|
121
|
+
return organizationImportBatchResultSchema.parse(
|
|
122
|
+
await this.ctx.service.request('POST', '/organizations/external/batch', input, {
|
|
123
|
+
cache: false,
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
async importExternal(input: OrganizationExternalInput) {
|
|
128
|
+
return organizationExternalSchema.parse(
|
|
129
|
+
await this.ctx.request('POST', '/organizations/external', input, { cache: false }),
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
async resolveExternal(input: { namespace: string; externalId: string }) {
|
|
133
|
+
return organizationExternalResolutionSchema.parse(
|
|
134
|
+
await this.ctx.request(
|
|
135
|
+
'GET',
|
|
136
|
+
`/organizations/external/${encodeURIComponent(input.namespace)}/${encodeURIComponent(input.externalId)}`,
|
|
137
|
+
undefined,
|
|
138
|
+
{ cache: false },
|
|
139
|
+
),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
async curate(accountId: string, input: OrganizationCuration) {
|
|
143
|
+
const result = organizationCurationResultSchema.parse(
|
|
144
|
+
await this.ctx.request(
|
|
145
|
+
'POST',
|
|
146
|
+
`/organizations/${encodeURIComponent(accountId)}/curation`,
|
|
147
|
+
input,
|
|
148
|
+
{ cache: false },
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
evictOxyIdentityCache(this.ctx.http, accountId);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
async merge(accountId: string, input: OrganizationMerge) {
|
|
156
|
+
const result = organizationSchema.parse(
|
|
157
|
+
await this.ctx.request(
|
|
158
|
+
'POST',
|
|
159
|
+
`/organizations/${encodeURIComponent(accountId)}/merge`,
|
|
160
|
+
input,
|
|
161
|
+
{ cache: false },
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
evictOxyIdentityCache(this.ctx.http, accountId);
|
|
166
|
+
evictOxyIdentityCache(this.ctx.http, result.accountId);
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
async *iterate(input: OrganizationSearch) {
|
|
170
|
+
let cursor = input.cursor;
|
|
171
|
+
const seen = new Set<string>();
|
|
172
|
+
do {
|
|
173
|
+
const page = await this.search({ ...input, cursor });
|
|
174
|
+
yield* page.items;
|
|
175
|
+
cursor = page.nextCursor ?? undefined;
|
|
176
|
+
if (cursor && seen.has(cursor)) throw new Error('Organization directory repeated a cursor');
|
|
177
|
+
if (cursor) seen.add(cursor);
|
|
178
|
+
} while (cursor);
|
|
179
|
+
}
|
|
180
|
+
}
|