@simpleplatform/sdk 1.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.
- package/LICENSE +201 -0
- package/README.md +309 -0
- package/dist/ai.d.ts +239 -0
- package/dist/ai.js +265 -0
- package/dist/build.js +161 -0
- package/dist/graphql.d.ts +33 -0
- package/dist/graphql.js +56 -0
- package/dist/host.d.ts +28 -0
- package/dist/host.js +148 -0
- package/dist/http.d.ts +26 -0
- package/dist/http.js +42 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +165 -0
- package/dist/internal/global.d.ts +9 -0
- package/dist/internal/global.js +29 -0
- package/dist/internal/memory.d.ts +103 -0
- package/dist/internal/memory.js +152 -0
- package/dist/internal/polyfills.d.ts +52 -0
- package/dist/internal/polyfills.js +150 -0
- package/dist/security.d.ts +174 -0
- package/dist/security.js +60 -0
- package/dist/settings.d.ts +13 -0
- package/dist/settings.js +25 -0
- package/dist/storage.d.ts +34 -0
- package/dist/storage.js +72 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.js +1 -0
- package/dist/worker-override.js +86 -0
- package/package.json +55 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves application settings for the specified keys.
|
|
4
|
+
* This function communicates with the host system's settings action and returns
|
|
5
|
+
* a map of the requested settings.
|
|
6
|
+
*
|
|
7
|
+
* @param appId The application identifier for which to retrieve settings.
|
|
8
|
+
* @param keys An array of setting keys to retrieve.
|
|
9
|
+
* @param context The execution context.
|
|
10
|
+
* @returns A promise that resolves with a map containing the requested settings.
|
|
11
|
+
* @throws Will throw an error if the request fails or the host returns an error.
|
|
12
|
+
*/
|
|
13
|
+
export declare function get(appId: string, keys: string[], context: Context): Promise<Record<string, any>>;
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { execute as hostExecute } from './host';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves application settings for the specified keys.
|
|
4
|
+
* This function communicates with the host system's settings action and returns
|
|
5
|
+
* a map of the requested settings.
|
|
6
|
+
*
|
|
7
|
+
* @param appId The application identifier for which to retrieve settings.
|
|
8
|
+
* @param keys An array of setting keys to retrieve.
|
|
9
|
+
* @param context The execution context.
|
|
10
|
+
* @returns A promise that resolves with a map containing the requested settings.
|
|
11
|
+
* @throws Will throw an error if the request fails or the host returns an error.
|
|
12
|
+
*/
|
|
13
|
+
export async function get(appId, keys, context) {
|
|
14
|
+
if (!appId) {
|
|
15
|
+
throw new Error('appId is required for settings retrieval');
|
|
16
|
+
}
|
|
17
|
+
if (!keys || keys.length === 0) {
|
|
18
|
+
throw new Error('setting keys are required for settings retrieval');
|
|
19
|
+
}
|
|
20
|
+
const response = await hostExecute('action:settings/get', { app_id: appId, keys }, context);
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
throw new Error(response.error?.message ?? 'Settings retrieval failed');
|
|
23
|
+
}
|
|
24
|
+
return response.data;
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Context, DocumentHandle, ExternalFileSource, StorageTarget } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Uploads a file from an external URL to the platform's storage system.
|
|
4
|
+
*
|
|
5
|
+
* This function downloads a file from the specified external source and uploads it
|
|
6
|
+
* to the target location in the platform's storage. The file is content-addressed
|
|
7
|
+
* using SHA-256 hashing, enabling automatic deduplication.
|
|
8
|
+
*
|
|
9
|
+
* @param source The external file source configuration including URL and optional authentication.
|
|
10
|
+
* @param target The target location where the file should be stored.
|
|
11
|
+
* @param context The execution context for the request.
|
|
12
|
+
* @returns A promise that resolves with a DocumentHandle containing file metadata.
|
|
13
|
+
* @throws Will throw an error if validation fails or the upload operation fails.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const handle = await uploadExternal(
|
|
18
|
+
* {
|
|
19
|
+
* url: 'https://example.com/document.pdf',
|
|
20
|
+
* auth: {
|
|
21
|
+
* type: 'bearer',
|
|
22
|
+
* bearer_token: 'your-token-here'
|
|
23
|
+
* }
|
|
24
|
+
* },
|
|
25
|
+
* {
|
|
26
|
+
* app_id: 'dev.simple.system',
|
|
27
|
+
* table_name: 'documents',
|
|
28
|
+
* field_name: 'attachment'
|
|
29
|
+
* },
|
|
30
|
+
* context
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function uploadExternal(source: ExternalFileSource, target: StorageTarget, context: Context): Promise<DocumentHandle>;
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { execute as hostExecute } from './host';
|
|
2
|
+
/**
|
|
3
|
+
* Uploads a file from an external URL to the platform's storage system.
|
|
4
|
+
*
|
|
5
|
+
* This function downloads a file from the specified external source and uploads it
|
|
6
|
+
* to the target location in the platform's storage. The file is content-addressed
|
|
7
|
+
* using SHA-256 hashing, enabling automatic deduplication.
|
|
8
|
+
*
|
|
9
|
+
* @param source The external file source configuration including URL and optional authentication.
|
|
10
|
+
* @param target The target location where the file should be stored.
|
|
11
|
+
* @param context The execution context for the request.
|
|
12
|
+
* @returns A promise that resolves with a DocumentHandle containing file metadata.
|
|
13
|
+
* @throws Will throw an error if validation fails or the upload operation fails.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const handle = await uploadExternal(
|
|
18
|
+
* {
|
|
19
|
+
* url: 'https://example.com/document.pdf',
|
|
20
|
+
* auth: {
|
|
21
|
+
* type: 'bearer',
|
|
22
|
+
* bearer_token: 'your-token-here'
|
|
23
|
+
* }
|
|
24
|
+
* },
|
|
25
|
+
* {
|
|
26
|
+
* app_id: 'dev.simple.system',
|
|
27
|
+
* table_name: 'documents',
|
|
28
|
+
* field_name: 'attachment'
|
|
29
|
+
* },
|
|
30
|
+
* context
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export async function uploadExternal(source, target, context) {
|
|
35
|
+
// Validate source
|
|
36
|
+
if (!source.url || source.url.trim() === '') {
|
|
37
|
+
throw new Error('Source URL is required and cannot be empty');
|
|
38
|
+
}
|
|
39
|
+
// Validate target
|
|
40
|
+
if (!target.app_id || target.app_id.trim() === '') {
|
|
41
|
+
throw new Error('Target app_id is required and cannot be empty');
|
|
42
|
+
}
|
|
43
|
+
if (!target.table_name || target.table_name.trim() === '') {
|
|
44
|
+
throw new Error('Target table_name is required and cannot be empty');
|
|
45
|
+
}
|
|
46
|
+
if (!target.field_name || target.field_name.trim() === '') {
|
|
47
|
+
throw new Error('Target field_name is required and cannot be empty');
|
|
48
|
+
}
|
|
49
|
+
// Validate auth if provided
|
|
50
|
+
if (source.auth) {
|
|
51
|
+
if (source.auth.type !== 'basic' && source.auth.type !== 'bearer') {
|
|
52
|
+
throw new Error('Auth type must be either "basic" or "bearer"');
|
|
53
|
+
}
|
|
54
|
+
if (source.auth.type === 'bearer' && (!source.auth.bearer_token || source.auth.bearer_token.trim() === '')) {
|
|
55
|
+
throw new Error('Bearer token is required when auth type is "bearer"');
|
|
56
|
+
}
|
|
57
|
+
if (source.auth.type === 'basic') {
|
|
58
|
+
if (!source.auth.username || source.auth.username.trim() === '') {
|
|
59
|
+
throw new Error('Username is required when auth type is "basic"');
|
|
60
|
+
}
|
|
61
|
+
if (!source.auth.password || source.auth.password.trim() === '') {
|
|
62
|
+
throw new Error('Password is required when auth type is "basic"');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Call the host function
|
|
67
|
+
const response = await hostExecute('action:storage/upload-external', { source, target }, context);
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
throw new Error(response.error?.message ?? 'External file upload failed');
|
|
70
|
+
}
|
|
71
|
+
return response.data;
|
|
72
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** The complete execution context for an action. */
|
|
2
|
+
export interface Context {
|
|
3
|
+
logic: Logic;
|
|
4
|
+
tenant: Tenant;
|
|
5
|
+
user: User;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Represents the metadata handle for a file securely stored in the platform.
|
|
9
|
+
* This JSON object is the "pointer" to the file and is stored in `:document` fields.
|
|
10
|
+
*/
|
|
11
|
+
export interface DocumentHandle {
|
|
12
|
+
/** The SHA-256 hash of the file content, used as the unique content-addressable key. */
|
|
13
|
+
file_hash: string;
|
|
14
|
+
/** The original name of the file when it was uploaded. */
|
|
15
|
+
filename: string;
|
|
16
|
+
/** The type of the file, e.g., "application/pdf". */
|
|
17
|
+
mime_type: string;
|
|
18
|
+
/** The size of the file in bytes. */
|
|
19
|
+
size: number;
|
|
20
|
+
/** The storage path where the file is stored. */
|
|
21
|
+
storage_path: string;
|
|
22
|
+
}
|
|
23
|
+
/** Represents the source configuration for downloading an external file. */
|
|
24
|
+
export interface ExternalFileSource {
|
|
25
|
+
/** Optional authentication configuration for accessing the external file. */
|
|
26
|
+
auth?: {
|
|
27
|
+
/** Bearer token for bearer authentication. */
|
|
28
|
+
bearer_token?: string;
|
|
29
|
+
/** Password for basic authentication. */
|
|
30
|
+
password?: string;
|
|
31
|
+
/** The type of authentication to use. */
|
|
32
|
+
type: 'basic' | 'bearer';
|
|
33
|
+
/** Username for basic authentication. */
|
|
34
|
+
username?: string;
|
|
35
|
+
};
|
|
36
|
+
/** The URL of the external file to download. */
|
|
37
|
+
url: string;
|
|
38
|
+
}
|
|
39
|
+
/** Contains metadata about the specific logic execution. */
|
|
40
|
+
export interface Logic {
|
|
41
|
+
execution_env: string;
|
|
42
|
+
execution_id: string;
|
|
43
|
+
id: string;
|
|
44
|
+
trigger_id: string;
|
|
45
|
+
}
|
|
46
|
+
/** Error structure for host communication responses. */
|
|
47
|
+
export interface SimpleError {
|
|
48
|
+
message: string;
|
|
49
|
+
reasons?: string[];
|
|
50
|
+
}
|
|
51
|
+
/** The low-level request structure sent by the host to an action. */
|
|
52
|
+
export interface SimpleRequest {
|
|
53
|
+
context: Context;
|
|
54
|
+
data?: string;
|
|
55
|
+
headers: Record<string, any>;
|
|
56
|
+
}
|
|
57
|
+
/** The low-level response structure for host communication. */
|
|
58
|
+
export interface SimpleResponse<T = any> {
|
|
59
|
+
data?: T;
|
|
60
|
+
error?: SimpleError;
|
|
61
|
+
ok: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Represents the target location for storing an uploaded file. */
|
|
64
|
+
export interface StorageTarget {
|
|
65
|
+
/** The application ID where the file will be stored. */
|
|
66
|
+
app_id: string;
|
|
67
|
+
/** The field name where the DocumentHandle will be stored. */
|
|
68
|
+
field_name: string;
|
|
69
|
+
/** The table name where the record exists. */
|
|
70
|
+
table_name: string;
|
|
71
|
+
}
|
|
72
|
+
/** Represents tenant information in the execution context. */
|
|
73
|
+
export interface Tenant {
|
|
74
|
+
host?: string;
|
|
75
|
+
id?: string;
|
|
76
|
+
name: string;
|
|
77
|
+
}
|
|
78
|
+
/** Represents user information in the execution context. */
|
|
79
|
+
export interface User {
|
|
80
|
+
id?: string;
|
|
81
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SDK Worker Override Module.
|
|
3
|
+
* This file exports worker-compatible implementations of `execute` and
|
|
4
|
+
* `executeAsync`. The SDK's build tool will use esbuild's `alias` feature
|
|
5
|
+
* to replace the original `@simple/sdk/host` module with this one during
|
|
6
|
+
* the async application build.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// State and listeners are sandboxed within this module's closure.
|
|
10
|
+
const pendingHostRequests = new Map()
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line no-restricted-globals
|
|
13
|
+
self.addEventListener('message', (event) => {
|
|
14
|
+
const message = event && event.data
|
|
15
|
+
if (
|
|
16
|
+
typeof message !== 'object'
|
|
17
|
+
|| message === null
|
|
18
|
+
|| message.type !== 'host_response'
|
|
19
|
+
) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const pending = pendingHostRequests.get(message.requestId)
|
|
24
|
+
if (!pending)
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
message.response.ok
|
|
28
|
+
? pending.resolve(message.response)
|
|
29
|
+
: pending.reject(new Error(message.response.error ?? 'Unknown host error'))
|
|
30
|
+
|
|
31
|
+
pendingHostRequests.delete(message.requestId)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Worker-compatible implementation that returns a Promise and uses postMessage.
|
|
36
|
+
* @returns {Promise<import('./types').SimpleResponse<any>>} A promise that resolves with the host response
|
|
37
|
+
*/
|
|
38
|
+
export function execute(actionName, params, context) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const requestId = crypto.randomUUID()
|
|
41
|
+
pendingHostRequests.set(requestId, { reject, resolve })
|
|
42
|
+
|
|
43
|
+
const hostRequest = {
|
|
44
|
+
context,
|
|
45
|
+
executionId: context.logic.execution_id,
|
|
46
|
+
name: actionName,
|
|
47
|
+
params,
|
|
48
|
+
type: 'hostRequest',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// eslint-disable-next-line no-restricted-globals
|
|
52
|
+
self.postMessage({
|
|
53
|
+
request: hostRequest,
|
|
54
|
+
requestId,
|
|
55
|
+
type: 'host_request',
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Worker-compatible fire-and-forget implementation.
|
|
62
|
+
*/
|
|
63
|
+
export function executeAsync(actionName, params, context) {
|
|
64
|
+
const hostRequest = {
|
|
65
|
+
context,
|
|
66
|
+
executionId: context.logic.execution_id,
|
|
67
|
+
name: actionName,
|
|
68
|
+
params,
|
|
69
|
+
type: 'hostRequest',
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// eslint-disable-next-line no-restricted-globals
|
|
73
|
+
self.postMessage({
|
|
74
|
+
request: hostRequest,
|
|
75
|
+
type: 'host_cast',
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* This module replaces host.ts, which also exports getContext.
|
|
81
|
+
* We provide a stub here, as it's not used in the worker context.
|
|
82
|
+
*/
|
|
83
|
+
export function getContext() {
|
|
84
|
+
console.warn('getContext() was called in a script worker context, which is not supported.')
|
|
85
|
+
return new Uint8Array(0)
|
|
86
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@simpleplatform/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Simple Platform Typescript SDK",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"default": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./ai": {
|
|
11
|
+
"types": "./dist/ai.d.ts",
|
|
12
|
+
"default": "./dist/ai.js"
|
|
13
|
+
},
|
|
14
|
+
"./graphql": {
|
|
15
|
+
"types": "./dist/graphql.d.ts",
|
|
16
|
+
"default": "./dist/graphql.js"
|
|
17
|
+
},
|
|
18
|
+
"./http": {
|
|
19
|
+
"types": "./dist/http.d.ts",
|
|
20
|
+
"default": "./dist/http.js"
|
|
21
|
+
},
|
|
22
|
+
"./settings": {
|
|
23
|
+
"types": "./dist/settings.d.ts",
|
|
24
|
+
"default": "./dist/settings.js"
|
|
25
|
+
},
|
|
26
|
+
"./security": {
|
|
27
|
+
"types": "./dist/security.d.ts",
|
|
28
|
+
"default": "./dist/security.js"
|
|
29
|
+
},
|
|
30
|
+
"./host": {
|
|
31
|
+
"types": "./dist/host.d.ts",
|
|
32
|
+
"default": "./dist/host.js"
|
|
33
|
+
},
|
|
34
|
+
"./worker": "./dist/worker-override.js",
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"main": "dist/index.js",
|
|
38
|
+
"types": "dist/index.d.ts",
|
|
39
|
+
"bin": {
|
|
40
|
+
"simple-sdk-build": "./dist/build.js"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"esbuild": "0.27.2"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "25.0.3",
|
|
50
|
+
"typescript": "5.9.3"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "rm -rf dist && tsc && cp src/worker-override.js dist/ && cp cli/build.js dist/"
|
|
54
|
+
}
|
|
55
|
+
}
|