@kmlckj/licos-platform-sdk 0.6.5 → 0.6.8
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 +88 -23
- package/dist/browser.js +1 -0
- package/dist/database.js +1 -0
- package/dist/index.d.ts +531 -0
- package/dist/index.js +1 -0
- package/dist/knowledge.js +1 -0
- package/dist/runtime.js +1 -0
- package/dist/shared.js +1 -0
- package/dist/storage.js +1 -0
- package/dist/studio-database.js +1 -0
- package/package.json +19 -14
- package/src/browser.js +0 -1
- package/src/database.js +0 -688
- package/src/index.d.ts +0 -251
- package/src/index.js +0 -3
- package/src/runtime.js +0 -144
- package/src/shared.js +0 -12
- package/src/storage.js +0 -167
- /package/{src → dist}/browser.d.ts +0 -0
package/src/index.d.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
export class PlatformSdkError extends Error {
|
|
2
|
-
status?: number;
|
|
3
|
-
code?: number;
|
|
4
|
-
details?: unknown;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export class ConfigurationError extends PlatformSdkError {}
|
|
8
|
-
export class ApiError extends PlatformSdkError {}
|
|
9
|
-
|
|
10
|
-
export interface DatabaseFilter {
|
|
11
|
-
field: string;
|
|
12
|
-
op: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'not_in' | 'is_null' | 'is_not_null' | 'like' | 'ilike' | string;
|
|
13
|
-
value?: unknown;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface DatabaseOrderBy {
|
|
17
|
-
field: string;
|
|
18
|
-
direction?: 'asc' | 'desc';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface DatabaseRange {
|
|
22
|
-
from: number;
|
|
23
|
-
to: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface DatabaseResponse {
|
|
27
|
-
data?: Record<string, unknown>[];
|
|
28
|
-
count?: number;
|
|
29
|
-
affectedRows?: number;
|
|
30
|
-
message?: string;
|
|
31
|
-
[key: string]: unknown;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface DatabaseQueryOptions {
|
|
35
|
-
select?: string | string[];
|
|
36
|
-
filters?: DatabaseFilter[];
|
|
37
|
-
orderBy?: DatabaseOrderBy[];
|
|
38
|
-
range?: DatabaseRange;
|
|
39
|
-
limit?: number;
|
|
40
|
-
offset?: number;
|
|
41
|
-
count?: boolean;
|
|
42
|
-
head?: boolean;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface DatabaseMutationOptions {
|
|
46
|
-
row?: Record<string, unknown>;
|
|
47
|
-
rows?: Record<string, unknown>[];
|
|
48
|
-
values?: Record<string, unknown>;
|
|
49
|
-
filters?: DatabaseFilter[];
|
|
50
|
-
updates?: Array<{ filters?: DatabaseFilter[]; values?: Record<string, unknown> }>;
|
|
51
|
-
deletes?: Array<{ filters?: DatabaseFilter[] }>;
|
|
52
|
-
conflictKeys?: string[];
|
|
53
|
-
returning?: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface DatabaseOperation {
|
|
57
|
-
type: 'query' | 'insert' | 'update' | 'delete' | 'upsert' | string;
|
|
58
|
-
request: Record<string, unknown>;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface DatabaseSchemaColumn {
|
|
62
|
-
name: string;
|
|
63
|
-
type?: string;
|
|
64
|
-
nullable?: boolean;
|
|
65
|
-
primaryKey?: boolean;
|
|
66
|
-
defaultValue?: string | null;
|
|
67
|
-
[key: string]: unknown;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface DatabaseSchemaTable {
|
|
71
|
-
schema?: string;
|
|
72
|
-
name: string;
|
|
73
|
-
description?: string | null;
|
|
74
|
-
columns?: DatabaseSchemaColumn[];
|
|
75
|
-
indexes?: unknown[];
|
|
76
|
-
foreignKeys?: unknown[];
|
|
77
|
-
constraints?: unknown[];
|
|
78
|
-
[key: string]: unknown;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface DatabaseSchema {
|
|
82
|
-
databaseId?: string;
|
|
83
|
-
environment?: 'dev' | 'prod' | string;
|
|
84
|
-
tables?: DatabaseSchemaTable[];
|
|
85
|
-
views?: unknown[];
|
|
86
|
-
functions?: unknown[];
|
|
87
|
-
enums?: unknown[];
|
|
88
|
-
[key: string]: unknown;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface GenerateOrmOptions {
|
|
92
|
-
language: 'typescript' | 'python' | 'ts' | 'py' | string;
|
|
93
|
-
orm?: 'drizzle' | 'sqlalchemy' | string;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export interface TableQuery {
|
|
97
|
-
select(...fields: string[]): TableQuery;
|
|
98
|
-
filter(field: string, op: string, value?: unknown): TableQuery;
|
|
99
|
-
eq(field: string, value: unknown): TableQuery;
|
|
100
|
-
neq(field: string, value: unknown): TableQuery;
|
|
101
|
-
gt(field: string, value: unknown): TableQuery;
|
|
102
|
-
gte(field: string, value: unknown): TableQuery;
|
|
103
|
-
lt(field: string, value: unknown): TableQuery;
|
|
104
|
-
lte(field: string, value: unknown): TableQuery;
|
|
105
|
-
in(field: string, value: unknown[]): TableQuery;
|
|
106
|
-
notIn(field: string, value: unknown[]): TableQuery;
|
|
107
|
-
isNull(field: string): TableQuery;
|
|
108
|
-
isNotNull(field: string): TableQuery;
|
|
109
|
-
like(field: string, value: string): TableQuery;
|
|
110
|
-
ilike(field: string, value: string): TableQuery;
|
|
111
|
-
order(field: string, options?: { desc?: boolean }): TableQuery;
|
|
112
|
-
range(from: number, to: number): TableQuery;
|
|
113
|
-
limit(value: number): TableQuery;
|
|
114
|
-
offset(value: number): TableQuery;
|
|
115
|
-
withCount(options?: { head?: boolean }): TableQuery;
|
|
116
|
-
execute(): Promise<DatabaseResponse>;
|
|
117
|
-
single(): Promise<DatabaseResponse>;
|
|
118
|
-
maybeSingle(): Promise<DatabaseResponse>;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function query(table: string, options?: DatabaseQueryOptions): Promise<DatabaseResponse>;
|
|
122
|
-
export function single(table: string, options?: DatabaseQueryOptions & { maybe?: boolean }): Promise<DatabaseResponse>;
|
|
123
|
-
export function maybeSingle(table: string, options?: DatabaseQueryOptions): Promise<DatabaseResponse>;
|
|
124
|
-
export function aggregate(table: string, aggregateName: string, options?: { field?: string; groupBy?: string[]; filters?: DatabaseFilter[] }): Promise<DatabaseResponse>;
|
|
125
|
-
export function insert(table: string, options?: DatabaseMutationOptions): Promise<DatabaseResponse>;
|
|
126
|
-
export function updateRows(table: string, options?: DatabaseMutationOptions): Promise<DatabaseResponse>;
|
|
127
|
-
export function deleteRows(table: string, options?: DatabaseMutationOptions): Promise<DatabaseResponse>;
|
|
128
|
-
export function upsert(table: string, options?: DatabaseMutationOptions): Promise<DatabaseResponse>;
|
|
129
|
-
export function transaction(operations: DatabaseOperation[]): Promise<DatabaseResponse[]>;
|
|
130
|
-
export function rpc(functionName: string, args?: Record<string, unknown>): Promise<DatabaseResponse>;
|
|
131
|
-
export function getSchema(): Promise<DatabaseSchema>;
|
|
132
|
-
export function defaultOrm(language: string): string;
|
|
133
|
-
export function generateOrm(schemaPayload: DatabaseSchema, options: GenerateOrmOptions): string;
|
|
134
|
-
export function exportOrm(options: GenerateOrmOptions): Promise<string>;
|
|
135
|
-
export function table(name: string): TableQuery;
|
|
136
|
-
|
|
137
|
-
export const database: {
|
|
138
|
-
query: typeof query;
|
|
139
|
-
single: typeof single;
|
|
140
|
-
maybeSingle: typeof maybeSingle;
|
|
141
|
-
aggregate: typeof aggregate;
|
|
142
|
-
insert: typeof insert;
|
|
143
|
-
updateRows: typeof updateRows;
|
|
144
|
-
deleteRows: typeof deleteRows;
|
|
145
|
-
upsert: typeof upsert;
|
|
146
|
-
transaction: typeof transaction;
|
|
147
|
-
rpc: typeof rpc;
|
|
148
|
-
getSchema: typeof getSchema;
|
|
149
|
-
defaultOrm: typeof defaultOrm;
|
|
150
|
-
generateOrm: typeof generateOrm;
|
|
151
|
-
exportOrm: typeof exportOrm;
|
|
152
|
-
table: typeof table;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
export interface StorageSummary {
|
|
156
|
-
workspaceId?: string;
|
|
157
|
-
projectId?: string;
|
|
158
|
-
scope?: string;
|
|
159
|
-
bucketName?: string;
|
|
160
|
-
usedSizeBytes?: number;
|
|
161
|
-
fileCount?: number;
|
|
162
|
-
folderCount?: number;
|
|
163
|
-
serviceEnabled?: boolean;
|
|
164
|
-
[key: string]: unknown;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export interface StorageFolder {
|
|
168
|
-
id?: string;
|
|
169
|
-
workspaceId?: string;
|
|
170
|
-
projectId?: string;
|
|
171
|
-
scope?: string;
|
|
172
|
-
parentId?: string | null;
|
|
173
|
-
folderName?: string;
|
|
174
|
-
folderPath?: string;
|
|
175
|
-
createdAt?: string;
|
|
176
|
-
updatedAt?: string;
|
|
177
|
-
[key: string]: unknown;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface StorageFile {
|
|
181
|
-
id?: string;
|
|
182
|
-
workspaceId?: string;
|
|
183
|
-
projectId?: string;
|
|
184
|
-
scope?: string;
|
|
185
|
-
folderId?: string | null;
|
|
186
|
-
folderPath?: string;
|
|
187
|
-
fileName?: string;
|
|
188
|
-
contentType?: string;
|
|
189
|
-
sizeBytes?: number;
|
|
190
|
-
storageBucket?: string;
|
|
191
|
-
storageKey?: string;
|
|
192
|
-
downloadUrl?: string;
|
|
193
|
-
createdAt?: string;
|
|
194
|
-
updatedAt?: string;
|
|
195
|
-
[key: string]: unknown;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export interface StorageEntries {
|
|
199
|
-
currentFolderId?: string | null;
|
|
200
|
-
currentFolderName?: string;
|
|
201
|
-
currentFolderPath?: string;
|
|
202
|
-
breadcrumbs?: unknown[];
|
|
203
|
-
folders?: StorageFolder[];
|
|
204
|
-
files?: StorageFile[];
|
|
205
|
-
[key: string]: unknown;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export interface UploadFileOptions {
|
|
209
|
-
folderId?: string;
|
|
210
|
-
fileName?: string;
|
|
211
|
-
contentType?: string;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export const MAX_UPLOAD_FILE_BYTES: number;
|
|
215
|
-
|
|
216
|
-
export interface ShareUrlOptions {
|
|
217
|
-
expirySeconds?: number;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
export function summary(): Promise<StorageSummary>;
|
|
221
|
-
export function listFolders(): Promise<StorageFolder[]>;
|
|
222
|
-
export function listEntries(options?: { folderId?: string }): Promise<StorageEntries>;
|
|
223
|
-
export function listFiles(): Promise<StorageFile[]>;
|
|
224
|
-
export function createFolder(folderName: string, options?: { parentId?: string }): Promise<StorageFolder>;
|
|
225
|
-
export function renameFolder(folderId: string, folderName: string): Promise<StorageFolder>;
|
|
226
|
-
export function deleteFolder(folderId: string): Promise<void>;
|
|
227
|
-
export function uploadFile(
|
|
228
|
-
input: string | Blob | Buffer | Uint8Array,
|
|
229
|
-
options?: UploadFileOptions,
|
|
230
|
-
): Promise<StorageFile>;
|
|
231
|
-
export function renameFile(fileId: string, fileName: string): Promise<StorageFile>;
|
|
232
|
-
export function moveFile(fileId: string, options?: { folderId?: string }): Promise<StorageFile>;
|
|
233
|
-
export function shareUrl(fileId: string, options?: ShareUrlOptions): Promise<{ url?: string; expiresAt?: string; [key: string]: unknown }>;
|
|
234
|
-
export function objectExists(options?: { fileId?: string; objectKey?: string }): Promise<{ fileId?: string; bucketName?: string; objectKey?: string; exists?: boolean; [key: string]: unknown }>;
|
|
235
|
-
export function deleteFile(fileId: string): Promise<void>;
|
|
236
|
-
|
|
237
|
-
export const storage: {
|
|
238
|
-
summary: typeof summary;
|
|
239
|
-
listFolders: typeof listFolders;
|
|
240
|
-
listEntries: typeof listEntries;
|
|
241
|
-
listFiles: typeof listFiles;
|
|
242
|
-
createFolder: typeof createFolder;
|
|
243
|
-
renameFolder: typeof renameFolder;
|
|
244
|
-
deleteFolder: typeof deleteFolder;
|
|
245
|
-
uploadFile: typeof uploadFile;
|
|
246
|
-
renameFile: typeof renameFile;
|
|
247
|
-
moveFile: typeof moveFile;
|
|
248
|
-
shareUrl: typeof shareUrl;
|
|
249
|
-
objectExists: typeof objectExists;
|
|
250
|
-
deleteFile: typeof deleteFile;
|
|
251
|
-
};
|
package/src/index.js
DELETED
package/src/runtime.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { ConfigurationError } from './shared.js';
|
|
2
|
-
|
|
3
|
-
const AI_USER_TOKEN_PATH = '/api/v1/internal/auth/ai-user-token';
|
|
4
|
-
const tokenCache = new Map();
|
|
5
|
-
|
|
6
|
-
export function env(name) {
|
|
7
|
-
const value = process.env[name];
|
|
8
|
-
if (typeof value !== 'string') return undefined;
|
|
9
|
-
const trimmed = value.trim();
|
|
10
|
-
return trimmed ? trimmed : undefined;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function normalizeBaseUrl(value) {
|
|
14
|
-
let trimmed = value.trim().replace(/\/+$/, '');
|
|
15
|
-
if (trimmed.endsWith('/api/v1')) {
|
|
16
|
-
trimmed = trimmed.slice(0, -'/api/v1'.length);
|
|
17
|
-
}
|
|
18
|
-
return trimmed.replace(/\/+$/, '');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function serviceBaseUrl(hostEnv, portEnv, defaultPort) {
|
|
22
|
-
const host = env(hostEnv);
|
|
23
|
-
if (!host) return undefined;
|
|
24
|
-
return `http://${host}:${env(portEnv) || defaultPort}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function platformBaseUrl() {
|
|
28
|
-
const value =
|
|
29
|
-
env('LICOS_PLATFORM_API_BASE_URL') ||
|
|
30
|
-
serviceBaseUrl('AIOS_PLATFORM_SERVICE_HOST', 'AIOS_PLATFORM_SERVICE_PORT', '9100') ||
|
|
31
|
-
serviceBaseUrl('LICOS_PLATFORM_SERVICE_HOST', 'LICOS_PLATFORM_SERVICE_PORT', '9100') ||
|
|
32
|
-
serviceBaseUrl('PLATFORM_SERVICE_HOST', 'PLATFORM_SERVICE_PORT', '9100');
|
|
33
|
-
if (!value) {
|
|
34
|
-
throw new ConfigurationError('LICOS_PLATFORM_API_BASE_URL is not configured');
|
|
35
|
-
}
|
|
36
|
-
return normalizeBaseUrl(value);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function projectEnvironment(overrideEnvName) {
|
|
40
|
-
const explicit = ((overrideEnvName ? env(overrideEnvName) : undefined) || '').toLowerCase();
|
|
41
|
-
if (explicit === 'dev' || explicit === 'prod') return explicit;
|
|
42
|
-
const projectEnv = (env('LICOS_PROJECT_ENV') || env('AGENT_ENV') || '').toLowerCase();
|
|
43
|
-
return ['prod', 'production', 'release'].includes(projectEnv) ? 'prod' : 'dev';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function decodeAiTokenPayload(payload) {
|
|
47
|
-
if (!payload || typeof payload !== 'object') {
|
|
48
|
-
throw new ConfigurationError('AI user token exchange response is not an object');
|
|
49
|
-
}
|
|
50
|
-
if ((payload.code !== undefined && payload.code !== 0) || payload.success === false) {
|
|
51
|
-
const error = new ConfigurationError(payload.message || 'AI user token exchange failed');
|
|
52
|
-
error.code = typeof payload.code === 'number' ? payload.code : undefined;
|
|
53
|
-
error.details = payload;
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
56
|
-
const data = payload.data;
|
|
57
|
-
const token =
|
|
58
|
-
typeof data === 'string'
|
|
59
|
-
? data.trim()
|
|
60
|
-
: String(data?.accessToken || data?.access_token || data?.token || '').trim();
|
|
61
|
-
if (!token) {
|
|
62
|
-
const error = new ConfigurationError('AI user token exchange response missing accessToken');
|
|
63
|
-
error.details = payload;
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
return token;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function resolveUserToken(baseUrl, userId) {
|
|
70
|
-
const ownerUserId = String(userId || '').trim();
|
|
71
|
-
if (!ownerUserId) {
|
|
72
|
-
throw new ConfigurationError('project owner user ID is not configured');
|
|
73
|
-
}
|
|
74
|
-
const aiAgentToken = env('LICOS_AI_AGENT_TOKEN');
|
|
75
|
-
if (!aiAgentToken) {
|
|
76
|
-
throw new ConfigurationError('platform runtime identity is unavailable');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const cacheKey = `${baseUrl}\n${ownerUserId}\n${aiAgentToken}`;
|
|
80
|
-
if (tokenCache.has(cacheKey)) return tokenCache.get(cacheKey);
|
|
81
|
-
|
|
82
|
-
const promise = fetch(`${baseUrl}${AI_USER_TOKEN_PATH}`, {
|
|
83
|
-
method: 'POST',
|
|
84
|
-
headers: {
|
|
85
|
-
Authorization: `Bearer ${aiAgentToken}`,
|
|
86
|
-
'Content-Type': 'application/json',
|
|
87
|
-
},
|
|
88
|
-
body: JSON.stringify({ userId: ownerUserId }),
|
|
89
|
-
}).then(async (response) => {
|
|
90
|
-
const text = await response.text();
|
|
91
|
-
let payload = null;
|
|
92
|
-
try {
|
|
93
|
-
payload = text ? JSON.parse(text) : null;
|
|
94
|
-
} catch (error) {
|
|
95
|
-
const wrapped = new ConfigurationError('parse AI user token exchange response failed');
|
|
96
|
-
wrapped.status = response.status;
|
|
97
|
-
wrapped.details = text;
|
|
98
|
-
throw wrapped;
|
|
99
|
-
}
|
|
100
|
-
if (!response.ok) {
|
|
101
|
-
const message = payload?.message || text || `AI user token exchange returned ${response.status}`;
|
|
102
|
-
const wrapped = new ConfigurationError(message);
|
|
103
|
-
wrapped.status = response.status;
|
|
104
|
-
wrapped.details = payload;
|
|
105
|
-
throw wrapped;
|
|
106
|
-
}
|
|
107
|
-
return decodeAiTokenPayload(payload);
|
|
108
|
-
});
|
|
109
|
-
tokenCache.set(cacheKey, promise);
|
|
110
|
-
try {
|
|
111
|
-
return await promise;
|
|
112
|
-
} catch (error) {
|
|
113
|
-
tokenCache.delete(cacheKey);
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function runtimeConfig({ environmentOverrideEnv } = {}) {
|
|
119
|
-
const projectId = env('LICOS_PROJECT_ID') || env('AGENT_PROJECT_ID');
|
|
120
|
-
if (!projectId) {
|
|
121
|
-
throw new ConfigurationError('LICOS_PROJECT_ID or AGENT_PROJECT_ID is not configured');
|
|
122
|
-
}
|
|
123
|
-
const baseUrl = platformBaseUrl();
|
|
124
|
-
const userId = env('LICOS_USER_ID') || env('AGENT_USER_ID');
|
|
125
|
-
const token = await resolveUserToken(baseUrl, userId);
|
|
126
|
-
return {
|
|
127
|
-
baseUrl,
|
|
128
|
-
projectId,
|
|
129
|
-
environment: projectEnvironment(environmentOverrideEnv),
|
|
130
|
-
token,
|
|
131
|
-
workspaceId: env('LICOS_WORKSPACE_ID') || env('AGENT_WORKSPACE_ID'),
|
|
132
|
-
userId,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function authHeaders(config, contentType = 'application/json') {
|
|
137
|
-
const result = {
|
|
138
|
-
Authorization: `Bearer ${config.token}`,
|
|
139
|
-
};
|
|
140
|
-
if (contentType) result['Content-Type'] = contentType;
|
|
141
|
-
if (config.workspaceId) result['X-Workspace-Id'] = config.workspaceId;
|
|
142
|
-
if (config.userId) result['X-User-Id'] = config.userId;
|
|
143
|
-
return result;
|
|
144
|
-
}
|
package/src/shared.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export class PlatformSdkError extends Error {
|
|
2
|
-
constructor(message, options = {}) {
|
|
3
|
-
super(message);
|
|
4
|
-
this.name = new.target.name;
|
|
5
|
-
this.status = options.status;
|
|
6
|
-
this.code = options.code;
|
|
7
|
-
this.details = options.details;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class ConfigurationError extends PlatformSdkError {}
|
|
12
|
-
export class ApiError extends PlatformSdkError {}
|
package/src/storage.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
import { ApiError } from './shared.js';
|
|
5
|
-
import { authHeaders, runtimeConfig } from './runtime.js';
|
|
6
|
-
|
|
7
|
-
export const MAX_UPLOAD_FILE_BYTES = 20 * 1024 * 1024;
|
|
8
|
-
|
|
9
|
-
async function storageConfig() {
|
|
10
|
-
return runtimeConfig({ environmentOverrideEnv: 'LICOS_STORAGE_SCOPE' });
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function query(config, params = {}) {
|
|
14
|
-
const search = new URLSearchParams();
|
|
15
|
-
search.set('projectId', config.projectId);
|
|
16
|
-
search.set('scope', config.environment);
|
|
17
|
-
for (const [key, value] of Object.entries(params)) {
|
|
18
|
-
if (value !== undefined && value !== null) search.set(key, String(value));
|
|
19
|
-
}
|
|
20
|
-
return search.toString();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function storageUrl(config, route, params) {
|
|
24
|
-
return `${config.baseUrl}/api/v1/studio/storage${route}?${query(config, params)}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function decodeResponse(response) {
|
|
28
|
-
const text = await response.text();
|
|
29
|
-
const payload = text ? JSON.parse(text) : null;
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
throw new ApiError(text || `platform storage API returned ${response.status}`, {
|
|
32
|
-
status: response.status,
|
|
33
|
-
details: payload,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
if (!payload || typeof payload !== 'object') return payload;
|
|
37
|
-
if ((payload.code !== undefined && payload.code !== 0) || payload.success === false) {
|
|
38
|
-
throw new ApiError(payload.message || 'platform storage API failed', {
|
|
39
|
-
status: response.status,
|
|
40
|
-
code: typeof payload.code === 'number' ? payload.code : undefined,
|
|
41
|
-
details: payload,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return payload.data;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async function requestJson(method, route, { params, body } = {}) {
|
|
48
|
-
const config = await storageConfig();
|
|
49
|
-
const response = await fetch(storageUrl(config, route, params), {
|
|
50
|
-
method,
|
|
51
|
-
headers: authHeaders(config),
|
|
52
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
53
|
-
});
|
|
54
|
-
return decodeResponse(response);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function filePart(input, options = {}) {
|
|
58
|
-
if (typeof input === 'string') {
|
|
59
|
-
const info = await stat(input);
|
|
60
|
-
ensureUploadSize(info.size);
|
|
61
|
-
const data = await readFile(input);
|
|
62
|
-
return {
|
|
63
|
-
blob: new Blob([data], { type: options.contentType || 'application/octet-stream' }),
|
|
64
|
-
fileName: options.fileName || path.basename(input),
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
if (input instanceof Blob) {
|
|
68
|
-
ensureUploadSize(input.size);
|
|
69
|
-
return { blob: input, fileName: options.fileName || 'file' };
|
|
70
|
-
}
|
|
71
|
-
if (input instanceof Uint8Array || Buffer.isBuffer(input)) {
|
|
72
|
-
ensureUploadSize(input.byteLength);
|
|
73
|
-
return {
|
|
74
|
-
blob: new Blob([input], { type: options.contentType || 'application/octet-stream' }),
|
|
75
|
-
fileName: options.fileName || 'file',
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
throw new TypeError('uploadFile input must be a file path, Blob, Buffer, or Uint8Array');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function ensureUploadSize(size) {
|
|
82
|
-
if (size > MAX_UPLOAD_FILE_BYTES) {
|
|
83
|
-
throw new RangeError(`uploadFile input exceeds max size of ${MAX_UPLOAD_FILE_BYTES} bytes`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export async function summary() {
|
|
88
|
-
return requestJson('GET', '/summary');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function listFolders() {
|
|
92
|
-
return (await requestJson('GET', '/folders')) || [];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function listEntries({ folderId } = {}) {
|
|
96
|
-
return requestJson('GET', '/entries', { params: { folderId } });
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function listFiles() {
|
|
100
|
-
return (await requestJson('GET', '/files')) || [];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export async function createFolder(folderName, { parentId } = {}) {
|
|
104
|
-
return requestJson('POST', '/folders', { body: { folderName, parentId } });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export async function renameFolder(folderId, folderName) {
|
|
108
|
-
return requestJson('PUT', `/folders/${encodeURIComponent(folderId)}`, { body: { folderName } });
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export async function deleteFolder(folderId) {
|
|
112
|
-
await requestJson('DELETE', `/folders/${encodeURIComponent(folderId)}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export async function uploadFile(input, options = {}) {
|
|
116
|
-
const { blob, fileName } = await filePart(input, options);
|
|
117
|
-
const config = await storageConfig();
|
|
118
|
-
const form = new FormData();
|
|
119
|
-
form.set('projectId', config.projectId);
|
|
120
|
-
form.set('scope', config.environment);
|
|
121
|
-
if (options.folderId) form.set('folderId', options.folderId);
|
|
122
|
-
form.set('file', blob, fileName);
|
|
123
|
-
const response = await fetch(`${config.baseUrl}/api/v1/studio/storage/files/upload`, {
|
|
124
|
-
method: 'POST',
|
|
125
|
-
headers: authHeaders(config, undefined),
|
|
126
|
-
body: form,
|
|
127
|
-
});
|
|
128
|
-
return decodeResponse(response);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export async function renameFile(fileId, fileName) {
|
|
132
|
-
return requestJson('PUT', `/files/${encodeURIComponent(fileId)}/rename`, { body: { fileName } });
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export async function moveFile(fileId, { folderId } = {}) {
|
|
136
|
-
return requestJson('PUT', `/files/${encodeURIComponent(fileId)}/move`, { body: { folderId } });
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export async function shareUrl(fileId, { expirySeconds } = {}) {
|
|
140
|
-
return requestJson('POST', `/files/${encodeURIComponent(fileId)}/share-url`, {
|
|
141
|
-
body: { expirySeconds },
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export async function objectExists({ fileId, objectKey } = {}) {
|
|
146
|
-
return requestJson('POST', '/objects/exists', { body: { fileId, objectKey } });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export async function deleteFile(fileId) {
|
|
150
|
-
await requestJson('DELETE', `/files/${encodeURIComponent(fileId)}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export const storage = {
|
|
154
|
-
summary,
|
|
155
|
-
listFolders,
|
|
156
|
-
listEntries,
|
|
157
|
-
listFiles,
|
|
158
|
-
createFolder,
|
|
159
|
-
renameFolder,
|
|
160
|
-
deleteFolder,
|
|
161
|
-
uploadFile,
|
|
162
|
-
renameFile,
|
|
163
|
-
moveFile,
|
|
164
|
-
shareUrl,
|
|
165
|
-
objectExists,
|
|
166
|
-
deleteFile,
|
|
167
|
-
};
|
|
File without changes
|