@onreza/runtime 0.2.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 +153 -0
- package/dist/context.d.ts +45 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +69 -0
- package/dist/context.js.map +1 -0
- package/dist/db.d.ts +39 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +81 -0
- package/dist/db.js.map +1 -0
- package/dist/env.d.ts +58 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +86 -0
- package/dist/env.js.map +1 -0
- package/dist/image.d.ts +92 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +150 -0
- package/dist/image.js.map +1 -0
- package/dist/kv.d.ts +35 -0
- package/dist/kv.d.ts.map +1 -0
- package/dist/kv.js +144 -0
- package/dist/kv.js.map +1 -0
- package/package.json +43 -0
- package/types.d.ts +222 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# @onreza/runtime
|
|
2
|
+
|
|
3
|
+
Runtime SDK for ONREZA platform APIs with TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Установка
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @onreza/runtime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Модули
|
|
12
|
+
|
|
13
|
+
### `@onreza/runtime/kv`
|
|
14
|
+
|
|
15
|
+
KV store (namespace-isolated):
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { kv, isKVAvailable } from '@onreza/runtime/kv';
|
|
19
|
+
|
|
20
|
+
// Check availability (optional)
|
|
21
|
+
if (isKVAvailable()) {
|
|
22
|
+
// Set with TTL
|
|
23
|
+
await kv.set('session:123', { userId: '456' }, { ttl: 3600 });
|
|
24
|
+
|
|
25
|
+
// Get as JSON
|
|
26
|
+
const user = await kv.get('user:123', { type: 'json' });
|
|
27
|
+
|
|
28
|
+
// Check existence
|
|
29
|
+
const exists = await kv.has('user:123');
|
|
30
|
+
|
|
31
|
+
// Delete
|
|
32
|
+
await kv.delete('session:123');
|
|
33
|
+
|
|
34
|
+
// List keys with prefix
|
|
35
|
+
const { keys, cursor } = await kv.list({ prefix: 'user:', limit: 50 });
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### `@onreza/runtime/db`
|
|
40
|
+
|
|
41
|
+
D1-compatible database:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { db, isDBAvailable } from '@onreza/runtime/db';
|
|
45
|
+
|
|
46
|
+
if (isDBAvailable()) {
|
|
47
|
+
// Prepare and execute query
|
|
48
|
+
const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
|
49
|
+
const { results } = await stmt.bind(1).all();
|
|
50
|
+
|
|
51
|
+
// Get first row
|
|
52
|
+
const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(1).first();
|
|
53
|
+
|
|
54
|
+
// Insert
|
|
55
|
+
await db.prepare('INSERT INTO users (name) VALUES (?)').bind('Alice').run();
|
|
56
|
+
|
|
57
|
+
// Batch operations
|
|
58
|
+
const stmt1 = db.prepare('UPDATE users SET name = ? WHERE id = ?').bind('Bob', 1);
|
|
59
|
+
const stmt2 = db.prepare('UPDATE users SET name = ? WHERE id = ?').bind('Charlie', 2);
|
|
60
|
+
await db.batch([stmt1, stmt2]);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `@onreza/runtime/context`
|
|
65
|
+
|
|
66
|
+
Request context and geolocation:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { getContext, isContextAvailable, getClientIp, getGeo, getRequestId } from '@onreza/runtime/context';
|
|
70
|
+
|
|
71
|
+
if (isContextAvailable()) {
|
|
72
|
+
// Get full context
|
|
73
|
+
const ctx = getContext();
|
|
74
|
+
console.log(ctx.geo?.city); // 'Moscow'
|
|
75
|
+
console.log(ctx.geo?.country); // 'RU'
|
|
76
|
+
console.log(ctx.clientIp); // '1.2.3.4'
|
|
77
|
+
console.log(ctx.requestId); // UUID v7
|
|
78
|
+
|
|
79
|
+
// Or use shortcuts
|
|
80
|
+
const ip = getClientIp();
|
|
81
|
+
const geo = getGeo();
|
|
82
|
+
const requestId = getRequestId();
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `@onreza/runtime/env`
|
|
87
|
+
|
|
88
|
+
Environment variables:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { env, isEnvAvailable, getEnv } from '@onreza/runtime/env';
|
|
92
|
+
|
|
93
|
+
if (isEnvAvailable()) {
|
|
94
|
+
// Get required variable (throws if missing)
|
|
95
|
+
const apiKey = env.get('API_KEY');
|
|
96
|
+
|
|
97
|
+
// Get with default
|
|
98
|
+
const timeout = getEnv('TIMEOUT', '5000');
|
|
99
|
+
|
|
100
|
+
// Check existence
|
|
101
|
+
if (env.has('DEBUG')) {
|
|
102
|
+
console.log('Debug mode enabled');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Iterate all variables
|
|
106
|
+
for (const [key, value] of env.entries()) {
|
|
107
|
+
console.log(`${key}=${value}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `@onreza/runtime/image`
|
|
113
|
+
|
|
114
|
+
Image optimization URL builder:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
|
|
118
|
+
|
|
119
|
+
// Basic usage
|
|
120
|
+
const url = imageUrl('/images/hero.jpg', { width: 1080 });
|
|
121
|
+
// → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
|
|
122
|
+
|
|
123
|
+
// With all options
|
|
124
|
+
const optimized = imageUrl('/images/photo.jpg', {
|
|
125
|
+
width: 640,
|
|
126
|
+
height: 480,
|
|
127
|
+
quality: 80,
|
|
128
|
+
format: 'webp',
|
|
129
|
+
fit: 'cover',
|
|
130
|
+
blur: 10,
|
|
131
|
+
dpr: 2
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Generate srcset for responsive images
|
|
135
|
+
const srcset = generateSrcset('/images/photo.jpg', [640, 1080, 1920], { quality: 80 });
|
|
136
|
+
// → '/_onreza/image?url=...&w=640&q=80 640w, /_onreza/image?url=...&w=1080&q=80 1080w, ...'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `@onreza/runtime/types`
|
|
140
|
+
|
|
141
|
+
All types combined:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
/// <reference types="@onreza/runtime/types" />
|
|
145
|
+
|
|
146
|
+
// Or import specific types
|
|
147
|
+
import type { KVStore, D1Database, OnrezaContext } from '@onreza/runtime/types';
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Требования
|
|
151
|
+
|
|
152
|
+
- TypeScript 5.0+
|
|
153
|
+
- ONREZA runtime environment (edge runtime)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Request Context SDK
|
|
3
|
+
*
|
|
4
|
+
* Utilities for accessing request context and geolocation
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { getContext, isContextAvailable } from '@onreza/runtime/context';
|
|
9
|
+
*
|
|
10
|
+
* if (isContextAvailable()) {
|
|
11
|
+
* const ctx = getContext();
|
|
12
|
+
* console.log(ctx.geo?.city);
|
|
13
|
+
* console.log(ctx.requestId);
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import type { OnrezaContext, OnrezaGeo } from "../types.d.ts";
|
|
18
|
+
/**
|
|
19
|
+
* Check if request context is available
|
|
20
|
+
*
|
|
21
|
+
* @returns true if ONREZA.context is available
|
|
22
|
+
*/
|
|
23
|
+
export declare function isContextAvailable(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Get the ONREZA request context
|
|
26
|
+
* @throws Error if not running in ONREZA runtime
|
|
27
|
+
*/
|
|
28
|
+
export declare function getContext(): OnrezaContext;
|
|
29
|
+
/**
|
|
30
|
+
* Get client IP from context
|
|
31
|
+
* @returns Client IP or null if not available
|
|
32
|
+
*/
|
|
33
|
+
export declare function getClientIp(): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get GeoIP data from context
|
|
36
|
+
* @returns Geo data or null if not available
|
|
37
|
+
*/
|
|
38
|
+
export declare function getGeo(): OnrezaGeo | null;
|
|
39
|
+
/**
|
|
40
|
+
* Get request ID from context
|
|
41
|
+
* @returns Request ID or null if not available
|
|
42
|
+
*/
|
|
43
|
+
export declare function getRequestId(): string | null;
|
|
44
|
+
export type { OnrezaContext, OnrezaGeo } from "../types.d.ts";
|
|
45
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS9D;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,aAAa,CAM1C;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAG3C;AAED;;;GAGG;AACH,wBAAgB,MAAM,IAAI,SAAS,GAAG,IAAI,CAGzC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAG5C;AAGD,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Request Context SDK
|
|
3
|
+
*
|
|
4
|
+
* Utilities for accessing request context and geolocation
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { getContext, isContextAvailable } from '@onreza/runtime/context';
|
|
9
|
+
*
|
|
10
|
+
* if (isContextAvailable()) {
|
|
11
|
+
* const ctx = getContext();
|
|
12
|
+
* console.log(ctx.geo?.city);
|
|
13
|
+
* console.log(ctx.requestId);
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Check if running in ONREZA runtime environment
|
|
19
|
+
*/
|
|
20
|
+
function isOnrezaRuntime() {
|
|
21
|
+
return typeof globalThis.ONREZA !== "undefined";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if request context is available
|
|
25
|
+
*
|
|
26
|
+
* @returns true if ONREZA.context is available
|
|
27
|
+
*/
|
|
28
|
+
export function isContextAvailable() {
|
|
29
|
+
return isOnrezaRuntime() && !!globalThis.ONREZA?.context;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the ONREZA request context
|
|
33
|
+
* @throws Error if not running in ONREZA runtime
|
|
34
|
+
*/
|
|
35
|
+
export function getContext() {
|
|
36
|
+
const onreza = globalThis.ONREZA;
|
|
37
|
+
if (!onreza?.context) {
|
|
38
|
+
throw new Error("ONREZA context is not available. " + "Make sure you are running in ONREZA runtime.");
|
|
39
|
+
}
|
|
40
|
+
return onreza.context;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get client IP from context
|
|
44
|
+
* @returns Client IP or null if not available
|
|
45
|
+
*/
|
|
46
|
+
export function getClientIp() {
|
|
47
|
+
if (!isContextAvailable())
|
|
48
|
+
return null;
|
|
49
|
+
return getContext().clientIp;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get GeoIP data from context
|
|
53
|
+
* @returns Geo data or null if not available
|
|
54
|
+
*/
|
|
55
|
+
export function getGeo() {
|
|
56
|
+
if (!isContextAvailable())
|
|
57
|
+
return null;
|
|
58
|
+
return getContext().geo;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get request ID from context
|
|
62
|
+
* @returns Request ID or null if not available
|
|
63
|
+
*/
|
|
64
|
+
export function getRequestId() {
|
|
65
|
+
if (!isContextAvailable())
|
|
66
|
+
return null;
|
|
67
|
+
return getContext().requestId;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,OAAQ,UAAmC,CAAC,MAAM,KAAK,WAAW,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,EAAE,IAAI,CAAC,CAAE,UAAiD,CAAC,MAAM,EAAE,OAAO,CAAC;AACnG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAI,UAAuD,CAAC,MAAM,CAAC;IAC/E,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,8CAA8C,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,UAAU,EAAE,CAAC,QAAQ,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,UAAU,EAAE,CAAC,GAAG,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,UAAU,EAAE,CAAC,SAAS,CAAC;AAChC,CAAC"}
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA D1 Database SDK
|
|
3
|
+
*
|
|
4
|
+
* Types and wrappers for ONREZA.db platform API
|
|
5
|
+
* Compatible with Cloudflare D1
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { db, isDBAvailable } from '@onreza/runtime/db';
|
|
10
|
+
*
|
|
11
|
+
* if (isDBAvailable()) {
|
|
12
|
+
* // Prepare and execute query
|
|
13
|
+
* const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
|
14
|
+
* const { results } = await stmt.bind(1).all();
|
|
15
|
+
*
|
|
16
|
+
* // Get first row
|
|
17
|
+
* const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(1).first();
|
|
18
|
+
*
|
|
19
|
+
* // Insert
|
|
20
|
+
* await db.prepare('INSERT INTO users (name) VALUES (?)').bind('Alice').run();
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import type { D1Database } from "../types.d.ts";
|
|
25
|
+
/**
|
|
26
|
+
* D1 Database operations
|
|
27
|
+
*
|
|
28
|
+
* Note: In ONREZA runtime, this uses the platform-injected ONREZA.db.
|
|
29
|
+
* Outside runtime, operations throw an error.
|
|
30
|
+
*/
|
|
31
|
+
export declare const db: Pick<D1Database, "batch" | "exec" | "prepare">;
|
|
32
|
+
/**
|
|
33
|
+
* Check if D1 database is available in the current environment
|
|
34
|
+
*
|
|
35
|
+
* @returns true if ONREZA.db is available
|
|
36
|
+
*/
|
|
37
|
+
export declare function isDBAvailable(): boolean;
|
|
38
|
+
export type { D1Database, D1PreparedStatement, D1Result } from "../types.d.ts";
|
|
39
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAiC,MAAM,eAAe,CAAC;AAwB/E;;;;;GAKG;AACH,eAAO,MAAM,EAAE,EAyBV,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAGD,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA D1 Database SDK
|
|
3
|
+
*
|
|
4
|
+
* Types and wrappers for ONREZA.db platform API
|
|
5
|
+
* Compatible with Cloudflare D1
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { db, isDBAvailable } from '@onreza/runtime/db';
|
|
10
|
+
*
|
|
11
|
+
* if (isDBAvailable()) {
|
|
12
|
+
* // Prepare and execute query
|
|
13
|
+
* const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
|
14
|
+
* const { results } = await stmt.bind(1).all();
|
|
15
|
+
*
|
|
16
|
+
* // Get first row
|
|
17
|
+
* const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(1).first();
|
|
18
|
+
*
|
|
19
|
+
* // Insert
|
|
20
|
+
* await db.prepare('INSERT INTO users (name) VALUES (?)').bind('Alice').run();
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Check if running in ONREZA runtime environment
|
|
26
|
+
*/
|
|
27
|
+
function isOnrezaRuntime() {
|
|
28
|
+
return typeof globalThis.ONREZA !== "undefined";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the ONREZA D1 database instance
|
|
32
|
+
* @throws Error if not running in ONREZA runtime
|
|
33
|
+
*/
|
|
34
|
+
function getDatabase() {
|
|
35
|
+
const onreza = globalThis.ONREZA;
|
|
36
|
+
if (!onreza?.db) {
|
|
37
|
+
throw new Error("ONREZA D1 database is not available. " +
|
|
38
|
+
'Make sure you are running in ONREZA runtime and have "bindings.db: true" in your manifest.');
|
|
39
|
+
}
|
|
40
|
+
return onreza.db;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* D1 Database operations
|
|
44
|
+
*
|
|
45
|
+
* Note: In ONREZA runtime, this uses the platform-injected ONREZA.db.
|
|
46
|
+
* Outside runtime, operations throw an error.
|
|
47
|
+
*/
|
|
48
|
+
export const db = {
|
|
49
|
+
/**
|
|
50
|
+
* Batch execute statements atomically
|
|
51
|
+
*/
|
|
52
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for D1Database API
|
|
53
|
+
async batch(statements) {
|
|
54
|
+
const database = getDatabase();
|
|
55
|
+
return database.batch(statements);
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Execute multiple statements (DDL)
|
|
59
|
+
*/
|
|
60
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for D1Database API
|
|
61
|
+
async exec(query) {
|
|
62
|
+
const database = getDatabase();
|
|
63
|
+
return database.exec(query);
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* Prepare a SQL statement
|
|
67
|
+
*/
|
|
68
|
+
prepare(query) {
|
|
69
|
+
const database = getDatabase();
|
|
70
|
+
return database.prepare(query);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Check if D1 database is available in the current environment
|
|
75
|
+
*
|
|
76
|
+
* @returns true if ONREZA.db is available
|
|
77
|
+
*/
|
|
78
|
+
export function isDBAvailable() {
|
|
79
|
+
return isOnrezaRuntime() && !!globalThis.ONREZA?.db;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,OAAQ,UAAmC,CAAC,MAAM,KAAK,WAAW,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW;IAClB,MAAM,MAAM,GAAI,UAA+C,CAAC,MAAM,CAAC;IACvE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,uCAAuC;YACrC,4FAA4F,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB;;OAEG;IACH,oEAAoE;IACpE,KAAK,CAAC,KAAK,CAAc,UAAiC;QACxD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IACD;;OAEG;IACH,oEAAoE;IACpE,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAa;QACnB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;CACgD,CAAC;AAEpD;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,eAAe,EAAE,IAAI,CAAC,CAAE,UAA4C,CAAC,MAAM,EAAE,EAAE,CAAC;AACzF,CAAC"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Environment SDK
|
|
3
|
+
*
|
|
4
|
+
* Utilities for accessing environment variables
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { env, isEnvAvailable, getEnv } from '@onreza/runtime/env';
|
|
9
|
+
*
|
|
10
|
+
* if (isEnvAvailable()) {
|
|
11
|
+
* // Get required variable (throws if missing)
|
|
12
|
+
* const apiKey = env.get('API_KEY');
|
|
13
|
+
*
|
|
14
|
+
* // Get with default
|
|
15
|
+
* const timeout = getEnv('TIMEOUT', '5000');
|
|
16
|
+
*
|
|
17
|
+
* // Check existence
|
|
18
|
+
* if (env.has('DEBUG')) {
|
|
19
|
+
* console.log('Debug mode enabled');
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Environment variable operations
|
|
26
|
+
*/
|
|
27
|
+
export declare const env: {
|
|
28
|
+
/**
|
|
29
|
+
* Iterate over all environment variables
|
|
30
|
+
*/
|
|
31
|
+
entries(): IterableIterator<[string, string]>;
|
|
32
|
+
/**
|
|
33
|
+
* Get environment variable
|
|
34
|
+
* @param key - Variable name
|
|
35
|
+
* @returns Value or undefined if not set
|
|
36
|
+
*/
|
|
37
|
+
get(key: string): string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Check if environment variable exists
|
|
40
|
+
* @param key - Variable name
|
|
41
|
+
* @returns true if exists
|
|
42
|
+
*/
|
|
43
|
+
has(key: string): boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Check if env store is available
|
|
47
|
+
* @returns true if ONREZA.env is available
|
|
48
|
+
*/
|
|
49
|
+
export declare function isEnvAvailable(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get environment variable with default value
|
|
52
|
+
* @param key - Variable name
|
|
53
|
+
* @param defaultValue - Default if not set
|
|
54
|
+
* @returns Value or default
|
|
55
|
+
*/
|
|
56
|
+
export declare function getEnv(key: string, defaultValue: string): string;
|
|
57
|
+
export type { EnvStore } from "../types.d.ts";
|
|
58
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuBH;;GAEG;AACH,eAAO,MAAM,GAAG;IACd;;OAEG;eACQ,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG7C;;;;OAIG;aACM,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpC;;;;OAIG;aACM,MAAM,GAAG,OAAO;CAG1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAGhE;AAGD,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Environment SDK
|
|
3
|
+
*
|
|
4
|
+
* Utilities for accessing environment variables
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { env, isEnvAvailable, getEnv } from '@onreza/runtime/env';
|
|
9
|
+
*
|
|
10
|
+
* if (isEnvAvailable()) {
|
|
11
|
+
* // Get required variable (throws if missing)
|
|
12
|
+
* const apiKey = env.get('API_KEY');
|
|
13
|
+
*
|
|
14
|
+
* // Get with default
|
|
15
|
+
* const timeout = getEnv('TIMEOUT', '5000');
|
|
16
|
+
*
|
|
17
|
+
* // Check existence
|
|
18
|
+
* if (env.has('DEBUG')) {
|
|
19
|
+
* console.log('Debug mode enabled');
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Check if running in ONREZA runtime environment
|
|
26
|
+
*/
|
|
27
|
+
function isOnrezaRuntime() {
|
|
28
|
+
return typeof globalThis.ONREZA !== "undefined";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the ONREZA env store instance
|
|
32
|
+
* @throws Error if not running in ONREZA runtime
|
|
33
|
+
*/
|
|
34
|
+
function getEnvStore() {
|
|
35
|
+
const onreza = globalThis.ONREZA;
|
|
36
|
+
if (!onreza?.env) {
|
|
37
|
+
throw new Error("ONREZA env is not available. Make sure you are running in ONREZA runtime.");
|
|
38
|
+
}
|
|
39
|
+
return onreza.env;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Environment variable operations
|
|
43
|
+
*/
|
|
44
|
+
export const env = {
|
|
45
|
+
/**
|
|
46
|
+
* Iterate over all environment variables
|
|
47
|
+
*/
|
|
48
|
+
entries() {
|
|
49
|
+
return getEnvStore().entries();
|
|
50
|
+
},
|
|
51
|
+
/**
|
|
52
|
+
* Get environment variable
|
|
53
|
+
* @param key - Variable name
|
|
54
|
+
* @returns Value or undefined if not set
|
|
55
|
+
*/
|
|
56
|
+
get(key) {
|
|
57
|
+
return getEnvStore().get(key);
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* Check if environment variable exists
|
|
61
|
+
* @param key - Variable name
|
|
62
|
+
* @returns true if exists
|
|
63
|
+
*/
|
|
64
|
+
has(key) {
|
|
65
|
+
return getEnvStore().has(key);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Check if env store is available
|
|
70
|
+
* @returns true if ONREZA.env is available
|
|
71
|
+
*/
|
|
72
|
+
export function isEnvAvailable() {
|
|
73
|
+
return isOnrezaRuntime() && !!globalThis.ONREZA?.env;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get environment variable with default value
|
|
77
|
+
* @param key - Variable name
|
|
78
|
+
* @param defaultValue - Default if not set
|
|
79
|
+
* @returns Value or default
|
|
80
|
+
*/
|
|
81
|
+
export function getEnv(key, defaultValue) {
|
|
82
|
+
if (!isEnvAvailable())
|
|
83
|
+
return defaultValue;
|
|
84
|
+
return env.get(key) ?? defaultValue;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,OAAQ,UAAmC,CAAC,MAAM,KAAK,WAAW,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW;IAClB,MAAM,MAAM,GAAI,UAA8C,CAAC,MAAM,CAAC;IACtE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB;;OAEG;IACH,OAAO;QACL,OAAO,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IACD;;;;OAIG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,eAAe,EAAE,IAAI,CAAC,CAAE,UAA6C,CAAC,MAAM,EAAE,GAAG,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,YAAoB;IACtD,IAAI,CAAC,cAAc,EAAE;QAAE,OAAO,YAAY,CAAC;IAC3C,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC;AACtC,CAAC"}
|
package/dist/image.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Image Optimization SDK
|
|
3
|
+
*
|
|
4
|
+
* URL builder for platform image optimization service
|
|
5
|
+
* Endpoint: /_onreza/image
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
|
|
10
|
+
*
|
|
11
|
+
* // Basic usage
|
|
12
|
+
* const url = imageUrl('/images/hero.jpg', { width: 1080 });
|
|
13
|
+
* // → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
|
|
14
|
+
*
|
|
15
|
+
* // With quality and format
|
|
16
|
+
* const optimized = imageUrl('/images/photo.jpg', {
|
|
17
|
+
* width: 640,
|
|
18
|
+
* quality: 80,
|
|
19
|
+
* format: 'webp'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Generate srcset for responsive images
|
|
23
|
+
* const srcset = generateSrcset('/images/photo.jpg', [640, 1080, 1920]);
|
|
24
|
+
* // → '/_onreza/image?url=...&w=640 640w, /_onreza/image?url=...&w=1080 1080w, ...'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
/** Default platform image sizes */
|
|
28
|
+
export declare const DEFAULT_SIZES: readonly [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
|
|
29
|
+
/** Supported image formats */
|
|
30
|
+
export type ImageFormat = "webp" | "avif";
|
|
31
|
+
/** Resize fit modes */
|
|
32
|
+
export type ImageFit = "cover" | "contain" | "fill";
|
|
33
|
+
/**
|
|
34
|
+
* Image transformation options
|
|
35
|
+
*/
|
|
36
|
+
export interface ImageTransformOptions {
|
|
37
|
+
/** Target width in pixels (must be from allowed sizes) */
|
|
38
|
+
width?: number;
|
|
39
|
+
/** Target height in pixels (optional, maintains aspect ratio by default) */
|
|
40
|
+
height?: number;
|
|
41
|
+
/** Quality 1-100 (default: 75) */
|
|
42
|
+
quality?: number;
|
|
43
|
+
/** Output format (default: auto from Accept header) */
|
|
44
|
+
format?: ImageFormat;
|
|
45
|
+
/** Resize fit mode (default: 'cover') */
|
|
46
|
+
fit?: ImageFit;
|
|
47
|
+
/** Gaussian blur sigma 0-250 (default: 0) */
|
|
48
|
+
blur?: number;
|
|
49
|
+
/** Device Pixel Ratio 1-5 (default: 1) - multiplies width/height */
|
|
50
|
+
dpr?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build ONREZA image optimization URL
|
|
54
|
+
*
|
|
55
|
+
* @param src - Relative image path (e.g., "/images/photo.jpg")
|
|
56
|
+
* @param options - Transformation options
|
|
57
|
+
* @returns Optimized image URL
|
|
58
|
+
* @throws Error if src is absolute URL or contains path traversal
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* imageUrl('/images/hero.jpg', { width: 1080 })
|
|
63
|
+
* // → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
|
|
64
|
+
*
|
|
65
|
+
* imageUrl('/images/photo.jpg', { width: 640, quality: 80, format: 'webp', blur: 10 })
|
|
66
|
+
* // → '/_onreza/image?url=%2Fimages%2Fphoto.jpg&w=640&q=80&f=webp&blur=10'
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function imageUrl(src: string, options?: ImageTransformOptions): string;
|
|
70
|
+
/**
|
|
71
|
+
* Validate and normalize image options
|
|
72
|
+
*
|
|
73
|
+
* @param options - Raw options
|
|
74
|
+
* @returns Normalized options with valid values
|
|
75
|
+
*/
|
|
76
|
+
export declare function validateImageOptions(options: ImageTransformOptions): Required<Pick<ImageTransformOptions, "quality" | "blur" | "dpr" | "fit">> & Pick<ImageTransformOptions, "width" | "height" | "format">;
|
|
77
|
+
/**
|
|
78
|
+
* Generate responsive srcset attribute
|
|
79
|
+
*
|
|
80
|
+
* @param src - Relative image path
|
|
81
|
+
* @param widths - Array of desired widths (will be normalized to allowed sizes)
|
|
82
|
+
* @param options - Base options (applied to all sizes)
|
|
83
|
+
* @returns srcset string for img srcset attribute
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* generateSrcset('/images/photo.jpg', [640, 1080, 1920], { quality: 80 })
|
|
88
|
+
* // → '/_onreza/image?url=...&w=640&q=80 640w, /_onreza/image?url=...&w=1080&q=80 1080w, ...'
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function generateSrcset(src: string, widths: number[], options?: Omit<ImageTransformOptions, "width">): string;
|
|
92
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,mCAAmC;AACnC,eAAO,MAAM,aAAa,wDAAyD,CAAC;AAEpF,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C,uBAAuB;AACvB,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yCAAyC;IACzC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAgCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAyCjF;AASD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,GAC1E,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAU3D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAM,GACjD,MAAM,CAQR"}
|
package/dist/image.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Image Optimization SDK
|
|
3
|
+
*
|
|
4
|
+
* URL builder for platform image optimization service
|
|
5
|
+
* Endpoint: /_onreza/image
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
|
|
10
|
+
*
|
|
11
|
+
* // Basic usage
|
|
12
|
+
* const url = imageUrl('/images/hero.jpg', { width: 1080 });
|
|
13
|
+
* // → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
|
|
14
|
+
*
|
|
15
|
+
* // With quality and format
|
|
16
|
+
* const optimized = imageUrl('/images/photo.jpg', {
|
|
17
|
+
* width: 640,
|
|
18
|
+
* quality: 80,
|
|
19
|
+
* format: 'webp'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Generate srcset for responsive images
|
|
23
|
+
* const srcset = generateSrcset('/images/photo.jpg', [640, 1080, 1920]);
|
|
24
|
+
* // → '/_onreza/image?url=...&w=640 640w, /_onreza/image?url=...&w=1080 1080w, ...'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
/** Default platform image sizes */
|
|
28
|
+
export const DEFAULT_SIZES = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
|
|
29
|
+
/**
|
|
30
|
+
* Validate image source path
|
|
31
|
+
* @throws Error if path is invalid
|
|
32
|
+
*/
|
|
33
|
+
function validateSrc(src) {
|
|
34
|
+
// Reject absolute URLs
|
|
35
|
+
if (src.startsWith("http://") || src.startsWith("https://") || src.startsWith("//")) {
|
|
36
|
+
throw new Error(`Image source must be a relative path, got: ${src}`);
|
|
37
|
+
}
|
|
38
|
+
// Path traversal protection
|
|
39
|
+
const normalized = src.replace(/\\/g, "/");
|
|
40
|
+
if (normalized.includes("..") ||
|
|
41
|
+
normalized.includes("%2e") ||
|
|
42
|
+
normalized.includes("%2E") ||
|
|
43
|
+
normalized.includes("%252e") ||
|
|
44
|
+
normalized.includes("%252E")) {
|
|
45
|
+
throw new Error(`Path traversal detected in image source: ${src}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Clamp value to range
|
|
50
|
+
*/
|
|
51
|
+
function clamp(value, min, max) {
|
|
52
|
+
return Math.min(Math.max(value, min), max);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build ONREZA image optimization URL
|
|
56
|
+
*
|
|
57
|
+
* @param src - Relative image path (e.g., "/images/photo.jpg")
|
|
58
|
+
* @param options - Transformation options
|
|
59
|
+
* @returns Optimized image URL
|
|
60
|
+
* @throws Error if src is absolute URL or contains path traversal
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* imageUrl('/images/hero.jpg', { width: 1080 })
|
|
65
|
+
* // → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
|
|
66
|
+
*
|
|
67
|
+
* imageUrl('/images/photo.jpg', { width: 640, quality: 80, format: 'webp', blur: 10 })
|
|
68
|
+
* // → '/_onreza/image?url=%2Fimages%2Fphoto.jpg&w=640&q=80&f=webp&blur=10'
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function imageUrl(src, options = {}) {
|
|
72
|
+
validateSrc(src);
|
|
73
|
+
const params = new URLSearchParams();
|
|
74
|
+
params.set("url", src);
|
|
75
|
+
// Width (required)
|
|
76
|
+
if (options.width !== undefined) {
|
|
77
|
+
params.set("w", String(options.width));
|
|
78
|
+
}
|
|
79
|
+
// Height (optional)
|
|
80
|
+
if (options.height !== undefined) {
|
|
81
|
+
params.set("h", String(options.height));
|
|
82
|
+
}
|
|
83
|
+
// Quality (default: 75)
|
|
84
|
+
const quality = options.quality !== undefined ? clamp(options.quality, 1, 100) : 75;
|
|
85
|
+
params.set("q", String(quality));
|
|
86
|
+
// Format (optional)
|
|
87
|
+
if (options.format) {
|
|
88
|
+
params.set("f", options.format);
|
|
89
|
+
}
|
|
90
|
+
// Fit mode (optional, default: cover)
|
|
91
|
+
if (options.fit && options.fit !== "cover") {
|
|
92
|
+
params.set("fit", options.fit);
|
|
93
|
+
}
|
|
94
|
+
// Blur (optional, 0-250)
|
|
95
|
+
if (options.blur !== undefined && options.blur > 0) {
|
|
96
|
+
params.set("blur", String(clamp(options.blur, 0, 250)));
|
|
97
|
+
}
|
|
98
|
+
// DPR (optional, 1-5)
|
|
99
|
+
if (options.dpr !== undefined && options.dpr !== 1) {
|
|
100
|
+
params.set("dpr", String(clamp(options.dpr, 1, 5)));
|
|
101
|
+
}
|
|
102
|
+
return `/_onreza/image?${params.toString()}`;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Find nearest allowed width from DEFAULT_SIZES
|
|
106
|
+
*/
|
|
107
|
+
function findNearestWidth(width) {
|
|
108
|
+
return DEFAULT_SIZES.reduce((prev, curr) => (Math.abs(curr - width) < Math.abs(prev - width) ? curr : prev));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validate and normalize image options
|
|
112
|
+
*
|
|
113
|
+
* @param options - Raw options
|
|
114
|
+
* @returns Normalized options with valid values
|
|
115
|
+
*/
|
|
116
|
+
export function validateImageOptions(options) {
|
|
117
|
+
return {
|
|
118
|
+
blur: clamp(options.blur ?? 0, 0, 250),
|
|
119
|
+
dpr: clamp(options.dpr ?? 1, 1, 5),
|
|
120
|
+
fit: options.fit ?? "cover",
|
|
121
|
+
format: options.format,
|
|
122
|
+
height: options.height,
|
|
123
|
+
quality: clamp(options.quality ?? 75, 1, 100),
|
|
124
|
+
width: options.width !== undefined ? findNearestWidth(options.width) : undefined,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Generate responsive srcset attribute
|
|
129
|
+
*
|
|
130
|
+
* @param src - Relative image path
|
|
131
|
+
* @param widths - Array of desired widths (will be normalized to allowed sizes)
|
|
132
|
+
* @param options - Base options (applied to all sizes)
|
|
133
|
+
* @returns srcset string for img srcset attribute
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* generateSrcset('/images/photo.jpg', [640, 1080, 1920], { quality: 80 })
|
|
138
|
+
* // → '/_onreza/image?url=...&w=640&q=80 640w, /_onreza/image?url=...&w=1080&q=80 1080w, ...'
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export function generateSrcset(src, widths, options = {}) {
|
|
142
|
+
return widths
|
|
143
|
+
.map((width) => {
|
|
144
|
+
const nearest = findNearestWidth(width);
|
|
145
|
+
const url = imageUrl(src, { ...options, width: nearest });
|
|
146
|
+
return `${url} ${nearest}w`;
|
|
147
|
+
})
|
|
148
|
+
.join(", ");
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"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"}
|
package/dist/kv.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA KV Store SDK
|
|
3
|
+
*
|
|
4
|
+
* Types and wrappers for ONREZA.kv platform API
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { kv, isKVAvailable } from '@onreza/runtime/kv';
|
|
9
|
+
*
|
|
10
|
+
* // Check availability (optional)
|
|
11
|
+
* if (isKVAvailable()) {
|
|
12
|
+
* // Set with TTL
|
|
13
|
+
* await kv.set('session:123', { userId: '456' }, { ttl: 3600 });
|
|
14
|
+
*
|
|
15
|
+
* // Get as JSON
|
|
16
|
+
* const user = await kv.get('user:123', { type: 'json' });
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import type { KVStore } from "../types.d.ts";
|
|
21
|
+
/**
|
|
22
|
+
* KV store operations
|
|
23
|
+
*
|
|
24
|
+
* Note: In ONREZA runtime, this uses the platform-injected ONREZA.kv.
|
|
25
|
+
* Outside runtime, operations throw an error.
|
|
26
|
+
*/
|
|
27
|
+
export declare const kv: KVStore;
|
|
28
|
+
/**
|
|
29
|
+
* Check if KV store is available in the current environment
|
|
30
|
+
*
|
|
31
|
+
* @returns true if ONREZA.kv is available
|
|
32
|
+
*/
|
|
33
|
+
export declare function isKVAvailable(): boolean;
|
|
34
|
+
export type { KVGetOptions, KVListOptions, KVListResult, KVSetOptions, KVStore } from "../types.d.ts";
|
|
35
|
+
//# sourceMappingURL=kv.d.ts.map
|
package/dist/kv.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAA2D,OAAO,EAAE,MAAM,eAAe,CAAC;AAwBtG;;;;;GAKG;AACH,eAAO,MAAM,EAAE,EA8FV,OAAO,CAAC;AAEb;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAGD,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/kv.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA KV Store SDK
|
|
3
|
+
*
|
|
4
|
+
* Types and wrappers for ONREZA.kv platform API
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { kv, isKVAvailable } from '@onreza/runtime/kv';
|
|
9
|
+
*
|
|
10
|
+
* // Check availability (optional)
|
|
11
|
+
* if (isKVAvailable()) {
|
|
12
|
+
* // Set with TTL
|
|
13
|
+
* await kv.set('session:123', { userId: '456' }, { ttl: 3600 });
|
|
14
|
+
*
|
|
15
|
+
* // Get as JSON
|
|
16
|
+
* const user = await kv.get('user:123', { type: 'json' });
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Check if running in ONREZA runtime environment
|
|
22
|
+
*/
|
|
23
|
+
function isOnrezaRuntime() {
|
|
24
|
+
return typeof globalThis.ONREZA !== "undefined";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the ONREZA KV store instance
|
|
28
|
+
* @throws Error if not running in ONREZA runtime
|
|
29
|
+
*/
|
|
30
|
+
function getKVStore() {
|
|
31
|
+
const onreza = globalThis.ONREZA;
|
|
32
|
+
if (!onreza?.kv) {
|
|
33
|
+
throw new Error("ONREZA KV store is not available. " +
|
|
34
|
+
'Make sure you are running in ONREZA runtime and have "bindings.kv: true" in your manifest.');
|
|
35
|
+
}
|
|
36
|
+
return onreza.kv;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* KV store operations
|
|
40
|
+
*
|
|
41
|
+
* Note: In ONREZA runtime, this uses the platform-injected ONREZA.kv.
|
|
42
|
+
* Outside runtime, operations throw an error.
|
|
43
|
+
*/
|
|
44
|
+
export const kv = {
|
|
45
|
+
/**
|
|
46
|
+
* Delete a key from the KV store
|
|
47
|
+
*
|
|
48
|
+
* @param key - The key to delete
|
|
49
|
+
* @returns true if key existed and was deleted, false otherwise
|
|
50
|
+
*/
|
|
51
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for KVStore API
|
|
52
|
+
async delete(key) {
|
|
53
|
+
const store = getKVStore();
|
|
54
|
+
return store.delete(key);
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Get a value from the KV store
|
|
58
|
+
*
|
|
59
|
+
* @param key - The key to retrieve
|
|
60
|
+
* @param options - Get options (type: 'text' | 'json' | 'arrayBuffer')
|
|
61
|
+
* @returns The value or null if not found
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* // Get as string (default)
|
|
66
|
+
* const value = await kv.get('my-key');
|
|
67
|
+
*
|
|
68
|
+
* // Get as JSON
|
|
69
|
+
* const data = await kv.get('user:123', { type: 'json' });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for KVStore API
|
|
73
|
+
async get(key, options) {
|
|
74
|
+
const store = getKVStore();
|
|
75
|
+
return store.get(key, options);
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Check if a key exists in the KV store
|
|
79
|
+
*
|
|
80
|
+
* @param key - The key to check
|
|
81
|
+
* @returns true if key exists, false otherwise
|
|
82
|
+
*/
|
|
83
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for KVStore API
|
|
84
|
+
async has(key) {
|
|
85
|
+
const store = getKVStore();
|
|
86
|
+
return store.has(key);
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* List keys in the KV store with optional filtering
|
|
90
|
+
*
|
|
91
|
+
* @param options - List options (prefix, limit, cursor)
|
|
92
|
+
* @returns Object with keys array and optional cursor for pagination
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // List first 50 keys with prefix
|
|
97
|
+
* const { keys, cursor } = await kv.list({ prefix: 'user:', limit: 50 });
|
|
98
|
+
*
|
|
99
|
+
* // Get next page
|
|
100
|
+
* if (cursor) {
|
|
101
|
+
* const next = await kv.list({ prefix: 'user:', limit: 50, cursor });
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for KVStore API
|
|
106
|
+
async list(options) {
|
|
107
|
+
const store = getKVStore();
|
|
108
|
+
return store.list(options);
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* Set a value in the KV store
|
|
112
|
+
*
|
|
113
|
+
* @param key - The key to set
|
|
114
|
+
* @param value - The value to store (string, object, or ArrayBuffer)
|
|
115
|
+
* @param options - Set options (ttl in seconds)
|
|
116
|
+
* @returns Promise that resolves when set is complete
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Set string
|
|
121
|
+
* await kv.set('name', 'John');
|
|
122
|
+
*
|
|
123
|
+
* // Set object (auto-JSON.stringify)
|
|
124
|
+
* await kv.set('user', { name: 'John', age: 30 });
|
|
125
|
+
*
|
|
126
|
+
* // Set with TTL (1 hour)
|
|
127
|
+
* await kv.set('session', { id: 'abc' }, { ttl: 3600 });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
// biome-ignore lint/suspicious/useAwait: Wrapper for KVStore API
|
|
131
|
+
async set(key, value, options) {
|
|
132
|
+
const store = getKVStore();
|
|
133
|
+
return store.set(key, value, options);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Check if KV store is available in the current environment
|
|
138
|
+
*
|
|
139
|
+
* @returns true if ONREZA.kv is available
|
|
140
|
+
*/
|
|
141
|
+
export function isKVAvailable() {
|
|
142
|
+
return isOnrezaRuntime() && !!globalThis.ONREZA?.kv;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=kv.js.map
|
package/dist/kv.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH;;GAEG;AACH,SAAS,eAAe;IACtB,OAAO,OAAQ,UAAmC,CAAC,MAAM,KAAK,WAAW,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU;IACjB,MAAM,MAAM,GAAI,UAA4C,CAAC,MAAM,CAAC;IACpE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,oCAAoC;YAClC,4FAA4F,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB;;;;;OAKG;IACH,iEAAiE;IACjE,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD;;;;;;;;;;;;;;;OAeG;IACH,iEAAiE;IACjE,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,OAAsB;QAC3C,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,OAAQ,KAAK,CAAC,GAAiE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChG,CAAC;IAED;;;;;OAKG;IACH,iEAAiE;IACjE,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,iEAAiE;IACjE,KAAK,CAAC,IAAI,CAAC,OAAuB;QAChC,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,iEAAiE;IACjE,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAoC,EAAE,OAAsB;QACjF,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;CACS,CAAC;AAEb;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,eAAe,EAAE,IAAI,CAAC,CAAE,UAA4C,CAAC,MAAM,EAAE,EAAE,CAAC;AACzF,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onreza/runtime",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "ONREZA runtime SDK - types and utilities for platform APIs",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "ONREZA OSS <opensource@onreza.ru>",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
"./kv": {
|
|
10
|
+
"types": "./dist/kv.d.ts",
|
|
11
|
+
"import": "./dist/kv.js"
|
|
12
|
+
},
|
|
13
|
+
"./db": {
|
|
14
|
+
"types": "./dist/db.d.ts",
|
|
15
|
+
"import": "./dist/db.js"
|
|
16
|
+
},
|
|
17
|
+
"./context": {
|
|
18
|
+
"types": "./dist/context.d.ts",
|
|
19
|
+
"import": "./dist/context.js"
|
|
20
|
+
},
|
|
21
|
+
"./image": {
|
|
22
|
+
"types": "./dist/image.d.ts",
|
|
23
|
+
"import": "./dist/image.js"
|
|
24
|
+
},
|
|
25
|
+
"./env": {
|
|
26
|
+
"types": "./dist/env.d.ts",
|
|
27
|
+
"import": "./dist/env.js"
|
|
28
|
+
},
|
|
29
|
+
"./types": {
|
|
30
|
+
"types": "./types.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": ["dist", "types.d.ts"],
|
|
34
|
+
"keywords": ["onreza", "runtime", "edge", "kv", "d1", "image-optimization"],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "bun run build.ts",
|
|
37
|
+
"test": "bun test",
|
|
38
|
+
"typecheck": "tsc --noEmit"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/bun": "latest"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONREZA Runtime Global Types
|
|
3
|
+
*
|
|
4
|
+
* These types define the platform-injected global ONREZA object
|
|
5
|
+
* available in edge runtime (nrz-isolate).
|
|
6
|
+
*
|
|
7
|
+
* Usage in your code:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* /// <reference types="@onreza/runtime/types" />
|
|
10
|
+
*
|
|
11
|
+
* // Or import specific modules:
|
|
12
|
+
* import { kv } from '@onreza/runtime/kv';
|
|
13
|
+
* import { db } from '@onreza/runtime/db';
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
declare global {
|
|
18
|
+
/**
|
|
19
|
+
* ONREZA platform runtime API
|
|
20
|
+
* Injected by nrz-isolate at runtime
|
|
21
|
+
*/
|
|
22
|
+
const ONREZA: OnrezaRuntime;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* GeoIP data from edge server
|
|
27
|
+
*/
|
|
28
|
+
export interface OnrezaGeo {
|
|
29
|
+
/** ISO 3166-1 alpha-2 country code */
|
|
30
|
+
country: string | null;
|
|
31
|
+
/** City name */
|
|
32
|
+
city: string | null;
|
|
33
|
+
/** Continent code */
|
|
34
|
+
continent: string | null;
|
|
35
|
+
/** Edge region (e.g., "ru-central-1") */
|
|
36
|
+
region: string | null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Platform context - readonly metadata about the current request
|
|
41
|
+
*/
|
|
42
|
+
export interface OnrezaContext {
|
|
43
|
+
/** Client IP address (forwarded from edge) */
|
|
44
|
+
readonly clientIp: string | null;
|
|
45
|
+
/** GeoIP data */
|
|
46
|
+
readonly geo: OnrezaGeo;
|
|
47
|
+
/** Current deployment ID */
|
|
48
|
+
readonly deploymentId: string | null;
|
|
49
|
+
/** Project ID */
|
|
50
|
+
readonly projectId: string | null;
|
|
51
|
+
/** Git commit SHA (short) */
|
|
52
|
+
readonly commitSha: string | null;
|
|
53
|
+
/** Unique request ID (UUID v7, generated per request) */
|
|
54
|
+
readonly requestId: string | null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* KV store operations result
|
|
59
|
+
*/
|
|
60
|
+
export interface KVListResult {
|
|
61
|
+
/** Keys in the result */
|
|
62
|
+
keys: string[];
|
|
63
|
+
/** Cursor for pagination (undefined if no more results) */
|
|
64
|
+
cursor?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* KV store options for set operations
|
|
69
|
+
*/
|
|
70
|
+
export interface KVSetOptions {
|
|
71
|
+
/** TTL in seconds (0 = no expiry) */
|
|
72
|
+
ttl?: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* KV store get options
|
|
77
|
+
*/
|
|
78
|
+
export interface KVGetOptions {
|
|
79
|
+
/** Expected return type */
|
|
80
|
+
type?: "text" | "json" | "arrayBuffer";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* KV store list options
|
|
85
|
+
*/
|
|
86
|
+
export interface KVListOptions {
|
|
87
|
+
/** Key prefix to filter */
|
|
88
|
+
prefix?: string;
|
|
89
|
+
/** Maximum number of keys to return (max 1000) */
|
|
90
|
+
limit?: number;
|
|
91
|
+
/** Cursor for pagination */
|
|
92
|
+
cursor?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* D1 database result metadata
|
|
97
|
+
*/
|
|
98
|
+
export interface D1Meta {
|
|
99
|
+
/** Execution time in seconds */
|
|
100
|
+
duration: number;
|
|
101
|
+
/** Rows changed (0 for SELECT) */
|
|
102
|
+
changes: number;
|
|
103
|
+
/** Last inserted rowid (0 for SELECT) */
|
|
104
|
+
last_row_id: number;
|
|
105
|
+
/** True if changes > 0 */
|
|
106
|
+
changed_db: boolean;
|
|
107
|
+
/** DB + WAL size in bytes */
|
|
108
|
+
size_after: number;
|
|
109
|
+
/** Result row count */
|
|
110
|
+
rows_read: number;
|
|
111
|
+
/** Same as changes (capped at 0) */
|
|
112
|
+
rows_written: number;
|
|
113
|
+
/** Always "nrz-isolate" */
|
|
114
|
+
served_by: string;
|
|
115
|
+
/** Always "local" (single-region) */
|
|
116
|
+
served_by_region: string;
|
|
117
|
+
/** Always true (no replicas) */
|
|
118
|
+
served_by_primary: boolean;
|
|
119
|
+
/** Timing details */
|
|
120
|
+
timings: {
|
|
121
|
+
/** SQL execution time in milliseconds */
|
|
122
|
+
sql_duration_ms: number;
|
|
123
|
+
};
|
|
124
|
+
/** Always 1 (no retries) */
|
|
125
|
+
total_attempts: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* D1 query result
|
|
130
|
+
*/
|
|
131
|
+
export interface D1Result<T = unknown> {
|
|
132
|
+
/** Query results */
|
|
133
|
+
results: T[];
|
|
134
|
+
/** Whether query succeeded */
|
|
135
|
+
success: boolean;
|
|
136
|
+
/** Result metadata */
|
|
137
|
+
meta: D1Meta;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* D1 prepared statement
|
|
142
|
+
*/
|
|
143
|
+
export interface D1PreparedStatement {
|
|
144
|
+
/** Bind parameters and return statement */
|
|
145
|
+
bind(...values: unknown[]): D1PreparedStatement;
|
|
146
|
+
/** Execute and return all rows */
|
|
147
|
+
all<T = unknown>(): Promise<D1Result<T>>;
|
|
148
|
+
/** Execute and return first row or null */
|
|
149
|
+
first<T = unknown>(colName?: string): Promise<T | null>;
|
|
150
|
+
/** Execute write operation */
|
|
151
|
+
run(): Promise<D1Result>;
|
|
152
|
+
/** Return raw array of arrays */
|
|
153
|
+
raw<T = unknown[]>(): Promise<T[]>;
|
|
154
|
+
raw<T = unknown[]>(options: { columnNames: true }): Promise<{ columns: string[]; results: T[] }>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* D1 database API
|
|
159
|
+
* Compatible with Cloudflare D1
|
|
160
|
+
*/
|
|
161
|
+
export interface D1Database {
|
|
162
|
+
/** Prepare a statement */
|
|
163
|
+
prepare(query: string): D1PreparedStatement;
|
|
164
|
+
/** Execute multiple statements (DDL) */
|
|
165
|
+
exec(query: string): Promise<{ count: number; duration: number }>;
|
|
166
|
+
/** Batch execute statements atomically */
|
|
167
|
+
batch<T = unknown>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;
|
|
168
|
+
/** Dump database (not implemented - throws Error) */
|
|
169
|
+
dump(): Promise<ArrayBuffer>;
|
|
170
|
+
/** With session (not implemented - throws Error) */
|
|
171
|
+
withSession<T>(callback: (db: D1Database) => T | Promise<T>): Promise<T>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* KV store API
|
|
176
|
+
* Namespace-isolated by project_id
|
|
177
|
+
*/
|
|
178
|
+
export interface KVStore {
|
|
179
|
+
/** Get value by key */
|
|
180
|
+
get(key: string, options?: { type: "text" }): Promise<string | null>;
|
|
181
|
+
get<T = unknown>(key: string, options: { type: "json" }): Promise<T | null>;
|
|
182
|
+
get(key: string, options: { type: "arrayBuffer" }): Promise<ArrayBuffer | null>;
|
|
183
|
+
get(key: string): Promise<string | null>;
|
|
184
|
+
|
|
185
|
+
/** Set value */
|
|
186
|
+
set(key: string, value: string | object | ArrayBuffer, options?: KVSetOptions): Promise<void>;
|
|
187
|
+
|
|
188
|
+
/** Delete key */
|
|
189
|
+
delete(key: string): Promise<boolean>;
|
|
190
|
+
|
|
191
|
+
/** Check if key exists */
|
|
192
|
+
has(key: string): Promise<boolean>;
|
|
193
|
+
|
|
194
|
+
/** List keys with optional prefix */
|
|
195
|
+
list(options?: KVListOptions): Promise<KVListResult>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Environment variable access
|
|
200
|
+
*/
|
|
201
|
+
export interface EnvStore {
|
|
202
|
+
/** Get environment variable */
|
|
203
|
+
get(key: string): string | undefined;
|
|
204
|
+
/** Check if environment variable exists */
|
|
205
|
+
has(key: string): boolean;
|
|
206
|
+
/** Iterate over all environment variables */
|
|
207
|
+
entries(): IterableIterator<[string, string]>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Main ONREZA runtime interface
|
|
212
|
+
*/
|
|
213
|
+
export interface OnrezaRuntime {
|
|
214
|
+
/** KV store (requires bindings.kv: true in manifest) */
|
|
215
|
+
readonly kv: KVStore;
|
|
216
|
+
/** D1 database (requires bindings.db: true in manifest) */
|
|
217
|
+
readonly db: D1Database;
|
|
218
|
+
/** Platform context (request metadata) */
|
|
219
|
+
readonly context: OnrezaContext;
|
|
220
|
+
/** Environment variables */
|
|
221
|
+
readonly env: EnvStore;
|
|
222
|
+
}
|