@oxyhq/core 3.15.0 → 3.16.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/.tsbuildinfo +1 -1
- package/dist/cjs/mixins/OxyServices.assets.js +14 -35
- package/dist/cjs/mixins/OxyServices.auth.js +12 -1
- package/dist/cjs/mixins/OxyServices.links.js +68 -0
- package/dist/cjs/mixins/index.js +4 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/mixins/OxyServices.assets.js +14 -35
- package/dist/esm/mixins/OxyServices.auth.js +12 -1
- package/dist/esm/mixins/OxyServices.links.js +65 -0
- package/dist/esm/mixins/index.js +4 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/mixins/OxyServices.assets.d.ts +8 -29
- package/dist/types/mixins/OxyServices.auth.d.ts +8 -0
- package/dist/types/mixins/OxyServices.links.d.ts +102 -0
- package/dist/types/mixins/index.d.ts +2 -1
- package/package.json +1 -1
- package/src/mixins/OxyServices.assets.ts +14 -44
- package/src/mixins/OxyServices.auth.ts +35 -1
- package/src/mixins/OxyServices.links.ts +103 -0
- package/src/mixins/__tests__/OxyServices.links.test.ts +154 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +41 -16
- package/src/mixins/__tests__/getFileDownloadUrl.test.ts +10 -24
- package/src/mixins/index.ts +5 -0
|
@@ -19,51 +19,30 @@ function OxyServicesAssetsMixin(Base) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Build a synchronous file URL from an Oxy asset id.
|
|
22
|
+
* Build a synchronous, `<img src>`-ready file URL from an Oxy asset id.
|
|
23
23
|
*
|
|
24
|
-
* This
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* `${cloudURL}/<id>[?variant=...]` (e.g. `https://cloud.oxy.so/<id>?variant=thumb`).
|
|
31
|
-
* CloudFront resolves the id against the public media origin. No token,
|
|
32
|
-
* `fallback`, or origin query params are emitted — these URLs are cacheable
|
|
33
|
-
* and shareable.
|
|
34
|
-
* - **Signed / private asset** — an access token is present on the client OR
|
|
35
|
-
* `expiresIn` was passed (the caller explicitly wants an expiring/authorized
|
|
36
|
-
* URL) → keeps the authenticated origin form
|
|
37
|
-
* `${baseURL}/assets/<id>/stream?...&token=...`. Private assets are NOT on
|
|
38
|
-
* the public CDN, so they must go through the API origin that can authorize
|
|
39
|
-
* the request.
|
|
40
|
-
*
|
|
41
|
-
* `cloudURL` (default `https://cloud.oxy.so`) is configured once on the
|
|
42
|
-
* `OxyServices` constructor and read via `getCloudURL()`; the API origin is
|
|
43
|
-
* `getBaseURL()` (e.g. `https://api.oxy.so`).
|
|
44
|
-
*
|
|
45
|
-
* For a CDN-signed URL fetched from the API, use {@link getFileDownloadUrlAsync}.
|
|
24
|
+
* This method must never embed the caller's general access token in the
|
|
25
|
+
* returned URL. The URL is commonly rendered into DOM attributes, browser
|
|
26
|
+
* network panels, caches, and logs. Public asset URLs use the clean CDN
|
|
27
|
+
* origin; callers that need authorized/private access should use
|
|
28
|
+
* {@link getFileDownloadUrlAsync}, which asks the API for a scoped download
|
|
29
|
+
* URL instead of exposing the in-memory bearer token in a query string.
|
|
46
30
|
*/
|
|
47
|
-
getFileDownloadUrl(fileId, variant, expiresIn
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
31
|
+
getFileDownloadUrl(fileId, variant, expiresIn) {
|
|
32
|
+
// Never embed the in-memory bearer token: this URL is rendered into DOM
|
|
33
|
+
// attributes, browser network panels, caches, and logs. Public assets get
|
|
34
|
+
// the clean CDN origin; private/authorized access goes through
|
|
35
|
+
// `getFileDownloadUrlAsync`.
|
|
36
|
+
if (!expiresIn) {
|
|
52
37
|
const variantQs = variant ? `?variant=${encodeURIComponent(variant)}` : '';
|
|
53
38
|
return `${this.getCloudURL()}/${encodeURIComponent(fileId)}${variantQs}`;
|
|
54
39
|
}
|
|
55
|
-
// Signed / private case: route through the authenticated API origin's
|
|
56
|
-
// stream endpoint so the request can be authorized (private assets are not
|
|
57
|
-
// exposed on the public CDN).
|
|
58
40
|
const base = this.getBaseURL();
|
|
59
41
|
const params = new URLSearchParams();
|
|
60
42
|
if (variant)
|
|
61
43
|
params.set('variant', variant);
|
|
62
|
-
|
|
63
|
-
params.set('expiresIn', String(expiresIn));
|
|
44
|
+
params.set('expiresIn', String(expiresIn));
|
|
64
45
|
params.set('fallback', 'placeholderVisible');
|
|
65
|
-
if (token)
|
|
66
|
-
params.set('token', token);
|
|
67
46
|
const qs = params.toString();
|
|
68
47
|
return `${base}/assets/${encodeURIComponent(fileId)}/stream${qs ? `?${qs}` : ''}`;
|
|
69
48
|
}
|
|
@@ -551,7 +551,18 @@ function OxyServicesAuthMixin(Base) {
|
|
|
551
551
|
*/
|
|
552
552
|
async getCommonsApprovalInfo(authorizeCode) {
|
|
553
553
|
try {
|
|
554
|
-
|
|
554
|
+
const raw = await this.makeRequest('GET', `/auth/session/approve-info/${encodeURIComponent(authorizeCode)}`, undefined, { cache: false });
|
|
555
|
+
return {
|
|
556
|
+
application: raw.application,
|
|
557
|
+
scopes: raw.scopes,
|
|
558
|
+
boundOrigin: raw.boundOrigin,
|
|
559
|
+
// Fail-safe: only a literal boolean `true` counts as verified. A
|
|
560
|
+
// missing or non-boolean value (older server, malformed response)
|
|
561
|
+
// coerces to `false` so a stale server can never imply trust.
|
|
562
|
+
originVerified: raw.originVerified === true,
|
|
563
|
+
expiresAt: raw.expiresAt,
|
|
564
|
+
status: raw.status,
|
|
565
|
+
};
|
|
555
566
|
}
|
|
556
567
|
catch (error) {
|
|
557
568
|
throw this.handleError(error);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OxyServicesLinksMixin = OxyServicesLinksMixin;
|
|
4
|
+
const apiUtils_1 = require("../utils/apiUtils");
|
|
5
|
+
/**
|
|
6
|
+
* Maximum number of URLs sent per `POST /links/previews` request. Matches the
|
|
7
|
+
* server-side batch cap (`linkPreviewBatchRequestSchema`'s `.max(50)`); larger
|
|
8
|
+
* inputs are split into multiple chunked calls and the result maps merged,
|
|
9
|
+
* mirroring how `getUsersByIds` chunks at 100.
|
|
10
|
+
*/
|
|
11
|
+
const LINK_PREVIEWS_CHUNK_SIZE = 50;
|
|
12
|
+
function OxyServicesLinksMixin(Base) {
|
|
13
|
+
return class extends Base {
|
|
14
|
+
constructor(...args) {
|
|
15
|
+
super(...args);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a single link preview via `GET /links/preview?url=<encoded>&wait=0|1`.
|
|
19
|
+
*
|
|
20
|
+
* @param url - The URL to unfurl. Sent percent-encoded in the query string.
|
|
21
|
+
* @param opts.wait - When `true`, asks the server to resolve synchronously
|
|
22
|
+
* (`wait=1`) instead of returning a `'pending'` placeholder for a
|
|
23
|
+
* first-seen URL. Defaults to `false` (`wait=0`).
|
|
24
|
+
*
|
|
25
|
+
* Not cached at the SDK layer: a `'pending'` result can become `'resolved'`
|
|
26
|
+
* on a later read, so caching here would serve the stale placeholder.
|
|
27
|
+
*/
|
|
28
|
+
async getLinkPreview(url, opts) {
|
|
29
|
+
try {
|
|
30
|
+
const path = (0, apiUtils_1.buildUrl)('/links/preview', { url, wait: opts?.wait ? 1 : 0 });
|
|
31
|
+
return await this.makeRequest('GET', path, undefined, { cache: false });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw this.handleError(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Resolve multiple link previews via `POST /links/previews` (body `{ urls }`).
|
|
39
|
+
*
|
|
40
|
+
* Inputs are de-duplicated and split into chunks of {@link LINK_PREVIEWS_CHUNK_SIZE}
|
|
41
|
+
* (the server-side cap). Chunks run concurrently and their `data` maps are
|
|
42
|
+
* merged into a single result keyed by the REQUESTED url (the exact string
|
|
43
|
+
* passed in `urls`) — matching the batch contract — so a caller can always
|
|
44
|
+
* look its own input back up.
|
|
45
|
+
*
|
|
46
|
+
* An empty / whitespace-only input resolves immediately with `{}` and
|
|
47
|
+
* performs no network call. A failure in any chunk surfaces (via
|
|
48
|
+
* `handleError`) rather than being swallowed.
|
|
49
|
+
*/
|
|
50
|
+
async getLinkPreviews(urls) {
|
|
51
|
+
const uniqueUrls = Array.from(new Set(urls.filter((u) => typeof u === 'string' && u.trim().length > 0)));
|
|
52
|
+
if (uniqueUrls.length === 0) {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
const chunks = [];
|
|
56
|
+
for (let i = 0; i < uniqueUrls.length; i += LINK_PREVIEWS_CHUNK_SIZE) {
|
|
57
|
+
chunks.push(uniqueUrls.slice(i, i + LINK_PREVIEWS_CHUNK_SIZE));
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const responses = await Promise.all(chunks.map((chunk) => this.makeRequest('POST', '/links/previews', { urls: chunk }, { cache: false })));
|
|
61
|
+
return responses.reduce((merged, response) => Object.assign(merged, response?.data ?? {}), {});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
throw this.handleError(error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
package/dist/cjs/mixins/index.js
CHANGED
|
@@ -35,6 +35,7 @@ const OxyServices_contacts_1 = require("./OxyServices.contacts");
|
|
|
35
35
|
const OxyServices_appData_1 = require("./OxyServices.appData");
|
|
36
36
|
const OxyServices_civic_1 = require("./OxyServices.civic");
|
|
37
37
|
const OxyServices_nodes_1 = require("./OxyServices.nodes");
|
|
38
|
+
const OxyServices_links_1 = require("./OxyServices.links");
|
|
38
39
|
/**
|
|
39
40
|
* Mixin pipeline - applied in order from first to last.
|
|
40
41
|
*
|
|
@@ -85,6 +86,9 @@ const MIXIN_PIPELINE = [
|
|
|
85
86
|
// User nodes / decentralization (Fase 5): register/read/revoke/manage the
|
|
86
87
|
// caller's personal data node + ingest hint.
|
|
87
88
|
OxyServices_nodes_1.OxyServicesNodesMixin,
|
|
89
|
+
// Link previews / unfurls: SDK-owned link-metadata resolution via oxy-api,
|
|
90
|
+
// so apps stop scraping link metadata locally.
|
|
91
|
+
OxyServices_links_1.OxyServicesLinksMixin,
|
|
88
92
|
// Utility (last, can use all above)
|
|
89
93
|
OxyServices_utility_1.OxyServicesUtilityMixin,
|
|
90
94
|
];
|