@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,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WebAssembly Memory Management Module
|
|
3
|
+
*
|
|
4
|
+
* Provides a high-level interface for managing WebAssembly linear memory operations.
|
|
5
|
+
* This module handles string-based data exchange between JavaScript and the WASM
|
|
6
|
+
* runtime through direct UTF-8 operations, avoiding unnecessary serialization overhead.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture
|
|
9
|
+
*
|
|
10
|
+
* The memory bridge operates on two main principles:
|
|
11
|
+
* - **Direct String Operations**: Strings are passed directly between JS and WASM
|
|
12
|
+
* - **UTF-8 Encoding**: All string data is handled as UTF-8 encoded bytes
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Allocate memory for a string
|
|
18
|
+
* const [ptr, len] = stringToPtr("Hello, World!")
|
|
19
|
+
*
|
|
20
|
+
* // Read data back from memory
|
|
21
|
+
* const data = readBufferSlice(ptr, len)
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
/** Reusable TextDecoder instance for UTF-8 string decoding. */
|
|
25
|
+
export declare const decoder: TextDecoder;
|
|
26
|
+
/**
|
|
27
|
+
* Allocates a block of memory within the WebAssembly linear memory space.
|
|
28
|
+
*
|
|
29
|
+
* This function provides the primary interface for requesting memory from
|
|
30
|
+
* the WASM module's allocator. The returned pointer can be used for
|
|
31
|
+
* subsequent read/write operations.
|
|
32
|
+
*
|
|
33
|
+
* @param size - Number of bytes to allocate
|
|
34
|
+
* @returns Memory pointer (offset) to the allocated block
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const ptr = allocate(1024) // Allocate 1KB
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function allocate(size: number): number;
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param ptr - Memory pointer to deallocate
|
|
45
|
+
* @param size - Number of bytes to deallocate
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* deallocate(ptr, 1024) // Deallocate 1KB
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function deallocate(ptr: number, size: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Reads string data from WebAssembly memory and returns it as UTF-8 bytes.
|
|
55
|
+
*
|
|
56
|
+
* This function provides a safe interface for reading string data from
|
|
57
|
+
* WASM memory, with proper error handling and fallback behavior.
|
|
58
|
+
*
|
|
59
|
+
* @param ptr - Memory pointer to read from
|
|
60
|
+
* @param len - Number of bytes to read
|
|
61
|
+
* @returns UTF-8 encoded bytes of the string data
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const data = readBufferSlice(ptr, len)
|
|
66
|
+
* const text = decoder.decode(data) // Convert back to string
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function readBufferSlice(ptr: number, len: number): Uint8Array;
|
|
70
|
+
/**
|
|
71
|
+
* Reads a string directly from WebAssembly memory.
|
|
72
|
+
*
|
|
73
|
+
* This is a convenience function that combines memory reading and UTF-8
|
|
74
|
+
* decoding in a single operation.
|
|
75
|
+
*
|
|
76
|
+
* @param ptr - Memory pointer to read from
|
|
77
|
+
* @param len - Number of bytes to read
|
|
78
|
+
* @returns The decoded UTF-8 string
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const text = readString(ptr, len)
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function readString(ptr: number, len: number): string;
|
|
86
|
+
/**
|
|
87
|
+
* Writes a JavaScript string to WebAssembly memory and returns its location.
|
|
88
|
+
*
|
|
89
|
+
* This function handles the complete process of:
|
|
90
|
+
* 1. Calculating the UTF-8 byte length of the string
|
|
91
|
+
* 2. Allocating sufficient memory in the WASM linear memory
|
|
92
|
+
* 3. Writing the string data to the allocated location
|
|
93
|
+
*
|
|
94
|
+
* @param str - The string to write to memory
|
|
95
|
+
* @returns A tuple containing [pointer, byte_length]
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const [ptr, len] = stringToPtr("Hello, World!")
|
|
100
|
+
* // ptr points to the string data, len is the byte length
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function stringToPtr(str: string): [number, number];
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WebAssembly Memory Management Module
|
|
3
|
+
*
|
|
4
|
+
* Provides a high-level interface for managing WebAssembly linear memory operations.
|
|
5
|
+
* This module handles string-based data exchange between JavaScript and the WASM
|
|
6
|
+
* runtime through direct UTF-8 operations, avoiding unnecessary serialization overhead.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture
|
|
9
|
+
*
|
|
10
|
+
* The memory bridge operates on two main principles:
|
|
11
|
+
* - **Direct String Operations**: Strings are passed directly between JS and WASM
|
|
12
|
+
* - **UTF-8 Encoding**: All string data is handled as UTF-8 encoded bytes
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Allocate memory for a string
|
|
18
|
+
* const [ptr, len] = stringToPtr("Hello, World!")
|
|
19
|
+
*
|
|
20
|
+
* // Read data back from memory
|
|
21
|
+
* const data = readBufferSlice(ptr, len)
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// TEXT ENCODING UTILITIES
|
|
26
|
+
// =============================================================================
|
|
27
|
+
/** Reusable TextEncoder instance for UTF-8 string encoding. */
|
|
28
|
+
const encoder = new TextEncoder();
|
|
29
|
+
/** Reusable TextDecoder instance for UTF-8 string decoding. */
|
|
30
|
+
export const decoder = new TextDecoder('utf-8');
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// MEMORY ALLOCATION
|
|
33
|
+
// =============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Allocates a block of memory within the WebAssembly linear memory space.
|
|
36
|
+
*
|
|
37
|
+
* This function provides the primary interface for requesting memory from
|
|
38
|
+
* the WASM module's allocator. The returned pointer can be used for
|
|
39
|
+
* subsequent read/write operations.
|
|
40
|
+
*
|
|
41
|
+
* @param size - Number of bytes to allocate
|
|
42
|
+
* @returns Memory pointer (offset) to the allocated block
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const ptr = allocate(1024) // Allocate 1KB
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function allocate(size) {
|
|
50
|
+
return __wasm.alloc(size);
|
|
51
|
+
}
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// STRING MEMORY OPERATIONS
|
|
54
|
+
// =============================================================================
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param ptr - Memory pointer to deallocate
|
|
58
|
+
* @param size - Number of bytes to deallocate
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* deallocate(ptr, 1024) // Deallocate 1KB
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function deallocate(ptr, size) {
|
|
66
|
+
__wasm.dealloc(ptr, size);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Reads string data from WebAssembly memory and returns it as UTF-8 bytes.
|
|
70
|
+
*
|
|
71
|
+
* This function provides a safe interface for reading string data from
|
|
72
|
+
* WASM memory, with proper error handling and fallback behavior.
|
|
73
|
+
*
|
|
74
|
+
* @param ptr - Memory pointer to read from
|
|
75
|
+
* @param len - Number of bytes to read
|
|
76
|
+
* @returns UTF-8 encoded bytes of the string data
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const data = readBufferSlice(ptr, len)
|
|
81
|
+
* const text = decoder.decode(data) // Convert back to string
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function readBufferSlice(ptr, len) {
|
|
85
|
+
if (len === 0) {
|
|
86
|
+
return new Uint8Array(0);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const str = __wasm.read_string(ptr, len);
|
|
90
|
+
return encoder.encode(str);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(`Memory read failed at ptr=${ptr}, len=${len}:`, error);
|
|
94
|
+
return new Uint8Array(0);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// =============================================================================
|
|
98
|
+
// UTILITY FUNCTIONS
|
|
99
|
+
// =============================================================================
|
|
100
|
+
/**
|
|
101
|
+
* Reads a string directly from WebAssembly memory.
|
|
102
|
+
*
|
|
103
|
+
* This is a convenience function that combines memory reading and UTF-8
|
|
104
|
+
* decoding in a single operation.
|
|
105
|
+
*
|
|
106
|
+
* @param ptr - Memory pointer to read from
|
|
107
|
+
* @param len - Number of bytes to read
|
|
108
|
+
* @returns The decoded UTF-8 string
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const text = readString(ptr, len)
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function readString(ptr, len) {
|
|
116
|
+
if (len === 0) {
|
|
117
|
+
return '';
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
return __wasm.read_string(ptr, len);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error(`String read failed at ptr=${ptr}, len=${len}:`, error);
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Writes a JavaScript string to WebAssembly memory and returns its location.
|
|
129
|
+
*
|
|
130
|
+
* This function handles the complete process of:
|
|
131
|
+
* 1. Calculating the UTF-8 byte length of the string
|
|
132
|
+
* 2. Allocating sufficient memory in the WASM linear memory
|
|
133
|
+
* 3. Writing the string data to the allocated location
|
|
134
|
+
*
|
|
135
|
+
* @param str - The string to write to memory
|
|
136
|
+
* @returns A tuple containing [pointer, byte_length]
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const [ptr, len] = stringToPtr("Hello, World!")
|
|
141
|
+
* // ptr points to the string data, len is the byte length
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export function stringToPtr(str) {
|
|
145
|
+
if (str.length === 0) {
|
|
146
|
+
return [allocate(0), 0];
|
|
147
|
+
}
|
|
148
|
+
const bytes = encoder.encode(str);
|
|
149
|
+
const ptr = allocate(bytes.length);
|
|
150
|
+
__wasm.write_string(ptr, str);
|
|
151
|
+
return [ptr, bytes.length];
|
|
152
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Provides robust, production-quality polyfills for TextEncoder and TextDecoder.
|
|
3
|
+
* The logic is adapted from a public-domain UTF-8 implementation to ensure correctness
|
|
4
|
+
* and full Unicode support, including surrogate pairs.
|
|
5
|
+
*
|
|
6
|
+
* The Javy runtime has partial/non-compliant support for these APIs, so providing
|
|
7
|
+
* our own implementation makes the SDK self-sufficient and guarantees identical
|
|
8
|
+
* behavior in all environments (server and browser).
|
|
9
|
+
*/
|
|
10
|
+
export declare class TextDecoder {
|
|
11
|
+
/**
|
|
12
|
+
* The encoding supported by this polyfill, which is always "utf-8".
|
|
13
|
+
* This read-only property is required for full API compliance with TypeScript's built-in types.
|
|
14
|
+
*/
|
|
15
|
+
readonly encoding = "utf-8";
|
|
16
|
+
/**
|
|
17
|
+
* The `fatal` option is not supported by this polyfill but is required for API compliance.
|
|
18
|
+
*/
|
|
19
|
+
readonly fatal = false;
|
|
20
|
+
/**
|
|
21
|
+
* The `ignoreBOM` option is not supported by this polyfill but is required for API compliance.
|
|
22
|
+
*/
|
|
23
|
+
readonly ignoreBOM = false;
|
|
24
|
+
/**
|
|
25
|
+
* Decodes a Uint8Array containing UTF-8 bytes into a JavaScript string.
|
|
26
|
+
* @param octets The byte array to decode.
|
|
27
|
+
* @returns The decoded string.
|
|
28
|
+
*/
|
|
29
|
+
decode(octets: Uint8Array): string;
|
|
30
|
+
}
|
|
31
|
+
export declare class TextEncoder {
|
|
32
|
+
/**
|
|
33
|
+
* The encoding supported by this polyfill, which is always "utf-8".
|
|
34
|
+
* This read-only property is required for full API compliance with TypeScript's built-in types.
|
|
35
|
+
*/
|
|
36
|
+
readonly encoding = "utf-8";
|
|
37
|
+
/**
|
|
38
|
+
* Encodes a JavaScript string into a UTF-8 encoded Uint8Array.
|
|
39
|
+
* @param str The string to encode.
|
|
40
|
+
* @returns A Uint8Array containing the UTF-8 bytes.
|
|
41
|
+
*/
|
|
42
|
+
encode(str: string): Uint8Array;
|
|
43
|
+
/**
|
|
44
|
+
* An implementation of the `encodeInto` method for API compliance.
|
|
45
|
+
* Our SDK does not use this performance-optimization method, so this is
|
|
46
|
+
* a minimal, correct stub that performs a simple encode and copy.
|
|
47
|
+
*/
|
|
48
|
+
encodeInto(str: string, destination: Uint8Array): {
|
|
49
|
+
read: number;
|
|
50
|
+
written: number;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Provides robust, production-quality polyfills for TextEncoder and TextDecoder.
|
|
3
|
+
* The logic is adapted from a public-domain UTF-8 implementation to ensure correctness
|
|
4
|
+
* and full Unicode support, including surrogate pairs.
|
|
5
|
+
*
|
|
6
|
+
* The Javy runtime has partial/non-compliant support for these APIs, so providing
|
|
7
|
+
* our own implementation makes the SDK self-sufficient and guarantees identical
|
|
8
|
+
* behavior in all environments (server and browser).
|
|
9
|
+
*/
|
|
10
|
+
// To the extent possible under law, the author(s) have dedicated all copyright and related
|
|
11
|
+
// and neighboring rights to this software to the public domain worldwide. This software
|
|
12
|
+
// is distributed without any warranty.
|
|
13
|
+
// You should have received a copy of the CC0 Public Domain Dedication along with this
|
|
14
|
+
// software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
15
|
+
export class TextDecoder {
|
|
16
|
+
constructor() {
|
|
17
|
+
/**
|
|
18
|
+
* The encoding supported by this polyfill, which is always "utf-8".
|
|
19
|
+
* This read-only property is required for full API compliance with TypeScript's built-in types.
|
|
20
|
+
*/
|
|
21
|
+
this.encoding = 'utf-8';
|
|
22
|
+
/**
|
|
23
|
+
* The `fatal` option is not supported by this polyfill but is required for API compliance.
|
|
24
|
+
*/
|
|
25
|
+
this.fatal = false;
|
|
26
|
+
/**
|
|
27
|
+
* The `ignoreBOM` option is not supported by this polyfill but is required for API compliance.
|
|
28
|
+
*/
|
|
29
|
+
this.ignoreBOM = false;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Decodes a Uint8Array containing UTF-8 bytes into a JavaScript string.
|
|
33
|
+
* @param octets The byte array to decode.
|
|
34
|
+
* @returns The decoded string.
|
|
35
|
+
*/
|
|
36
|
+
decode(octets) {
|
|
37
|
+
let string = '';
|
|
38
|
+
let i = 0;
|
|
39
|
+
while (i < octets.length) {
|
|
40
|
+
let octet = octets[i];
|
|
41
|
+
let bytesNeeded = 0;
|
|
42
|
+
let codePoint = 0;
|
|
43
|
+
if (octet <= 0x7F) {
|
|
44
|
+
bytesNeeded = 0;
|
|
45
|
+
codePoint = octet & 0xFF;
|
|
46
|
+
}
|
|
47
|
+
else if (octet <= 0xDF) {
|
|
48
|
+
bytesNeeded = 1;
|
|
49
|
+
codePoint = octet & 0x1F;
|
|
50
|
+
}
|
|
51
|
+
else if (octet <= 0xEF) {
|
|
52
|
+
bytesNeeded = 2;
|
|
53
|
+
codePoint = octet & 0x0F;
|
|
54
|
+
}
|
|
55
|
+
else if (octet <= 0xF4) {
|
|
56
|
+
bytesNeeded = 3;
|
|
57
|
+
codePoint = octet & 0x07;
|
|
58
|
+
}
|
|
59
|
+
if (octets.length - i - bytesNeeded > 0) {
|
|
60
|
+
let k = 0;
|
|
61
|
+
while (k < bytesNeeded) {
|
|
62
|
+
octet = octets[i + k + 1];
|
|
63
|
+
codePoint = (codePoint << 6) | (octet & 0x3F);
|
|
64
|
+
k += 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// In case of a truncated multi-byte sequence, substitute with a replacement character.
|
|
69
|
+
codePoint = 0xFFFD;
|
|
70
|
+
bytesNeeded = octets.length - i;
|
|
71
|
+
}
|
|
72
|
+
// `String.fromCodePoint` is the modern, correct way to handle code points
|
|
73
|
+
// that may be outside the BMP.
|
|
74
|
+
string += String.fromCodePoint(codePoint);
|
|
75
|
+
i += bytesNeeded + 1;
|
|
76
|
+
}
|
|
77
|
+
return string;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export class TextEncoder {
|
|
81
|
+
constructor() {
|
|
82
|
+
/**
|
|
83
|
+
* The encoding supported by this polyfill, which is always "utf-8".
|
|
84
|
+
* This read-only property is required for full API compliance with TypeScript's built-in types.
|
|
85
|
+
*/
|
|
86
|
+
this.encoding = 'utf-8';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Encodes a JavaScript string into a UTF-8 encoded Uint8Array.
|
|
90
|
+
* @param str The string to encode.
|
|
91
|
+
* @returns A Uint8Array containing the UTF-8 bytes.
|
|
92
|
+
*/
|
|
93
|
+
encode(str) {
|
|
94
|
+
const octets = [];
|
|
95
|
+
const length = str.length;
|
|
96
|
+
let i = 0;
|
|
97
|
+
while (i < length) {
|
|
98
|
+
// The `codePointAt` method is essential for correctly handling characters
|
|
99
|
+
// outside the Basic Multilingual Plane (like many emojis).
|
|
100
|
+
const codePoint = str.codePointAt(i);
|
|
101
|
+
let c = 0;
|
|
102
|
+
let bits = 0;
|
|
103
|
+
if (codePoint <= 0x0000007F) {
|
|
104
|
+
c = 0;
|
|
105
|
+
bits = 0x00;
|
|
106
|
+
}
|
|
107
|
+
else if (codePoint <= 0x000007FF) {
|
|
108
|
+
c = 6;
|
|
109
|
+
bits = 0xC0;
|
|
110
|
+
}
|
|
111
|
+
else if (codePoint <= 0x0000FFFF) {
|
|
112
|
+
c = 12;
|
|
113
|
+
bits = 0xE0;
|
|
114
|
+
}
|
|
115
|
+
else if (codePoint <= 0x001FFFFF) {
|
|
116
|
+
c = 18;
|
|
117
|
+
bits = 0xF0;
|
|
118
|
+
}
|
|
119
|
+
octets.push(bits | (codePoint >> c));
|
|
120
|
+
c -= 6;
|
|
121
|
+
while (c >= 0) {
|
|
122
|
+
octets.push(0x80 | ((codePoint >> c) & 0x3F));
|
|
123
|
+
c -= 6;
|
|
124
|
+
}
|
|
125
|
+
// Advance by 2 if it was a surrogate pair, otherwise 1.
|
|
126
|
+
i += codePoint >= 0x10000 ? 2 : 1;
|
|
127
|
+
}
|
|
128
|
+
// The native API returns a Uint8Array, so we do the same for compatibility.
|
|
129
|
+
return new Uint8Array(octets);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* An implementation of the `encodeInto` method for API compliance.
|
|
133
|
+
* Our SDK does not use this performance-optimization method, so this is
|
|
134
|
+
* a minimal, correct stub that performs a simple encode and copy.
|
|
135
|
+
*/
|
|
136
|
+
encodeInto(str, destination) {
|
|
137
|
+
const bytes = this.encode(str);
|
|
138
|
+
const written = Math.min(bytes.length, destination.length);
|
|
139
|
+
destination.set(bytes.subarray(0, written));
|
|
140
|
+
// A true implementation would need to correctly calculate how many source
|
|
141
|
+
// characters were read to produce the written bytes. For our non-blocking
|
|
142
|
+
// SDK, this simplified stub is sufficient and safe.
|
|
143
|
+
let read = str.length;
|
|
144
|
+
if (bytes.length > destination.length) {
|
|
145
|
+
// A simplistic reverse-calculation if truncated.
|
|
146
|
+
read = new TextDecoder().decode(destination).length;
|
|
147
|
+
}
|
|
148
|
+
return { read, written };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Simple Platform Security SDK
|
|
3
|
+
*
|
|
4
|
+
* This module provides the global-style, fluent API for authoring security policies
|
|
5
|
+
* in a standard JavaScript (`.js`) file. It is designed to be executed by the
|
|
6
|
+
* platform's "Smart Compiler" (a Record Behavior) to produce a declarative
|
|
7
|
+
* JSON artifact.
|
|
8
|
+
*/
|
|
9
|
+
export type FilterCondition = Record<string, any>;
|
|
10
|
+
export interface Grant {
|
|
11
|
+
'*'?: boolean | Rule | Rule[];
|
|
12
|
+
'aggregate'?: {
|
|
13
|
+
allow?: {
|
|
14
|
+
avg?: boolean | string[];
|
|
15
|
+
count?: boolean;
|
|
16
|
+
max?: boolean | string[];
|
|
17
|
+
min?: boolean | string[];
|
|
18
|
+
sum?: boolean | string[];
|
|
19
|
+
};
|
|
20
|
+
allowRawData?: boolean;
|
|
21
|
+
filter?: Rule | Rule[];
|
|
22
|
+
};
|
|
23
|
+
'create'?: boolean | Rule | Rule[];
|
|
24
|
+
'delete'?: boolean | Rule | Rule[];
|
|
25
|
+
'edit'?: boolean | Rule | Rule[];
|
|
26
|
+
'inherits'?: string[];
|
|
27
|
+
'read'?: boolean | Rule | Rule[];
|
|
28
|
+
}
|
|
29
|
+
export interface GrantsObject {
|
|
30
|
+
[roleName: string]: Grant;
|
|
31
|
+
}
|
|
32
|
+
export interface LookupConfig {
|
|
33
|
+
filter?: Record<string, any>;
|
|
34
|
+
resource: string;
|
|
35
|
+
select: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The final, declarative JSON artifact for a single policy.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export interface Policy {
|
|
42
|
+
grants: GrantsObject;
|
|
43
|
+
resource: string;
|
|
44
|
+
}
|
|
45
|
+
export interface Rule {
|
|
46
|
+
check?: {
|
|
47
|
+
condition: FilterCondition;
|
|
48
|
+
errorMessage: string;
|
|
49
|
+
};
|
|
50
|
+
columns?: {
|
|
51
|
+
except: string[];
|
|
52
|
+
};
|
|
53
|
+
filter?: FilterCondition;
|
|
54
|
+
preset?: Record<string, any>;
|
|
55
|
+
}
|
|
56
|
+
declare global {
|
|
57
|
+
/**
|
|
58
|
+
* Logically combines multiple rules with an AND condition.
|
|
59
|
+
* An array of rules `[rule1, rule2]` is shorthand for `and(rule1, rule2)`.
|
|
60
|
+
*/
|
|
61
|
+
function and(...rules: Rule[]): {
|
|
62
|
+
_and: Rule[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Creates a validation rule for mutations.
|
|
66
|
+
* If the condition is met, the mutation is allowed. If not, the transaction
|
|
67
|
+
* is rejected with the provided error message.
|
|
68
|
+
* @param errorMessage The error message to return if the check fails.
|
|
69
|
+
* @param condition The filter-style condition object to validate.
|
|
70
|
+
*/
|
|
71
|
+
function check(errorMessage: string, condition: FilterCondition): Rule;
|
|
72
|
+
/**
|
|
73
|
+
* A helper for column-level security that denies access to specific fields.
|
|
74
|
+
* @param fields A list of field names to hide.
|
|
75
|
+
*/
|
|
76
|
+
function deny(...fields: string[]): {
|
|
77
|
+
columns: {
|
|
78
|
+
except: string[];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Creates a lookup rule for filtering against an unrelated resource.
|
|
83
|
+
* This is translated into a subquery by the SQLCompiler.
|
|
84
|
+
* @param config The lookup configuration.
|
|
85
|
+
* @example
|
|
86
|
+
* // Restrict access to projects where the current user is a team member.
|
|
87
|
+
* const rule = {
|
|
88
|
+
* filter: {
|
|
89
|
+
* id: {
|
|
90
|
+
* _in: lookup({
|
|
91
|
+
* resource: 'my_app/table/project_member',
|
|
92
|
+
* select: 'project_id',
|
|
93
|
+
* filter: { user_id: { _eq: '$user.id' } }
|
|
94
|
+
* })
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* };
|
|
98
|
+
*/
|
|
99
|
+
function lookup(config: LookupConfig): any;
|
|
100
|
+
/**
|
|
101
|
+
* Negates a rule.
|
|
102
|
+
*/
|
|
103
|
+
function not(rule: Rule): {
|
|
104
|
+
_not: Rule;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Logically combines multiple rules with an OR condition.
|
|
108
|
+
*/
|
|
109
|
+
function or(...rules: Rule[]): {
|
|
110
|
+
_or: Rule[];
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Defines a security policy for a specific resource.
|
|
114
|
+
* @param resourceName The full name of the target resource, following the pattern `app_id/table/resource_name` or `app_id/logic/resource_name`.
|
|
115
|
+
* @param grantsObject An object defining the permissions for each role.
|
|
116
|
+
* @example
|
|
117
|
+
* // Define reusable rule constants for clarity
|
|
118
|
+
* const when = {
|
|
119
|
+
* isOwner: { filter: { creator_id: { _eq: '$user.id' } } },
|
|
120
|
+
* isDraft: { filter: { status: { _eq: 'Draft' } } }
|
|
121
|
+
* };
|
|
122
|
+
*
|
|
123
|
+
* const hide = {
|
|
124
|
+
* financials: deny('rate', 'commission')
|
|
125
|
+
* };
|
|
126
|
+
*
|
|
127
|
+
* // Define a policy for the 'booking' table in the 'crm' app
|
|
128
|
+
* policy('crm/table/booking', {
|
|
129
|
+
* // Agents can read their own bookings and we hide financial fields.
|
|
130
|
+
* agent: {
|
|
131
|
+
* read: [when.isOwner, hide.financials],
|
|
132
|
+
* create: true, // Can create new bookings
|
|
133
|
+
* edit: [when.isOwner, when.isDraft] // Can only edit their own bookings if they are in draft status
|
|
134
|
+
* },
|
|
135
|
+
*
|
|
136
|
+
* // Managers have full access to all bookings.
|
|
137
|
+
* manager: {
|
|
138
|
+
* '*': true // Wildcard for all permissions
|
|
139
|
+
* },
|
|
140
|
+
*
|
|
141
|
+
* // Finance users have limited, read-only aggregation rights.
|
|
142
|
+
* finance: {
|
|
143
|
+
* read: false, // Cannot read individual booking records
|
|
144
|
+
* aggregate: {
|
|
145
|
+
* allowNodes: false, // Cannot view the raw data rows
|
|
146
|
+
* allow: {
|
|
147
|
+
* count: true,
|
|
148
|
+
* sum: ['amount', 'commission'] // Can only sum these specific numeric fields
|
|
149
|
+
* }
|
|
150
|
+
* }
|
|
151
|
+
* }
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* // Define a policy for a logic/action resource
|
|
155
|
+
* policy('crm/logic/send_invoice', {
|
|
156
|
+
* // Only managers and agents can execute this action.
|
|
157
|
+
* manager: { execute: true },
|
|
158
|
+
* agent: { execute: true }
|
|
159
|
+
* });
|
|
160
|
+
*/
|
|
161
|
+
function policy(resourceName: string, grantsObject: GrantsObject): void;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Clears the internal policy array.
|
|
165
|
+
* Called by the "Smart Compiler" to reset state between executions.
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
export declare function clearCompiledPolicies(): void;
|
|
169
|
+
/**
|
|
170
|
+
* Retrieves the array of compiled policies.
|
|
171
|
+
* Called by the "Smart Compiler" Record Behavior after executing the manifest.
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export declare function getCompiledPolicies(): Policy[];
|
package/dist/security.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Simple Platform Security SDK
|
|
3
|
+
*
|
|
4
|
+
* This module provides the global-style, fluent API for authoring security policies
|
|
5
|
+
* in a standard JavaScript (`.js`) file. It is designed to be executed by the
|
|
6
|
+
* platform's "Smart Compiler" (a Record Behavior) to produce a declarative
|
|
7
|
+
* JSON artifact.
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Internal State & Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* A module-level array that will hold the compiled policies after the user's
|
|
14
|
+
* security manifest script has been executed.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
const _compiledPolicies = [];
|
|
18
|
+
globalThis.policy = (resourceName, grantsObject) => {
|
|
19
|
+
_compiledPolicies.push({
|
|
20
|
+
grants: grantsObject,
|
|
21
|
+
resource: resourceName,
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
globalThis.lookup = (config) => {
|
|
25
|
+
// This function simply returns a structured object that the compiler can identify.
|
|
26
|
+
return { $$isLookup: true, ...config };
|
|
27
|
+
};
|
|
28
|
+
globalThis.and = (...rules) => ({ _and: rules });
|
|
29
|
+
globalThis.or = (...rules) => ({ _or: rules });
|
|
30
|
+
globalThis.not = (rule) => ({ _not: rule });
|
|
31
|
+
globalThis.deny = (...fields) => {
|
|
32
|
+
return { columns: { except: fields.flat() } };
|
|
33
|
+
};
|
|
34
|
+
globalThis.check = (errorMessage, condition) => {
|
|
35
|
+
return {
|
|
36
|
+
check: {
|
|
37
|
+
condition,
|
|
38
|
+
errorMessage,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Internal Helpers for the Compiler
|
|
44
|
+
// ============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Clears the internal policy array.
|
|
47
|
+
* Called by the "Smart Compiler" to reset state between executions.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export function clearCompiledPolicies() {
|
|
51
|
+
_compiledPolicies.length = 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Retrieves the array of compiled policies.
|
|
55
|
+
* Called by the "Smart Compiler" Record Behavior after executing the manifest.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export function getCompiledPolicies() {
|
|
59
|
+
return _compiledPolicies;
|
|
60
|
+
}
|