@aerostack/core 0.6.1
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 +13 -0
- package/dist/client.d.ts +163 -0
- package/dist/client.js +119 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +22 -0
- package/dist/schemas/registry.d.ts +76 -0
- package/dist/schemas/registry.js +48 -0
- package/dist/types/gateway.d.ts +42 -0
- package/dist/types/gateway.js +2 -0
- package/dist/types.d.ts +288 -0
- package/dist/types.js +2 -0
- package/package.json +21 -0
- package/src/client.ts +151 -0
- package/src/index.ts +4 -0
- package/src/schemas/registry.ts +51 -0
- package/src/types/gateway.ts +46 -0
- package/src/types.ts +207 -0
package/README.md
ADDED
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Product, Cart, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
|
|
2
|
+
export interface AerocallConfig {
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
jwt?: string;
|
|
6
|
+
projectId?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class AerocallClient implements AerostackRPC {
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private apiKey?;
|
|
11
|
+
private jwt?;
|
|
12
|
+
private projectId?;
|
|
13
|
+
constructor(config: AerocallConfig);
|
|
14
|
+
private request;
|
|
15
|
+
get db(): {
|
|
16
|
+
query: <T = any>(sql: string, params?: any[]) => Promise<T[]>;
|
|
17
|
+
};
|
|
18
|
+
get cache(): {
|
|
19
|
+
get: <T = any>(key: string) => Promise<{
|
|
20
|
+
value: T | null;
|
|
21
|
+
exists: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
set: (key: string, value: any, ttl?: number) => Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
delete: (key: string) => Promise<{
|
|
27
|
+
success: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
get queue(): {
|
|
31
|
+
enqueue: (type: string, data: any) => Promise<{
|
|
32
|
+
success: boolean;
|
|
33
|
+
jobId: string;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
get ai(): {
|
|
37
|
+
chat: (messages: {
|
|
38
|
+
role: "user" | "assistant" | "system";
|
|
39
|
+
content: string;
|
|
40
|
+
}[], model?: string) => Promise<{
|
|
41
|
+
response: string;
|
|
42
|
+
}>;
|
|
43
|
+
search: {
|
|
44
|
+
ingest: (content: string, metadata?: Record<string, any>, type?: string) => Promise<{
|
|
45
|
+
success: boolean;
|
|
46
|
+
}>;
|
|
47
|
+
query: (text: string, options?: {
|
|
48
|
+
limit?: number;
|
|
49
|
+
threshold?: number;
|
|
50
|
+
filter?: Record<string, any>;
|
|
51
|
+
}) => Promise<{
|
|
52
|
+
results: any[];
|
|
53
|
+
}>;
|
|
54
|
+
delete: (id: string) => Promise<{
|
|
55
|
+
success: boolean;
|
|
56
|
+
}>;
|
|
57
|
+
deleteByType: (type: string) => Promise<{
|
|
58
|
+
success: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
listTypes: () => Promise<{
|
|
61
|
+
types: string[];
|
|
62
|
+
}>;
|
|
63
|
+
configure: (options: {
|
|
64
|
+
embeddingModel: string;
|
|
65
|
+
}) => Promise<{
|
|
66
|
+
success: boolean;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
get storage(): {
|
|
71
|
+
upload: (key: string, file: File | Blob, contentType?: string) => Promise<{
|
|
72
|
+
url: string;
|
|
73
|
+
}>;
|
|
74
|
+
};
|
|
75
|
+
get services(): {
|
|
76
|
+
invoke: <T = any>(serviceName: string, data?: any) => Promise<{
|
|
77
|
+
success: true;
|
|
78
|
+
result: T;
|
|
79
|
+
}>;
|
|
80
|
+
};
|
|
81
|
+
get auth(): {
|
|
82
|
+
signup: (data: {
|
|
83
|
+
email: string;
|
|
84
|
+
password: string;
|
|
85
|
+
name?: string;
|
|
86
|
+
customFields?: Record<string, any>;
|
|
87
|
+
}) => Promise<{
|
|
88
|
+
token: string;
|
|
89
|
+
user: any;
|
|
90
|
+
}>;
|
|
91
|
+
signin: (data: {
|
|
92
|
+
email: string;
|
|
93
|
+
password: string;
|
|
94
|
+
}) => Promise<{
|
|
95
|
+
token: string;
|
|
96
|
+
user: any;
|
|
97
|
+
}>;
|
|
98
|
+
};
|
|
99
|
+
collections(slug: string): {
|
|
100
|
+
list: (options?: {
|
|
101
|
+
status?: "draft" | "published";
|
|
102
|
+
limit?: number;
|
|
103
|
+
}) => Promise<CollectionItem[]>;
|
|
104
|
+
get: (itemId: string) => Promise<CollectionItem>;
|
|
105
|
+
create: (item: {
|
|
106
|
+
slug: string;
|
|
107
|
+
data: Record<string, any>;
|
|
108
|
+
status?: "draft" | "published";
|
|
109
|
+
author_id?: string;
|
|
110
|
+
}) => Promise<CollectionItem>;
|
|
111
|
+
update: (itemId: string, item: Partial<{
|
|
112
|
+
slug: string;
|
|
113
|
+
data: Record<string, any>;
|
|
114
|
+
status: string;
|
|
115
|
+
author_id?: string;
|
|
116
|
+
}>) => Promise<{
|
|
117
|
+
success: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
delete: (itemId: string) => Promise<{
|
|
120
|
+
success: boolean;
|
|
121
|
+
}>;
|
|
122
|
+
};
|
|
123
|
+
ecommerce(): {
|
|
124
|
+
config: () => Promise<StoreConfig>;
|
|
125
|
+
products: {
|
|
126
|
+
list: (options?: {
|
|
127
|
+
category?: string;
|
|
128
|
+
page?: number;
|
|
129
|
+
limit?: number;
|
|
130
|
+
search?: string;
|
|
131
|
+
}) => Promise<{
|
|
132
|
+
products: Product[];
|
|
133
|
+
total: number;
|
|
134
|
+
page: number;
|
|
135
|
+
limit: number;
|
|
136
|
+
}>;
|
|
137
|
+
get: (slugOrId: string) => Promise<{
|
|
138
|
+
product: Product & {
|
|
139
|
+
variants: ProductVariant[];
|
|
140
|
+
};
|
|
141
|
+
}>;
|
|
142
|
+
};
|
|
143
|
+
categories: {
|
|
144
|
+
list: () => Promise<{
|
|
145
|
+
categories: Category[];
|
|
146
|
+
total: number;
|
|
147
|
+
}>;
|
|
148
|
+
};
|
|
149
|
+
cart: (cartId: string) => {
|
|
150
|
+
get: () => Promise<Cart>;
|
|
151
|
+
addItem: (item: {
|
|
152
|
+
productId: string;
|
|
153
|
+
variant_id?: string;
|
|
154
|
+
quantity?: number;
|
|
155
|
+
}) => Promise<Cart>;
|
|
156
|
+
};
|
|
157
|
+
applyCoupon: (code: string) => Promise<{
|
|
158
|
+
valid: boolean;
|
|
159
|
+
discount_amount: number;
|
|
160
|
+
message?: string;
|
|
161
|
+
}>;
|
|
162
|
+
};
|
|
163
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AerocallClient = void 0;
|
|
4
|
+
class AerocallClient {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.baseUrl = config.baseUrl || 'https://api.aerocall.ai/v1';
|
|
7
|
+
this.apiKey = config.apiKey;
|
|
8
|
+
this.jwt = config.jwt;
|
|
9
|
+
this.projectId = config.projectId;
|
|
10
|
+
}
|
|
11
|
+
async request(path, method, body, isMultipart = false) {
|
|
12
|
+
const headers = {
|
|
13
|
+
'X-SDK-Version': '0.4.0'
|
|
14
|
+
};
|
|
15
|
+
if (!isMultipart) {
|
|
16
|
+
headers['Content-Type'] = 'application/json';
|
|
17
|
+
}
|
|
18
|
+
if (this.apiKey)
|
|
19
|
+
headers['X-API-Key'] = this.apiKey;
|
|
20
|
+
if (this.jwt)
|
|
21
|
+
headers['Authorization'] = `Bearer ${this.jwt}`;
|
|
22
|
+
if (this.projectId)
|
|
23
|
+
headers['X-Project-Id'] = this.projectId;
|
|
24
|
+
headers['X-Request-ID'] = crypto.randomUUID();
|
|
25
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
26
|
+
method,
|
|
27
|
+
headers,
|
|
28
|
+
body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
|
|
32
|
+
throw new Error(err.error?.message || 'Unknown error');
|
|
33
|
+
}
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
get db() {
|
|
37
|
+
return {
|
|
38
|
+
query: async (sql, params) => {
|
|
39
|
+
const res = await this.request('/db/query', 'POST', { sql, params });
|
|
40
|
+
return (res?.results ?? []);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
get cache() {
|
|
45
|
+
return {
|
|
46
|
+
get: (key) => this.request('/cache/get', 'POST', { key }),
|
|
47
|
+
set: (key, value, ttl) => this.request('/cache/set', 'POST', { key, value, ttl }),
|
|
48
|
+
delete: (key) => this.request('/cache/delete', 'POST', { key })
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
get queue() {
|
|
52
|
+
return {
|
|
53
|
+
enqueue: (type, data) => this.request('/queue/enqueue', 'POST', { type, data })
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
get ai() {
|
|
57
|
+
return {
|
|
58
|
+
chat: (messages, model) => this.request('/ai/chat', 'POST', { messages, model }),
|
|
59
|
+
search: {
|
|
60
|
+
ingest: (content, metadata, type) => this.request('/ai/search/ingest', 'POST', { content, metadata, type }),
|
|
61
|
+
query: (text, options) => this.request('/ai/search/query', 'POST', { text, ...options }),
|
|
62
|
+
delete: (id) => this.request('/ai/search/delete', 'POST', { id }),
|
|
63
|
+
deleteByType: (type) => this.request('/ai/search/deleteByType', 'POST', { type }),
|
|
64
|
+
listTypes: () => this.request('/ai/search/listTypes', 'GET'),
|
|
65
|
+
configure: (options) => this.request('/ai/search/configure', 'POST', options)
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
get storage() {
|
|
70
|
+
return {
|
|
71
|
+
upload: (key, file, contentType) => {
|
|
72
|
+
const formData = new FormData();
|
|
73
|
+
formData.append('key', key);
|
|
74
|
+
formData.append('file', file);
|
|
75
|
+
if (contentType)
|
|
76
|
+
formData.append('contentType', contentType);
|
|
77
|
+
return this.request('/storage/upload', 'POST', formData, true);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
get services() {
|
|
82
|
+
return {
|
|
83
|
+
invoke: (serviceName, data) => this.request('/services/invoke', 'POST', { serviceName, data })
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
get auth() {
|
|
87
|
+
return {
|
|
88
|
+
signup: (data) => this.request('/auth/signup', 'POST', data),
|
|
89
|
+
signin: (data) => this.request('/auth/signin', 'POST', data),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
collections(slug) {
|
|
93
|
+
return {
|
|
94
|
+
list: (options) => this.request(`/collections/${slug}/items`, 'GET', options),
|
|
95
|
+
get: (itemId) => this.request(`/collections/${slug}/items/${itemId}`, 'GET'),
|
|
96
|
+
create: (item) => this.request(`/collections/${slug}/items`, 'POST', item),
|
|
97
|
+
update: (itemId, item) => this.request(`/collections/${slug}/items/${itemId}`, 'PUT', item),
|
|
98
|
+
delete: (itemId) => this.request(`/collections/${slug}/items/${itemId}`, 'DELETE'),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
ecommerce() {
|
|
102
|
+
return {
|
|
103
|
+
config: () => this.request('/ecommerce/config', 'GET'),
|
|
104
|
+
products: {
|
|
105
|
+
list: (options) => this.request('/ecommerce/products', 'GET', options),
|
|
106
|
+
get: (slugOrId) => this.request(`/ecommerce/products/${slugOrId}`, 'GET'),
|
|
107
|
+
},
|
|
108
|
+
categories: {
|
|
109
|
+
list: () => this.request('/ecommerce/categories', 'GET'),
|
|
110
|
+
},
|
|
111
|
+
cart: (cartId) => ({
|
|
112
|
+
get: () => this.request(`/ecommerce/cart/${cartId}`, 'GET'),
|
|
113
|
+
addItem: (item) => this.request(`/ecommerce/cart/${cartId}/items`, 'POST', item),
|
|
114
|
+
}),
|
|
115
|
+
applyCoupon: (code) => this.request('/ecommerce/coupons/validate', 'POST', { code }),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.AerocallClient = AerocallClient;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.AerocallClient = void 0;
|
|
18
|
+
var client_1 = require("./client");
|
|
19
|
+
Object.defineProperty(exports, "AerocallClient", { enumerable: true, get: function () { return client_1.AerocallClient; } });
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
21
|
+
__exportStar(require("./types/gateway"), exports);
|
|
22
|
+
__exportStar(require("./schemas/registry"), exports);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const RegistryConfigSchemaV1: z.ZodObject<{
|
|
3
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
version: z.ZodString;
|
|
6
|
+
description: z.ZodString;
|
|
7
|
+
author: z.ZodOptional<z.ZodString>;
|
|
8
|
+
type: z.ZodEnum<{
|
|
9
|
+
feature: "feature";
|
|
10
|
+
utility: "utility";
|
|
11
|
+
hook: "hook";
|
|
12
|
+
}>;
|
|
13
|
+
dependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
14
|
+
registryDependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
15
|
+
files: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
16
|
+
source: z.ZodString;
|
|
17
|
+
target: z.ZodString;
|
|
18
|
+
}, z.core.$strip>>>>;
|
|
19
|
+
configuration: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
20
|
+
api_route: z.ZodOptional<z.ZodString>;
|
|
21
|
+
env: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
22
|
+
}, z.core.$strip>>>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
export type RegistryConfigV1 = z.infer<typeof RegistryConfigSchemaV1>;
|
|
25
|
+
export declare const RegistryConfigSchema: z.ZodObject<{
|
|
26
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
version: z.ZodString;
|
|
29
|
+
description: z.ZodString;
|
|
30
|
+
author: z.ZodOptional<z.ZodString>;
|
|
31
|
+
type: z.ZodEnum<{
|
|
32
|
+
feature: "feature";
|
|
33
|
+
utility: "utility";
|
|
34
|
+
hook: "hook";
|
|
35
|
+
}>;
|
|
36
|
+
dependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
37
|
+
registryDependencies: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
38
|
+
files: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
39
|
+
source: z.ZodString;
|
|
40
|
+
target: z.ZodString;
|
|
41
|
+
}, z.core.$strip>>>>;
|
|
42
|
+
configuration: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
43
|
+
api_route: z.ZodOptional<z.ZodString>;
|
|
44
|
+
env: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
45
|
+
}, z.core.$strip>>>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
|
|
48
|
+
/**
|
|
49
|
+
* Validates a configuration payload against the registry schema.
|
|
50
|
+
* @param config The raw configuration object
|
|
51
|
+
* @returns The successfully parsed and validated configuration, or throws a ZodError
|
|
52
|
+
*/
|
|
53
|
+
export declare function validateRegistryConfig(config: unknown): RegistryConfig;
|
|
54
|
+
/**
|
|
55
|
+
* Safely validates a configuration payload against the registry schema.
|
|
56
|
+
* @param config The raw configuration object
|
|
57
|
+
* @returns An object conforming to SafeParseReturnType indicating whether validation was successful
|
|
58
|
+
*/
|
|
59
|
+
export declare function safeValidateRegistryConfig(config: unknown): z.ZodSafeParseResult<{
|
|
60
|
+
name: string;
|
|
61
|
+
version: string;
|
|
62
|
+
description: string;
|
|
63
|
+
type: "feature" | "utility" | "hook";
|
|
64
|
+
dependencies: string[];
|
|
65
|
+
registryDependencies: string[];
|
|
66
|
+
files: {
|
|
67
|
+
source: string;
|
|
68
|
+
target: string;
|
|
69
|
+
}[];
|
|
70
|
+
configuration: {
|
|
71
|
+
env: string[];
|
|
72
|
+
api_route?: string | undefined;
|
|
73
|
+
};
|
|
74
|
+
$schema?: string | undefined;
|
|
75
|
+
author?: string | undefined;
|
|
76
|
+
}>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RegistryConfigSchema = exports.RegistryConfigSchemaV1 = void 0;
|
|
4
|
+
exports.validateRegistryConfig = validateRegistryConfig;
|
|
5
|
+
exports.safeValidateRegistryConfig = safeValidateRegistryConfig;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
// The schema is versioned to allow backwards compatibility
|
|
8
|
+
// Version 1 of the schema
|
|
9
|
+
exports.RegistryConfigSchemaV1 = zod_1.z.object({
|
|
10
|
+
$schema: zod_1.z.string().url().optional(),
|
|
11
|
+
name: zod_1.z.string()
|
|
12
|
+
.min(2, "Name must be at least 2 characters")
|
|
13
|
+
.max(50, "Name must be less than 50 characters")
|
|
14
|
+
.regex(/^[a-z0-9-]+$/, "Name can only contain lowercase letters, numbers, and hyphens"),
|
|
15
|
+
version: zod_1.z.string()
|
|
16
|
+
.regex(/^\d+\.\d+\.\d+$/, "Version must follow semantic versioning (e.g., 1.0.0)"),
|
|
17
|
+
description: zod_1.z.string().min(10, "Description must be at least 10 characters"),
|
|
18
|
+
author: zod_1.z.string().optional(),
|
|
19
|
+
type: zod_1.z.enum(['feature', 'utility', 'hook']),
|
|
20
|
+
dependencies: zod_1.z.array(zod_1.z.string()).optional().default([]),
|
|
21
|
+
registryDependencies: zod_1.z.array(zod_1.z.string()).optional().default([]),
|
|
22
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
23
|
+
source: zod_1.z.string(),
|
|
24
|
+
target: zod_1.z.string(),
|
|
25
|
+
})).min(1, "At least one file mapping is required").optional().default([]),
|
|
26
|
+
configuration: zod_1.z.object({
|
|
27
|
+
api_route: zod_1.z.string().optional(),
|
|
28
|
+
env: zod_1.z.array(zod_1.z.string()).optional().default([]),
|
|
29
|
+
}).optional().default({ env: [] }),
|
|
30
|
+
});
|
|
31
|
+
// Current registry schema version
|
|
32
|
+
exports.RegistryConfigSchema = exports.RegistryConfigSchemaV1;
|
|
33
|
+
/**
|
|
34
|
+
* Validates a configuration payload against the registry schema.
|
|
35
|
+
* @param config The raw configuration object
|
|
36
|
+
* @returns The successfully parsed and validated configuration, or throws a ZodError
|
|
37
|
+
*/
|
|
38
|
+
function validateRegistryConfig(config) {
|
|
39
|
+
return exports.RegistryConfigSchema.parse(config);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Safely validates a configuration payload against the registry schema.
|
|
43
|
+
* @param config The raw configuration object
|
|
44
|
+
* @returns An object conforming to SafeParseReturnType indicating whether validation was successful
|
|
45
|
+
*/
|
|
46
|
+
function safeValidateRegistryConfig(config) {
|
|
47
|
+
return exports.RegistryConfigSchema.safeParse(config);
|
|
48
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface AerostackGatewayConfig {
|
|
2
|
+
models?: Array<{
|
|
3
|
+
id: string;
|
|
4
|
+
provider: string;
|
|
5
|
+
model: string;
|
|
6
|
+
role: string;
|
|
7
|
+
system_prompt?: string;
|
|
8
|
+
max_tokens?: number;
|
|
9
|
+
temperature?: number;
|
|
10
|
+
endpoint?: string;
|
|
11
|
+
format?: string;
|
|
12
|
+
}>;
|
|
13
|
+
routing?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface GatewayMonetizationConfig {
|
|
16
|
+
managed_in_dashboard?: boolean;
|
|
17
|
+
billing_model: 'subscription' | 'pay_as_you_go' | 'freemium' | 'per_token' | 'per_minute';
|
|
18
|
+
credit_topup_enabled?: boolean;
|
|
19
|
+
per_model_cost_tracking?: boolean;
|
|
20
|
+
pricePer1kTokens?: number;
|
|
21
|
+
monthlyPrice?: number;
|
|
22
|
+
includedTokens?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface GatewaySecurityConfig {
|
|
25
|
+
require_api_key?: boolean;
|
|
26
|
+
rate_limit?: {
|
|
27
|
+
strategy: string;
|
|
28
|
+
requests_per_minute: number;
|
|
29
|
+
burst: number;
|
|
30
|
+
};
|
|
31
|
+
allowed_origins?: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface GatewayBillingPayload {
|
|
34
|
+
consumerId: string;
|
|
35
|
+
developerApiId: string;
|
|
36
|
+
metric?: string;
|
|
37
|
+
units: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ConsumerKeyResponse {
|
|
40
|
+
key: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
export interface User {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
avatar_url?: string;
|
|
6
|
+
created_at: number;
|
|
7
|
+
last_login_at?: number;
|
|
8
|
+
project_id?: string | null;
|
|
9
|
+
email_verified_at?: number;
|
|
10
|
+
phone?: string | null;
|
|
11
|
+
phone_verified_at?: number | null;
|
|
12
|
+
}
|
|
13
|
+
export interface Project {
|
|
14
|
+
id: string;
|
|
15
|
+
user_id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
slug: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
created_at: number;
|
|
20
|
+
updated_at: number;
|
|
21
|
+
is_public: number;
|
|
22
|
+
plan: 'free' | 'pro' | 'enterprise';
|
|
23
|
+
subdomain?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Component {
|
|
26
|
+
id: string;
|
|
27
|
+
project_id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
schema: any;
|
|
30
|
+
status: 'processing' | 'completed' | 'failed';
|
|
31
|
+
created_at: number;
|
|
32
|
+
updated_at: number;
|
|
33
|
+
}
|
|
34
|
+
export interface Page {
|
|
35
|
+
id: string;
|
|
36
|
+
project_id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
slug: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
type: 'static' | 'collection' | 'dynamic';
|
|
41
|
+
status: 'draft' | 'published' | 'archived';
|
|
42
|
+
meta_title?: string;
|
|
43
|
+
meta_description?: string;
|
|
44
|
+
published_at?: number;
|
|
45
|
+
created_at: number;
|
|
46
|
+
updated_at: number;
|
|
47
|
+
}
|
|
48
|
+
export interface Product {
|
|
49
|
+
id: string;
|
|
50
|
+
project_id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
slug: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
thumbnail_url?: string;
|
|
55
|
+
base_price: number;
|
|
56
|
+
compare_at_price?: number;
|
|
57
|
+
status: 'draft' | 'published' | 'archived';
|
|
58
|
+
product_type: 'simple' | 'variable';
|
|
59
|
+
data: string;
|
|
60
|
+
created_at: number;
|
|
61
|
+
updated_at: number;
|
|
62
|
+
}
|
|
63
|
+
export interface ProductVariant {
|
|
64
|
+
id: string;
|
|
65
|
+
product_id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
price?: number;
|
|
68
|
+
stock_quantity: number;
|
|
69
|
+
attributes: string;
|
|
70
|
+
created_at: number;
|
|
71
|
+
}
|
|
72
|
+
export interface Order {
|
|
73
|
+
id: string;
|
|
74
|
+
project_id: string;
|
|
75
|
+
order_number: string;
|
|
76
|
+
email: string;
|
|
77
|
+
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
|
|
78
|
+
payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
|
|
79
|
+
fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
|
|
80
|
+
currency: string;
|
|
81
|
+
subtotal: number;
|
|
82
|
+
grand_total: number;
|
|
83
|
+
created_at: number;
|
|
84
|
+
}
|
|
85
|
+
export interface Cart {
|
|
86
|
+
id: string;
|
|
87
|
+
project_id: string;
|
|
88
|
+
items: CartItem[];
|
|
89
|
+
created_at: number;
|
|
90
|
+
updated_at: number;
|
|
91
|
+
expires_at: number;
|
|
92
|
+
coupon_code?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface CartItem {
|
|
95
|
+
id: string;
|
|
96
|
+
product_id: string;
|
|
97
|
+
variant_id?: string;
|
|
98
|
+
name: string;
|
|
99
|
+
price: number;
|
|
100
|
+
quantity: number;
|
|
101
|
+
thumbnail_url?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface Customer {
|
|
104
|
+
id: string;
|
|
105
|
+
project_id: string;
|
|
106
|
+
email: string;
|
|
107
|
+
first_name?: string | null;
|
|
108
|
+
last_name?: string | null;
|
|
109
|
+
phone?: string | null;
|
|
110
|
+
created_at: number;
|
|
111
|
+
}
|
|
112
|
+
export interface AerostackRPC {
|
|
113
|
+
db: {
|
|
114
|
+
query<T = any>(sql: string, params?: any[]): Promise<T[]>;
|
|
115
|
+
};
|
|
116
|
+
cache: {
|
|
117
|
+
get<T = any>(key: string): Promise<{
|
|
118
|
+
value: T | null;
|
|
119
|
+
exists: boolean;
|
|
120
|
+
}>;
|
|
121
|
+
set(key: string, value: any, ttl?: number): Promise<{
|
|
122
|
+
success: boolean;
|
|
123
|
+
}>;
|
|
124
|
+
delete(key: string): Promise<{
|
|
125
|
+
success: boolean;
|
|
126
|
+
}>;
|
|
127
|
+
};
|
|
128
|
+
queue: {
|
|
129
|
+
enqueue(type: string, data: any): Promise<{
|
|
130
|
+
success: boolean;
|
|
131
|
+
jobId: string;
|
|
132
|
+
}>;
|
|
133
|
+
};
|
|
134
|
+
ai: {
|
|
135
|
+
chat(messages: Array<{
|
|
136
|
+
role: 'user' | 'assistant' | 'system';
|
|
137
|
+
content: string;
|
|
138
|
+
}>, model?: string): Promise<{
|
|
139
|
+
response: string;
|
|
140
|
+
}>;
|
|
141
|
+
search: {
|
|
142
|
+
ingest(content: string, metadata?: Record<string, any>, type?: string): Promise<{
|
|
143
|
+
success: boolean;
|
|
144
|
+
}>;
|
|
145
|
+
query(text: string, options?: {
|
|
146
|
+
limit?: number;
|
|
147
|
+
threshold?: number;
|
|
148
|
+
filter?: Record<string, any>;
|
|
149
|
+
}): Promise<{
|
|
150
|
+
results: any[];
|
|
151
|
+
}>;
|
|
152
|
+
delete(id: string): Promise<{
|
|
153
|
+
success: boolean;
|
|
154
|
+
}>;
|
|
155
|
+
deleteByType(type: string): Promise<{
|
|
156
|
+
success: boolean;
|
|
157
|
+
}>;
|
|
158
|
+
listTypes(): Promise<{
|
|
159
|
+
types: string[];
|
|
160
|
+
}>;
|
|
161
|
+
configure(options: {
|
|
162
|
+
embeddingModel: string;
|
|
163
|
+
}): Promise<{
|
|
164
|
+
success: boolean;
|
|
165
|
+
}>;
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
storage: {
|
|
169
|
+
upload(key: string, file: any, contentType?: string): Promise<{
|
|
170
|
+
url: string;
|
|
171
|
+
}>;
|
|
172
|
+
};
|
|
173
|
+
services: {
|
|
174
|
+
invoke<T = any>(serviceName: string, data?: any): Promise<{
|
|
175
|
+
success: true;
|
|
176
|
+
result: T;
|
|
177
|
+
}>;
|
|
178
|
+
};
|
|
179
|
+
auth: {
|
|
180
|
+
signup(data: {
|
|
181
|
+
email: string;
|
|
182
|
+
password: string;
|
|
183
|
+
name?: string;
|
|
184
|
+
customFields?: Record<string, any>;
|
|
185
|
+
}): Promise<{
|
|
186
|
+
token: string;
|
|
187
|
+
user: any;
|
|
188
|
+
}>;
|
|
189
|
+
signin(data: {
|
|
190
|
+
email: string;
|
|
191
|
+
password: string;
|
|
192
|
+
}): Promise<{
|
|
193
|
+
token: string;
|
|
194
|
+
user: any;
|
|
195
|
+
}>;
|
|
196
|
+
};
|
|
197
|
+
collections(slug: string): {
|
|
198
|
+
list(options?: {
|
|
199
|
+
status?: 'draft' | 'published';
|
|
200
|
+
limit?: number;
|
|
201
|
+
}): Promise<CollectionItem[]>;
|
|
202
|
+
get(itemId: string): Promise<CollectionItem>;
|
|
203
|
+
create(item: {
|
|
204
|
+
slug: string;
|
|
205
|
+
data: Record<string, any>;
|
|
206
|
+
status?: 'draft' | 'published';
|
|
207
|
+
author_id?: string;
|
|
208
|
+
}): Promise<CollectionItem>;
|
|
209
|
+
update(itemId: string, item: Partial<{
|
|
210
|
+
slug: string;
|
|
211
|
+
data: Record<string, any>;
|
|
212
|
+
status: string;
|
|
213
|
+
author_id?: string;
|
|
214
|
+
}>): Promise<{
|
|
215
|
+
success: boolean;
|
|
216
|
+
}>;
|
|
217
|
+
delete(itemId: string): Promise<{
|
|
218
|
+
success: boolean;
|
|
219
|
+
}>;
|
|
220
|
+
};
|
|
221
|
+
ecommerce(): {
|
|
222
|
+
config(): Promise<StoreConfig>;
|
|
223
|
+
products: {
|
|
224
|
+
list(options?: {
|
|
225
|
+
category?: string;
|
|
226
|
+
page?: number;
|
|
227
|
+
limit?: number;
|
|
228
|
+
search?: string;
|
|
229
|
+
}): Promise<{
|
|
230
|
+
products: Product[];
|
|
231
|
+
total: number;
|
|
232
|
+
page: number;
|
|
233
|
+
limit: number;
|
|
234
|
+
}>;
|
|
235
|
+
get(slugOrId: string): Promise<{
|
|
236
|
+
product: Product & {
|
|
237
|
+
variants: ProductVariant[];
|
|
238
|
+
};
|
|
239
|
+
}>;
|
|
240
|
+
};
|
|
241
|
+
categories: {
|
|
242
|
+
list(): Promise<{
|
|
243
|
+
categories: Category[];
|
|
244
|
+
total: number;
|
|
245
|
+
}>;
|
|
246
|
+
};
|
|
247
|
+
cart(cartId: string): {
|
|
248
|
+
get(): Promise<Cart>;
|
|
249
|
+
addItem(item: {
|
|
250
|
+
productId: string;
|
|
251
|
+
variant_id?: string;
|
|
252
|
+
quantity?: number;
|
|
253
|
+
}): Promise<Cart>;
|
|
254
|
+
};
|
|
255
|
+
applyCoupon(code: string): Promise<{
|
|
256
|
+
valid: boolean;
|
|
257
|
+
discount_amount: number;
|
|
258
|
+
message?: string;
|
|
259
|
+
}>;
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
export interface CollectionItem {
|
|
263
|
+
id: string;
|
|
264
|
+
collection_id: string;
|
|
265
|
+
slug: string;
|
|
266
|
+
data: any;
|
|
267
|
+
status: 'draft' | 'published';
|
|
268
|
+
author_id?: string;
|
|
269
|
+
created_at: number;
|
|
270
|
+
updated_at: number;
|
|
271
|
+
}
|
|
272
|
+
export interface StoreConfig {
|
|
273
|
+
default_currency: string;
|
|
274
|
+
currency_symbol: string;
|
|
275
|
+
tax_percentage: number;
|
|
276
|
+
flat_shipping_rate: number;
|
|
277
|
+
free_shipping_threshold?: number;
|
|
278
|
+
shipping_enabled: boolean;
|
|
279
|
+
payment_provider?: string;
|
|
280
|
+
}
|
|
281
|
+
export interface Category {
|
|
282
|
+
id: string;
|
|
283
|
+
name: string;
|
|
284
|
+
slug: string;
|
|
285
|
+
description?: string;
|
|
286
|
+
image_url?: string;
|
|
287
|
+
sort_order: number;
|
|
288
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aerostack/core",
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "Shared types and RPC client for Aerostack SDKs",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"zod": "^4.3.6"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.3.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Product, Order, Cart, Customer, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
|
|
2
|
+
|
|
3
|
+
export interface AerocallConfig {
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
jwt?: string;
|
|
7
|
+
projectId?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class AerocallClient implements AerostackRPC {
|
|
11
|
+
private baseUrl: string;
|
|
12
|
+
private apiKey?: string;
|
|
13
|
+
private jwt?: string;
|
|
14
|
+
private projectId?: string;
|
|
15
|
+
|
|
16
|
+
constructor(config: AerocallConfig) {
|
|
17
|
+
this.baseUrl = config.baseUrl || 'https://api.aerocall.ai/v1';
|
|
18
|
+
this.apiKey = config.apiKey;
|
|
19
|
+
this.jwt = config.jwt;
|
|
20
|
+
this.projectId = config.projectId;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private async request<T>(path: string, method: string, body?: any, isMultipart = false): Promise<T> {
|
|
24
|
+
const headers: Record<string, string> = {
|
|
25
|
+
'X-SDK-Version': '0.4.0'
|
|
26
|
+
};
|
|
27
|
+
if (!isMultipart) {
|
|
28
|
+
headers['Content-Type'] = 'application/json';
|
|
29
|
+
}
|
|
30
|
+
if (this.apiKey) headers['X-API-Key'] = this.apiKey;
|
|
31
|
+
if (this.jwt) headers['Authorization'] = `Bearer ${this.jwt}`;
|
|
32
|
+
if (this.projectId) headers['X-Project-Id'] = this.projectId;
|
|
33
|
+
|
|
34
|
+
headers['X-Request-ID'] = crypto.randomUUID();
|
|
35
|
+
|
|
36
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
37
|
+
method,
|
|
38
|
+
headers,
|
|
39
|
+
body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
|
|
44
|
+
throw new Error((err as any).error?.message || 'Unknown error');
|
|
45
|
+
}
|
|
46
|
+
return response.json() as Promise<T>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public get db() {
|
|
50
|
+
return {
|
|
51
|
+
query: async <T = any>(sql: string, params?: any[]) => {
|
|
52
|
+
const res = await this.request<{ results: T[]; meta?: any }>('/db/query', 'POST', { sql, params });
|
|
53
|
+
return (res?.results ?? []) as T[];
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public get cache() {
|
|
59
|
+
return {
|
|
60
|
+
get: <T = any>(key: string) => this.request<{ value: T | null, exists: boolean }>('/cache/get', 'POST', { key }),
|
|
61
|
+
set: (key: string, value: any, ttl?: number) => this.request<{ success: boolean }>('/cache/set', 'POST', { key, value, ttl }),
|
|
62
|
+
delete: (key: string) => this.request<{ success: boolean }>('/cache/delete', 'POST', { key })
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public get queue() {
|
|
67
|
+
return {
|
|
68
|
+
enqueue: (type: string, data: any) => this.request<{ success: boolean; jobId: string }>('/queue/enqueue', 'POST', { type, data })
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public get ai() {
|
|
73
|
+
return {
|
|
74
|
+
chat: (messages: { role: 'user' | 'assistant' | 'system'; content: string }[], model?: string) =>
|
|
75
|
+
this.request<{ response: string }>('/ai/chat', 'POST', { messages, model }),
|
|
76
|
+
search: {
|
|
77
|
+
ingest: (content: string, metadata?: Record<string, any>, type?: string) =>
|
|
78
|
+
this.request<{ success: boolean }>('/ai/search/ingest', 'POST', { content, metadata, type }),
|
|
79
|
+
query: (text: string, options?: { limit?: number; threshold?: number; filter?: Record<string, any> }) =>
|
|
80
|
+
this.request<{ results: any[] }>('/ai/search/query', 'POST', { text, ...options }),
|
|
81
|
+
delete: (id: string) => this.request<{ success: boolean }>('/ai/search/delete', 'POST', { id }),
|
|
82
|
+
deleteByType: (type: string) => this.request<{ success: boolean }>('/ai/search/deleteByType', 'POST', { type }),
|
|
83
|
+
listTypes: () => this.request<{ types: string[] }>('/ai/search/listTypes', 'GET'),
|
|
84
|
+
configure: (options: { embeddingModel: string }) => this.request<{ success: boolean }>('/ai/search/configure', 'POST', options)
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public get storage() {
|
|
90
|
+
return {
|
|
91
|
+
upload: (key: string, file: File | Blob, contentType?: string) => {
|
|
92
|
+
const formData = new FormData();
|
|
93
|
+
formData.append('key', key);
|
|
94
|
+
formData.append('file', file);
|
|
95
|
+
if (contentType) formData.append('contentType', contentType);
|
|
96
|
+
return this.request<{ url: string }>('/storage/upload', 'POST', formData, true);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public get services() {
|
|
102
|
+
return {
|
|
103
|
+
invoke: <T = any>(serviceName: string, data?: any) => this.request<{ success: true, result: T }>('/services/invoke', 'POST', { serviceName, data })
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public get auth() {
|
|
108
|
+
return {
|
|
109
|
+
signup: (data: { email: string; password: string; name?: string; customFields?: Record<string, any> }) =>
|
|
110
|
+
this.request<{ token: string; user: any }>('/auth/signup', 'POST', data),
|
|
111
|
+
signin: (data: { email: string; password: string }) =>
|
|
112
|
+
this.request<{ token: string; user: any }>('/auth/signin', 'POST', data),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public collections(slug: string) {
|
|
117
|
+
return {
|
|
118
|
+
list: (options?: { status?: 'draft' | 'published'; limit?: number }) =>
|
|
119
|
+
this.request<CollectionItem[]>(`/collections/${slug}/items`, 'GET', options),
|
|
120
|
+
get: (itemId: string) =>
|
|
121
|
+
this.request<CollectionItem>(`/collections/${slug}/items/${itemId}`, 'GET'),
|
|
122
|
+
create: (item: { slug: string; data: Record<string, any>; status?: 'draft' | 'published'; author_id?: string }) =>
|
|
123
|
+
this.request<CollectionItem>(`/collections/${slug}/items`, 'POST', item),
|
|
124
|
+
update: (itemId: string, item: Partial<{ slug: string; data: Record<string, any>; status: string; author_id?: string }>) =>
|
|
125
|
+
this.request<{ success: boolean }>(`/collections/${slug}/items/${itemId}`, 'PUT', item),
|
|
126
|
+
delete: (itemId: string) =>
|
|
127
|
+
this.request<{ success: boolean }>(`/collections/${slug}/items/${itemId}`, 'DELETE'),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public ecommerce() {
|
|
132
|
+
return {
|
|
133
|
+
config: () => this.request<StoreConfig>('/ecommerce/config', 'GET'),
|
|
134
|
+
products: {
|
|
135
|
+
list: (options?: { category?: string; page?: number; limit?: number; search?: string }) =>
|
|
136
|
+
this.request<{ products: Product[]; total: number; page: number; limit: number }>('/ecommerce/products', 'GET', options),
|
|
137
|
+
get: (slugOrId: string) =>
|
|
138
|
+
this.request<{ product: Product & { variants: ProductVariant[] } }>(`/ecommerce/products/${slugOrId}`, 'GET'),
|
|
139
|
+
},
|
|
140
|
+
categories: {
|
|
141
|
+
list: () => this.request<{ categories: Category[]; total: number }>('/ecommerce/categories', 'GET'),
|
|
142
|
+
},
|
|
143
|
+
cart: (cartId: string) => ({
|
|
144
|
+
get: () => this.request<Cart>(`/ecommerce/cart/${cartId}`, 'GET'),
|
|
145
|
+
addItem: (item: { productId: string; variant_id?: string; quantity?: number }) =>
|
|
146
|
+
this.request<Cart>(`/ecommerce/cart/${cartId}/items`, 'POST', item),
|
|
147
|
+
}),
|
|
148
|
+
applyCoupon: (code: string) => this.request<{ valid: boolean; discount_amount: number; message?: string }>('/ecommerce/coupons/validate', 'POST', { code }),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// The schema is versioned to allow backwards compatibility
|
|
4
|
+
// Version 1 of the schema
|
|
5
|
+
export const RegistryConfigSchemaV1 = z.object({
|
|
6
|
+
$schema: z.string().url().optional(),
|
|
7
|
+
name: z.string()
|
|
8
|
+
.min(2, "Name must be at least 2 characters")
|
|
9
|
+
.max(50, "Name must be less than 50 characters")
|
|
10
|
+
.regex(/^[a-z0-9-]+$/, "Name can only contain lowercase letters, numbers, and hyphens"),
|
|
11
|
+
version: z.string()
|
|
12
|
+
.regex(/^\d+\.\d+\.\d+$/, "Version must follow semantic versioning (e.g., 1.0.0)"),
|
|
13
|
+
description: z.string().min(10, "Description must be at least 10 characters"),
|
|
14
|
+
author: z.string().optional(),
|
|
15
|
+
type: z.enum(['feature', 'utility', 'hook']),
|
|
16
|
+
dependencies: z.array(z.string()).optional().default([]),
|
|
17
|
+
registryDependencies: z.array(z.string()).optional().default([]),
|
|
18
|
+
files: z.array(z.object({
|
|
19
|
+
source: z.string(),
|
|
20
|
+
target: z.string(),
|
|
21
|
+
})).min(1, "At least one file mapping is required").optional().default([]),
|
|
22
|
+
configuration: z.object({
|
|
23
|
+
api_route: z.string().optional(),
|
|
24
|
+
env: z.array(z.string()).optional().default([]),
|
|
25
|
+
}).optional().default({ env: [] }),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export type RegistryConfigV1 = z.infer<typeof RegistryConfigSchemaV1>;
|
|
29
|
+
|
|
30
|
+
// Current registry schema version
|
|
31
|
+
export const RegistryConfigSchema = RegistryConfigSchemaV1;
|
|
32
|
+
|
|
33
|
+
export type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validates a configuration payload against the registry schema.
|
|
37
|
+
* @param config The raw configuration object
|
|
38
|
+
* @returns The successfully parsed and validated configuration, or throws a ZodError
|
|
39
|
+
*/
|
|
40
|
+
export function validateRegistryConfig(config: unknown): RegistryConfig {
|
|
41
|
+
return RegistryConfigSchema.parse(config);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Safely validates a configuration payload against the registry schema.
|
|
46
|
+
* @param config The raw configuration object
|
|
47
|
+
* @returns An object conforming to SafeParseReturnType indicating whether validation was successful
|
|
48
|
+
*/
|
|
49
|
+
export function safeValidateRegistryConfig(config: unknown) {
|
|
50
|
+
return RegistryConfigSchema.safeParse(config);
|
|
51
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface AerostackGatewayConfig {
|
|
2
|
+
models?: Array<{
|
|
3
|
+
id: string;
|
|
4
|
+
provider: string;
|
|
5
|
+
model: string;
|
|
6
|
+
role: string;
|
|
7
|
+
system_prompt?: string;
|
|
8
|
+
max_tokens?: number;
|
|
9
|
+
temperature?: number;
|
|
10
|
+
endpoint?: string;
|
|
11
|
+
format?: string;
|
|
12
|
+
}>;
|
|
13
|
+
routing?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface GatewayMonetizationConfig {
|
|
17
|
+
managed_in_dashboard?: boolean;
|
|
18
|
+
billing_model: 'subscription' | 'pay_as_you_go' | 'freemium' | 'per_token' | 'per_minute';
|
|
19
|
+
credit_topup_enabled?: boolean;
|
|
20
|
+
per_model_cost_tracking?: boolean;
|
|
21
|
+
pricePer1kTokens?: number;
|
|
22
|
+
monthlyPrice?: number;
|
|
23
|
+
includedTokens?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GatewaySecurityConfig {
|
|
27
|
+
require_api_key?: boolean;
|
|
28
|
+
rate_limit?: {
|
|
29
|
+
strategy: string;
|
|
30
|
+
requests_per_minute: number;
|
|
31
|
+
burst: number;
|
|
32
|
+
};
|
|
33
|
+
allowed_origins?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface GatewayBillingPayload {
|
|
37
|
+
consumerId: string;
|
|
38
|
+
developerApiId: string;
|
|
39
|
+
metric?: string;
|
|
40
|
+
units: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ConsumerKeyResponse {
|
|
44
|
+
key: string;
|
|
45
|
+
name?: string;
|
|
46
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
export interface User {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
avatar_url?: string;
|
|
6
|
+
created_at: number;
|
|
7
|
+
last_login_at?: number;
|
|
8
|
+
project_id?: string | null;
|
|
9
|
+
email_verified_at?: number;
|
|
10
|
+
phone?: string | null;
|
|
11
|
+
phone_verified_at?: number | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Project {
|
|
15
|
+
id: string;
|
|
16
|
+
user_id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
slug: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
created_at: number;
|
|
21
|
+
updated_at: number;
|
|
22
|
+
is_public: number;
|
|
23
|
+
plan: 'free' | 'pro' | 'enterprise';
|
|
24
|
+
subdomain?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface Component {
|
|
28
|
+
id: string;
|
|
29
|
+
project_id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
schema: any;
|
|
32
|
+
status: 'processing' | 'completed' | 'failed';
|
|
33
|
+
created_at: number;
|
|
34
|
+
updated_at: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface Page {
|
|
38
|
+
id: string;
|
|
39
|
+
project_id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
slug: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
type: 'static' | 'collection' | 'dynamic';
|
|
44
|
+
status: 'draft' | 'published' | 'archived';
|
|
45
|
+
meta_title?: string;
|
|
46
|
+
meta_description?: string;
|
|
47
|
+
published_at?: number;
|
|
48
|
+
created_at: number;
|
|
49
|
+
updated_at: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface Product {
|
|
53
|
+
id: string;
|
|
54
|
+
project_id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
slug: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
thumbnail_url?: string;
|
|
59
|
+
base_price: number;
|
|
60
|
+
compare_at_price?: number;
|
|
61
|
+
status: 'draft' | 'published' | 'archived';
|
|
62
|
+
product_type: 'simple' | 'variable';
|
|
63
|
+
data: string;
|
|
64
|
+
created_at: number;
|
|
65
|
+
updated_at: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ProductVariant {
|
|
69
|
+
id: string;
|
|
70
|
+
product_id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
price?: number;
|
|
73
|
+
stock_quantity: number;
|
|
74
|
+
attributes: string;
|
|
75
|
+
created_at: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface Order {
|
|
79
|
+
id: string;
|
|
80
|
+
project_id: string;
|
|
81
|
+
order_number: string;
|
|
82
|
+
email: string;
|
|
83
|
+
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
|
|
84
|
+
payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
|
|
85
|
+
fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
|
|
86
|
+
currency: string;
|
|
87
|
+
subtotal: number;
|
|
88
|
+
grand_total: number;
|
|
89
|
+
created_at: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface Cart {
|
|
93
|
+
id: string;
|
|
94
|
+
project_id: string;
|
|
95
|
+
items: CartItem[];
|
|
96
|
+
created_at: number;
|
|
97
|
+
updated_at: number;
|
|
98
|
+
expires_at: number;
|
|
99
|
+
coupon_code?: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface CartItem {
|
|
103
|
+
id: string;
|
|
104
|
+
product_id: string;
|
|
105
|
+
variant_id?: string;
|
|
106
|
+
name: string;
|
|
107
|
+
price: number;
|
|
108
|
+
quantity: number;
|
|
109
|
+
thumbnail_url?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface Customer {
|
|
113
|
+
id: string;
|
|
114
|
+
project_id: string;
|
|
115
|
+
email: string;
|
|
116
|
+
first_name?: string | null;
|
|
117
|
+
last_name?: string | null;
|
|
118
|
+
phone?: string | null;
|
|
119
|
+
created_at: number;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface AerostackRPC {
|
|
123
|
+
db: {
|
|
124
|
+
query<T = any>(sql: string, params?: any[]): Promise<T[]>;
|
|
125
|
+
};
|
|
126
|
+
cache: {
|
|
127
|
+
get<T = any>(key: string): Promise<{ value: T | null; exists: boolean }>;
|
|
128
|
+
set(key: string, value: any, ttl?: number): Promise<{ success: boolean }>;
|
|
129
|
+
delete(key: string): Promise<{ success: boolean }>;
|
|
130
|
+
};
|
|
131
|
+
queue: {
|
|
132
|
+
enqueue(type: string, data: any): Promise<{ success: boolean; jobId: string }>;
|
|
133
|
+
};
|
|
134
|
+
ai: {
|
|
135
|
+
chat(messages: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>, model?: string): Promise<{ response: string }>;
|
|
136
|
+
search: {
|
|
137
|
+
ingest(content: string, metadata?: Record<string, any>, type?: string): Promise<{ success: boolean }>;
|
|
138
|
+
query(text: string, options?: { limit?: number; threshold?: number; filter?: Record<string, any> }): Promise<{ results: any[] }>;
|
|
139
|
+
delete(id: string): Promise<{ success: boolean }>;
|
|
140
|
+
deleteByType(type: string): Promise<{ success: boolean }>;
|
|
141
|
+
listTypes(): Promise<{ types: string[] }>;
|
|
142
|
+
configure(options: { embeddingModel: string }): Promise<{ success: boolean }>;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
storage: {
|
|
146
|
+
upload(key: string, file: any, contentType?: string): Promise<{ url: string }>;
|
|
147
|
+
};
|
|
148
|
+
services: {
|
|
149
|
+
invoke<T = any>(serviceName: string, data?: any): Promise<{ success: true; result: T }>;
|
|
150
|
+
};
|
|
151
|
+
auth: {
|
|
152
|
+
signup(data: { email: string; password: string; name?: string; customFields?: Record<string, any> }): Promise<{ token: string; user: any }>;
|
|
153
|
+
signin(data: { email: string; password: string }): Promise<{ token: string; user: any }>;
|
|
154
|
+
};
|
|
155
|
+
collections(slug: string): {
|
|
156
|
+
list(options?: { status?: 'draft' | 'published'; limit?: number }): Promise<CollectionItem[]>;
|
|
157
|
+
get(itemId: string): Promise<CollectionItem>;
|
|
158
|
+
create(item: { slug: string; data: Record<string, any>; status?: 'draft' | 'published'; author_id?: string }): Promise<CollectionItem>;
|
|
159
|
+
update(itemId: string, item: Partial<{ slug: string; data: Record<string, any>; status: string; author_id?: string }>): Promise<{ success: boolean }>;
|
|
160
|
+
delete(itemId: string): Promise<{ success: boolean }>;
|
|
161
|
+
};
|
|
162
|
+
ecommerce(): {
|
|
163
|
+
config(): Promise<StoreConfig>;
|
|
164
|
+
products: {
|
|
165
|
+
list(options?: { category?: string; page?: number; limit?: number; search?: string }): Promise<{ products: Product[]; total: number; page: number; limit: number }>;
|
|
166
|
+
get(slugOrId: string): Promise<{ product: Product & { variants: ProductVariant[] } }>;
|
|
167
|
+
};
|
|
168
|
+
categories: {
|
|
169
|
+
list(): Promise<{ categories: Category[]; total: number }>;
|
|
170
|
+
};
|
|
171
|
+
cart(cartId: string): {
|
|
172
|
+
get(): Promise<Cart>;
|
|
173
|
+
addItem(item: { productId: string; variant_id?: string; quantity?: number }): Promise<Cart>;
|
|
174
|
+
};
|
|
175
|
+
applyCoupon(code: string): Promise<{ valid: boolean; discount_amount: number; message?: string }>;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface CollectionItem {
|
|
180
|
+
id: string;
|
|
181
|
+
collection_id: string;
|
|
182
|
+
slug: string;
|
|
183
|
+
data: any;
|
|
184
|
+
status: 'draft' | 'published';
|
|
185
|
+
author_id?: string;
|
|
186
|
+
created_at: number;
|
|
187
|
+
updated_at: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface StoreConfig {
|
|
191
|
+
default_currency: string;
|
|
192
|
+
currency_symbol: string;
|
|
193
|
+
tax_percentage: number;
|
|
194
|
+
flat_shipping_rate: number;
|
|
195
|
+
free_shipping_threshold?: number;
|
|
196
|
+
shipping_enabled: boolean;
|
|
197
|
+
payment_provider?: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface Category {
|
|
201
|
+
id: string;
|
|
202
|
+
name: string;
|
|
203
|
+
slug: string;
|
|
204
|
+
description?: string;
|
|
205
|
+
image_url?: string;
|
|
206
|
+
sort_order: number;
|
|
207
|
+
}
|