@rool-dev/sdk 0.1.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/README.md +1070 -0
- package/dist/apps.d.ts +29 -0
- package/dist/apps.d.ts.map +1 -0
- package/dist/apps.js +88 -0
- package/dist/apps.js.map +1 -0
- package/dist/auth-browser.d.ts +80 -0
- package/dist/auth-browser.d.ts.map +1 -0
- package/dist/auth-browser.js +370 -0
- package/dist/auth-browser.js.map +1 -0
- package/dist/auth-node.d.ts +46 -0
- package/dist/auth-node.d.ts.map +1 -0
- package/dist/auth-node.js +316 -0
- package/dist/auth-node.js.map +1 -0
- package/dist/auth.d.ts +56 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +96 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +202 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +472 -0
- package/dist/client.js.map +1 -0
- package/dist/event-emitter.d.ts +38 -0
- package/dist/event-emitter.d.ts.map +1 -0
- package/dist/event-emitter.js +80 -0
- package/dist/event-emitter.js.map +1 -0
- package/dist/graphql.d.ts +71 -0
- package/dist/graphql.d.ts.map +1 -0
- package/dist/graphql.js +487 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonld.d.ts +47 -0
- package/dist/jsonld.d.ts.map +1 -0
- package/dist/jsonld.js +137 -0
- package/dist/jsonld.js.map +1 -0
- package/dist/media.d.ts +52 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +173 -0
- package/dist/media.js.map +1 -0
- package/dist/space.d.ts +358 -0
- package/dist/space.d.ts.map +1 -0
- package/dist/space.js +1121 -0
- package/dist/space.js.map +1 -0
- package/dist/subscription.d.ts +57 -0
- package/dist/subscription.d.ts.map +1 -0
- package/dist/subscription.js +296 -0
- package/dist/subscription.js.map +1 -0
- package/dist/types.d.ts +409 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -0
package/dist/jsonld.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert space data to JSON-LD format.
|
|
3
|
+
* Filters out orphan links (links to non-existent objects) to ensure clean exports.
|
|
4
|
+
*/
|
|
5
|
+
export function toJsonLd(data) {
|
|
6
|
+
const objectIds = new Set(Object.keys(data.objects));
|
|
7
|
+
const graph = Object.values(data.objects).map(entry => {
|
|
8
|
+
const node = { ...entry.data };
|
|
9
|
+
// Add relations as arrays of target IDs, filtering out orphans
|
|
10
|
+
for (const [relation, targets] of Object.entries(entry.links)) {
|
|
11
|
+
const validTargets = targets.filter(id => objectIds.has(id));
|
|
12
|
+
if (validTargets.length > 0) {
|
|
13
|
+
node[relation] = validTargets;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return node;
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
'@context': {
|
|
20
|
+
'@vocab': 'https://rool.dev/schema/',
|
|
21
|
+
'id': '@id',
|
|
22
|
+
},
|
|
23
|
+
'@graph': graph,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse JSON-LD into objects and relations for import.
|
|
28
|
+
*
|
|
29
|
+
* Uses two-pass parsing to distinguish relations from data:
|
|
30
|
+
* - First pass: collect all object IDs in the graph
|
|
31
|
+
* - Second pass: string arrays where ALL values are valid object IDs are treated as relations;
|
|
32
|
+
* otherwise they are treated as data fields
|
|
33
|
+
*/
|
|
34
|
+
export function fromJsonLd(jsonld) {
|
|
35
|
+
if (typeof jsonld !== 'object' || jsonld === null) {
|
|
36
|
+
throw new Error('Invalid JSON-LD: expected object');
|
|
37
|
+
}
|
|
38
|
+
const doc = jsonld;
|
|
39
|
+
const graph = doc['@graph'];
|
|
40
|
+
if (!Array.isArray(graph)) {
|
|
41
|
+
throw new Error('Invalid JSON-LD: missing @graph array');
|
|
42
|
+
}
|
|
43
|
+
// First pass: collect all object IDs
|
|
44
|
+
const objectIds = new Set();
|
|
45
|
+
for (const node of graph) {
|
|
46
|
+
if (typeof node !== 'object' || node === null)
|
|
47
|
+
continue;
|
|
48
|
+
const nodeObj = node;
|
|
49
|
+
const id = nodeObj.id;
|
|
50
|
+
if (id) {
|
|
51
|
+
objectIds.add(id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Second pass: parse objects and distinguish relations from data
|
|
55
|
+
const objects = [];
|
|
56
|
+
for (const node of graph) {
|
|
57
|
+
if (typeof node !== 'object' || node === null)
|
|
58
|
+
continue;
|
|
59
|
+
const nodeObj = node;
|
|
60
|
+
const id = nodeObj.id;
|
|
61
|
+
if (!id) {
|
|
62
|
+
throw new Error('Invalid JSON-LD: object missing id');
|
|
63
|
+
}
|
|
64
|
+
const data = { id };
|
|
65
|
+
const relations = [];
|
|
66
|
+
for (const [key, value] of Object.entries(nodeObj)) {
|
|
67
|
+
if (key === 'id' || key.startsWith('@'))
|
|
68
|
+
continue;
|
|
69
|
+
// Check if value is an array of strings where ALL values are valid object IDs
|
|
70
|
+
if (Array.isArray(value) &&
|
|
71
|
+
value.length > 0 &&
|
|
72
|
+
value.every(v => typeof v === 'string' && objectIds.has(v))) {
|
|
73
|
+
// All values are object IDs - treat as relations
|
|
74
|
+
for (const targetId of value) {
|
|
75
|
+
relations.push({ relation: key, targetId });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Not all values are object IDs - treat as data
|
|
80
|
+
data[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
objects.push({ id, data, relations });
|
|
84
|
+
}
|
|
85
|
+
return { objects };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Recursively find all string values in a JSON-LD document.
|
|
89
|
+
* Used to detect media URLs for archive export.
|
|
90
|
+
*/
|
|
91
|
+
export function findAllStrings(doc) {
|
|
92
|
+
const strings = new Set();
|
|
93
|
+
function scan(value) {
|
|
94
|
+
if (typeof value === 'string') {
|
|
95
|
+
strings.add(value);
|
|
96
|
+
}
|
|
97
|
+
else if (Array.isArray(value)) {
|
|
98
|
+
for (const item of value) {
|
|
99
|
+
scan(item);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (typeof value === 'object' && value !== null) {
|
|
103
|
+
for (const v of Object.values(value)) {
|
|
104
|
+
scan(v);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
scan(doc['@graph']);
|
|
109
|
+
return strings;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Rewrite string values in a JSON-LD document using a mapping.
|
|
113
|
+
* Returns a new document (does not mutate the original).
|
|
114
|
+
*/
|
|
115
|
+
export function rewriteStrings(doc, mapping) {
|
|
116
|
+
function rewrite(value) {
|
|
117
|
+
if (typeof value === 'string') {
|
|
118
|
+
return mapping.get(value) ?? value;
|
|
119
|
+
}
|
|
120
|
+
else if (Array.isArray(value)) {
|
|
121
|
+
return value.map(rewrite);
|
|
122
|
+
}
|
|
123
|
+
else if (typeof value === 'object' && value !== null) {
|
|
124
|
+
const result = {};
|
|
125
|
+
for (const [k, v] of Object.entries(value)) {
|
|
126
|
+
result[k] = rewrite(v);
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
'@context': doc['@context'],
|
|
134
|
+
'@graph': rewrite(doc['@graph']),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=jsonld.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonld.js","sourceRoot":"","sources":["../src/jsonld.ts"],"names":[],"mappings":"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"}
|
package/dist/media.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { MediaInfo, MediaResponse } from './types.js';
|
|
2
|
+
import type { AuthManager } from './auth.js';
|
|
3
|
+
export interface MediaClientConfig {
|
|
4
|
+
mediaUrl: string;
|
|
5
|
+
backendOrigin: string;
|
|
6
|
+
authManager: AuthManager;
|
|
7
|
+
}
|
|
8
|
+
export declare class MediaClient {
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config: MediaClientConfig);
|
|
11
|
+
private baseUrl;
|
|
12
|
+
/**
|
|
13
|
+
* Extract UUID from a media URL.
|
|
14
|
+
* URL format: {baseUrl}/{spaceId}/{uuid}
|
|
15
|
+
*/
|
|
16
|
+
private extractUuid;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a URL is a backend URL (requires auth).
|
|
19
|
+
*/
|
|
20
|
+
private isBackendUrl;
|
|
21
|
+
/**
|
|
22
|
+
* List all media files for a space.
|
|
23
|
+
*/
|
|
24
|
+
list(spaceId: string): Promise<MediaInfo[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Upload a file to a space. Returns the URL.
|
|
27
|
+
* Accepts File, Blob, or base64 data with content type.
|
|
28
|
+
*/
|
|
29
|
+
upload(spaceId: string, file: File | Blob | {
|
|
30
|
+
data: string;
|
|
31
|
+
contentType: string;
|
|
32
|
+
}): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Fetch any URL, returning headers and a blob() method (like fetch Response).
|
|
35
|
+
* For backend URLs: adds auth headers.
|
|
36
|
+
* For external URLs: tries direct fetch first, falls back to server proxy if CORS blocks it.
|
|
37
|
+
*/
|
|
38
|
+
fetch(spaceId: string, url: string): Promise<MediaResponse>;
|
|
39
|
+
/**
|
|
40
|
+
* Fetch a backend URL with auth headers.
|
|
41
|
+
*/
|
|
42
|
+
private fetchWithAuth;
|
|
43
|
+
/**
|
|
44
|
+
* Fetch an external URL via the server proxy (bypasses CORS).
|
|
45
|
+
*/
|
|
46
|
+
private fetchViaProxy;
|
|
47
|
+
/**
|
|
48
|
+
* Delete a media file by URL.
|
|
49
|
+
*/
|
|
50
|
+
delete(spaceId: string, url: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAoB;gBAEtB,MAAM,EAAE,iBAAiB;IAIrC,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAgBjD;;;OAGG;IACG,MAAM,CACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,MAAM,CAAC;IAmClB;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA6BjE;;OAEG;YACW,aAAa;IAgB3B;;OAEG;YACW,aAAa;IAiB3B;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAc1D"}
|
package/dist/media.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Media Client
|
|
3
|
+
// REST API wrapper for file upload/download/list/delete
|
|
4
|
+
// =============================================================================
|
|
5
|
+
export class MediaClient {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
baseUrl(spaceId) {
|
|
11
|
+
return `${this.config.mediaUrl}/${encodeURIComponent(spaceId)}`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extract UUID from a media URL.
|
|
15
|
+
* URL format: {baseUrl}/{spaceId}/{uuid}
|
|
16
|
+
*/
|
|
17
|
+
extractUuid(url) {
|
|
18
|
+
const parts = new URL(url).pathname.split('/');
|
|
19
|
+
const uuid = parts[parts.length - 1];
|
|
20
|
+
if (!uuid)
|
|
21
|
+
throw new Error('Invalid media URL: cannot extract UUID');
|
|
22
|
+
return uuid;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a URL is a backend URL (requires auth).
|
|
26
|
+
*/
|
|
27
|
+
isBackendUrl(url) {
|
|
28
|
+
if (url.startsWith('/'))
|
|
29
|
+
return true;
|
|
30
|
+
try {
|
|
31
|
+
const parsed = new URL(url);
|
|
32
|
+
return parsed.origin === this.config.backendOrigin;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* List all media files for a space.
|
|
40
|
+
*/
|
|
41
|
+
async list(spaceId) {
|
|
42
|
+
const token = await this.config.authManager.getToken();
|
|
43
|
+
if (!token)
|
|
44
|
+
throw new Error('Not authenticated');
|
|
45
|
+
const response = await fetch(this.baseUrl(spaceId), {
|
|
46
|
+
method: 'GET',
|
|
47
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error(`Failed to list media: ${response.status} ${response.statusText}`);
|
|
51
|
+
}
|
|
52
|
+
return response.json();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Upload a file to a space. Returns the URL.
|
|
56
|
+
* Accepts File, Blob, or base64 data with content type.
|
|
57
|
+
*/
|
|
58
|
+
async upload(spaceId, file) {
|
|
59
|
+
const token = await this.config.authManager.getToken();
|
|
60
|
+
if (!token)
|
|
61
|
+
throw new Error('Not authenticated');
|
|
62
|
+
let body;
|
|
63
|
+
const headers = {
|
|
64
|
+
Authorization: `Bearer ${token}`,
|
|
65
|
+
};
|
|
66
|
+
if (file instanceof File || file instanceof Blob) {
|
|
67
|
+
const formData = new FormData();
|
|
68
|
+
formData.append('file', file);
|
|
69
|
+
body = formData;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
headers['Content-Type'] = 'application/json';
|
|
73
|
+
body = JSON.stringify({
|
|
74
|
+
data: file.data,
|
|
75
|
+
contentType: file.contentType,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const response = await fetch(this.baseUrl(spaceId), {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers,
|
|
81
|
+
body,
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`Failed to upload media: ${response.status} ${response.statusText}`);
|
|
85
|
+
}
|
|
86
|
+
const item = await response.json();
|
|
87
|
+
return item.url;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fetch any URL, returning headers and a blob() method (like fetch Response).
|
|
91
|
+
* For backend URLs: adds auth headers.
|
|
92
|
+
* For external URLs: tries direct fetch first, falls back to server proxy if CORS blocks it.
|
|
93
|
+
*/
|
|
94
|
+
async fetch(spaceId, url) {
|
|
95
|
+
let response;
|
|
96
|
+
if (this.isBackendUrl(url)) {
|
|
97
|
+
response = await this.fetchWithAuth(url);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// External URL: try direct fetch first
|
|
101
|
+
try {
|
|
102
|
+
const directResponse = await fetch(url, { method: 'GET', mode: 'cors' });
|
|
103
|
+
if (directResponse.ok) {
|
|
104
|
+
response = directResponse;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Non-OK response, fall through to proxy
|
|
108
|
+
response = await this.fetchViaProxy(spaceId, url);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// CORS or network error, fall through to proxy
|
|
113
|
+
response = await this.fetchViaProxy(spaceId, url);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const contentLength = response.headers.get('content-length');
|
|
117
|
+
return {
|
|
118
|
+
contentType: response.headers.get('content-type') || 'application/octet-stream',
|
|
119
|
+
size: contentLength ? parseInt(contentLength, 10) : null,
|
|
120
|
+
blob: () => response.blob(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Fetch a backend URL with auth headers.
|
|
125
|
+
*/
|
|
126
|
+
async fetchWithAuth(url) {
|
|
127
|
+
const token = await this.config.authManager.getToken();
|
|
128
|
+
if (!token)
|
|
129
|
+
throw new Error('Not authenticated');
|
|
130
|
+
const response = await fetch(url, {
|
|
131
|
+
method: 'GET',
|
|
132
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
133
|
+
});
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
throw new Error(`Failed to fetch media: ${response.status} ${response.statusText}`);
|
|
136
|
+
}
|
|
137
|
+
return response;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Fetch an external URL via the server proxy (bypasses CORS).
|
|
141
|
+
*/
|
|
142
|
+
async fetchViaProxy(spaceId, url) {
|
|
143
|
+
const token = await this.config.authManager.getToken();
|
|
144
|
+
if (!token)
|
|
145
|
+
throw new Error('Not authenticated');
|
|
146
|
+
const proxyUrl = `${this.baseUrl(spaceId)}/proxy?url=${encodeURIComponent(url)}`;
|
|
147
|
+
const response = await fetch(proxyUrl, {
|
|
148
|
+
method: 'GET',
|
|
149
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
150
|
+
});
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
throw new Error(`Failed to fetch media via proxy: ${response.status} ${response.statusText}`);
|
|
153
|
+
}
|
|
154
|
+
return response;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Delete a media file by URL.
|
|
158
|
+
*/
|
|
159
|
+
async delete(spaceId, url) {
|
|
160
|
+
const token = await this.config.authManager.getToken();
|
|
161
|
+
if (!token)
|
|
162
|
+
throw new Error('Not authenticated');
|
|
163
|
+
const uuid = this.extractUuid(url);
|
|
164
|
+
const response = await fetch(`${this.baseUrl(spaceId)}/${encodeURIComponent(uuid)}`, {
|
|
165
|
+
method: 'DELETE',
|
|
166
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
167
|
+
});
|
|
168
|
+
if (!response.ok && response.status !== 204) {
|
|
169
|
+
throw new Error(`Failed to delete media: ${response.status} ${response.statusText}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"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"}
|