@layers/amba-node 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/index.d.ts +248 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +175 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @layers/amba-node
|
|
2
|
+
|
|
3
|
+
Node.js SDK for [amba](https://amba.dev). Server-side companion to `@layers/amba-web` — same 25-namespace surface, idiomatic Node ergonomics.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @layers/amba-node
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { AmbaClient } from "@layers/amba-node";
|
|
15
|
+
|
|
16
|
+
const amba = await AmbaClient.configure({
|
|
17
|
+
apiKey: process.env.AMBA_API_KEY!,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
await amba.events.track("webhook_received", { source: "stripe" });
|
|
21
|
+
|
|
22
|
+
const { data: orders } = await amba.collections.find("orders", {
|
|
23
|
+
filter: amba.collections.where.eq("status", "paid"),
|
|
24
|
+
limit: 100,
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Express middleware
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import express from "express";
|
|
32
|
+
import { AmbaClient } from "@layers/amba-node";
|
|
33
|
+
|
|
34
|
+
const amba = await AmbaClient.configure({ apiKey: process.env.AMBA_API_KEY! });
|
|
35
|
+
const app = express();
|
|
36
|
+
app.use(amba.middleware());
|
|
37
|
+
|
|
38
|
+
app.post("/webhook", (req, res) => {
|
|
39
|
+
req.amba.events.track("webhook_received");
|
|
40
|
+
res.sendStatus(204);
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
MIT.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface AmbaConfig {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
consentRequired?: boolean;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
}
|
|
8
|
+
type SocialProvider = "apple" | "google";
|
|
9
|
+
type PushPlatform = "apns" | "fcm" | "web";
|
|
10
|
+
interface User {
|
|
11
|
+
id: string;
|
|
12
|
+
email?: string | null;
|
|
13
|
+
display_name?: string | null;
|
|
14
|
+
avatar_url?: string | null;
|
|
15
|
+
external_id?: string | null;
|
|
16
|
+
anonymous_id?: string | null;
|
|
17
|
+
auth_providers: string[];
|
|
18
|
+
properties: Record<string, unknown>;
|
|
19
|
+
first_seen_at?: string;
|
|
20
|
+
last_seen_at?: string;
|
|
21
|
+
created_at?: string;
|
|
22
|
+
updated_at?: string;
|
|
23
|
+
}
|
|
24
|
+
interface AuthResult {
|
|
25
|
+
session_token: string;
|
|
26
|
+
refresh_token: string;
|
|
27
|
+
user: User;
|
|
28
|
+
anonymous_id?: string | null;
|
|
29
|
+
expires_at?: string | null;
|
|
30
|
+
}
|
|
31
|
+
type FilterValue = string | number | boolean | null | unknown[];
|
|
32
|
+
interface ConditionFilter {
|
|
33
|
+
column: string;
|
|
34
|
+
op: string;
|
|
35
|
+
value?: FilterValue;
|
|
36
|
+
}
|
|
37
|
+
interface AndFilter {
|
|
38
|
+
and: Filter[];
|
|
39
|
+
}
|
|
40
|
+
interface OrFilter {
|
|
41
|
+
or: Filter[];
|
|
42
|
+
}
|
|
43
|
+
interface NotFilter {
|
|
44
|
+
not: Filter;
|
|
45
|
+
}
|
|
46
|
+
type Filter = ConditionFilter | AndFilter | OrFilter | NotFilter;
|
|
47
|
+
interface OrderBy {
|
|
48
|
+
column: string;
|
|
49
|
+
direction: "asc" | "desc";
|
|
50
|
+
}
|
|
51
|
+
interface FindOptions {
|
|
52
|
+
filter?: Filter;
|
|
53
|
+
order?: OrderBy[];
|
|
54
|
+
limit?: number;
|
|
55
|
+
cursor?: string;
|
|
56
|
+
select?: string[];
|
|
57
|
+
include_deleted?: boolean;
|
|
58
|
+
}
|
|
59
|
+
interface FindResponse<T> {
|
|
60
|
+
data: T[];
|
|
61
|
+
next_cursor?: string | null;
|
|
62
|
+
has_more: boolean;
|
|
63
|
+
}
|
|
64
|
+
interface MediaAsset {
|
|
65
|
+
id: string;
|
|
66
|
+
bucket: string;
|
|
67
|
+
key: string;
|
|
68
|
+
url: string;
|
|
69
|
+
mime_type: string;
|
|
70
|
+
size_bytes: number;
|
|
71
|
+
width?: number | null;
|
|
72
|
+
height?: number | null;
|
|
73
|
+
retention_days?: number | null;
|
|
74
|
+
created_at: string;
|
|
75
|
+
}
|
|
76
|
+
interface PresignData {
|
|
77
|
+
upload_id: string;
|
|
78
|
+
upload_url: string;
|
|
79
|
+
upload_headers: Array<[string, string]>;
|
|
80
|
+
asset_id: string;
|
|
81
|
+
}
|
|
82
|
+
interface PushToken {
|
|
83
|
+
id: string;
|
|
84
|
+
token: string;
|
|
85
|
+
platform: PushPlatform;
|
|
86
|
+
bundle_id?: string | null;
|
|
87
|
+
created_at: string;
|
|
88
|
+
}
|
|
89
|
+
type EntitlementSource = "revenue_cat" | "app_store" | "play_store" | "stripe" | "promo_code" | "manual";
|
|
90
|
+
interface UserEntitlement {
|
|
91
|
+
id: string;
|
|
92
|
+
name: string;
|
|
93
|
+
is_active: boolean;
|
|
94
|
+
source: EntitlementSource;
|
|
95
|
+
expires_at?: string | null;
|
|
96
|
+
granted_at?: string | null;
|
|
97
|
+
metadata: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
interface AiMessage {
|
|
100
|
+
role: string;
|
|
101
|
+
content: unknown;
|
|
102
|
+
}
|
|
103
|
+
interface AiMessageRequest {
|
|
104
|
+
prompt_slug: string;
|
|
105
|
+
variables?: Record<string, unknown>;
|
|
106
|
+
messages?: AiMessage[];
|
|
107
|
+
max_tokens?: number;
|
|
108
|
+
temperature?: number;
|
|
109
|
+
enable_prompt_cache?: boolean;
|
|
110
|
+
}
|
|
111
|
+
interface AiUsage {
|
|
112
|
+
input_tokens: number;
|
|
113
|
+
output_tokens: number;
|
|
114
|
+
cache_creation_input_tokens?: number;
|
|
115
|
+
cache_read_input_tokens?: number;
|
|
116
|
+
}
|
|
117
|
+
interface AiMessageResponse {
|
|
118
|
+
content: unknown[];
|
|
119
|
+
usage: AiUsage;
|
|
120
|
+
stop_reason?: string | null;
|
|
121
|
+
model: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Resolved remote config returned by `config.fetch()`.
|
|
125
|
+
*
|
|
126
|
+
* Server: `GET /v1/client/config` returns body `{ "data": { key → value, ... } }`
|
|
127
|
+
* plus an `ETag` response header carrying the version stamp. `version`
|
|
128
|
+
* is parsed from the ETag prefix; `null` when the server didn't send one.
|
|
129
|
+
*/
|
|
130
|
+
interface ConfigBundle {
|
|
131
|
+
version: string | null;
|
|
132
|
+
values: Record<string, unknown>;
|
|
133
|
+
}
|
|
134
|
+
interface FlagAssignment {
|
|
135
|
+
name: string;
|
|
136
|
+
enabled: boolean;
|
|
137
|
+
variant?: string | null;
|
|
138
|
+
payload?: unknown;
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/index.d.ts
|
|
142
|
+
|
|
143
|
+
declare class AmbaClient {
|
|
144
|
+
private readonly core;
|
|
145
|
+
private constructor();
|
|
146
|
+
static configure(config: AmbaConfig): Promise<AmbaClient>;
|
|
147
|
+
get anonymousId(): string;
|
|
148
|
+
get appUserId(): string | undefined;
|
|
149
|
+
get isAuthenticated(): boolean;
|
|
150
|
+
setDebug(enabled: boolean): void;
|
|
151
|
+
events: {
|
|
152
|
+
track: (event: string, properties?: Record<string, unknown>) => Promise<void>;
|
|
153
|
+
};
|
|
154
|
+
auth: {
|
|
155
|
+
signInAnonymously: () => Promise<AuthResult>;
|
|
156
|
+
signInWithEmail: (email: string, password: string) => Promise<AuthResult>;
|
|
157
|
+
signUpWithEmail: (email: string, password: string) => Promise<AuthResult>;
|
|
158
|
+
signInWithSocial: (provider: SocialProvider, idToken: string) => Promise<AuthResult>;
|
|
159
|
+
signOut: (rotateAnonymousId?: boolean) => Promise<void>;
|
|
160
|
+
refresh: () => Promise<AuthResult>;
|
|
161
|
+
me: () => Promise<User>;
|
|
162
|
+
};
|
|
163
|
+
collections: {
|
|
164
|
+
find: <T = unknown>(name: string, options?: FindOptions) => Promise<FindResponse<T>>;
|
|
165
|
+
findOne: <T = unknown>(name: string, id: string) => Promise<T>;
|
|
166
|
+
insert: <T = unknown>(name: string, row: Record<string, unknown>) => Promise<T>;
|
|
167
|
+
update: <T = unknown>(name: string, id: string, set: Record<string, unknown>) => Promise<T>;
|
|
168
|
+
delete: (name: string, id: string) => Promise<{
|
|
169
|
+
data: {
|
|
170
|
+
deleted: boolean;
|
|
171
|
+
};
|
|
172
|
+
}>;
|
|
173
|
+
where: {
|
|
174
|
+
eq: (column: string, value: FilterValue) => Filter;
|
|
175
|
+
ne: (column: string, value: FilterValue) => Filter;
|
|
176
|
+
gt: (column: string, value: FilterValue) => Filter;
|
|
177
|
+
gte: (column: string, value: FilterValue) => Filter;
|
|
178
|
+
lt: (column: string, value: FilterValue) => Filter;
|
|
179
|
+
lte: (column: string, value: FilterValue) => Filter;
|
|
180
|
+
in: (column: string, values: FilterValue[]) => Filter;
|
|
181
|
+
notIn: (column: string, values: FilterValue[]) => Filter;
|
|
182
|
+
like: (column: string, pattern: string) => Filter;
|
|
183
|
+
ilike: (column: string, pattern: string) => Filter;
|
|
184
|
+
isNull: (column: string) => Filter;
|
|
185
|
+
isNotNull: (column: string) => Filter;
|
|
186
|
+
and: (...filters: Filter[]) => Filter;
|
|
187
|
+
or: (...filters: Filter[]) => Filter;
|
|
188
|
+
not: (filter: Filter) => Filter;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
storage: {
|
|
192
|
+
presign: (params: {
|
|
193
|
+
bucket: string;
|
|
194
|
+
filename: string;
|
|
195
|
+
mimeType: string;
|
|
196
|
+
sizeBytes: number;
|
|
197
|
+
retentionDays?: number;
|
|
198
|
+
}) => Promise<PresignData>;
|
|
199
|
+
commit: (uploadId: string, assetId: string) => Promise<MediaAsset>;
|
|
200
|
+
};
|
|
201
|
+
push: {
|
|
202
|
+
register: (token: string, platform: PushPlatform, bundleId?: string) => Promise<PushToken>;
|
|
203
|
+
subscribe: (topic: string) => Promise<void>;
|
|
204
|
+
};
|
|
205
|
+
entitlements: {
|
|
206
|
+
list: () => Promise<UserEntitlement[]>;
|
|
207
|
+
has: (name: string) => Promise<boolean>;
|
|
208
|
+
};
|
|
209
|
+
ai: {
|
|
210
|
+
anthropic: {
|
|
211
|
+
messages: {
|
|
212
|
+
create: (request: AiMessageRequest) => Promise<AiMessageResponse>;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
config: {
|
|
217
|
+
fetch: () => Promise<ConfigBundle>;
|
|
218
|
+
};
|
|
219
|
+
flags: {
|
|
220
|
+
fetch: () => Promise<FlagAssignment[]>;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Per-user scoped handle. **Not yet implemented.** A forthcoming
|
|
224
|
+
* release will mint a per-user core with a Bearer token override.
|
|
225
|
+
*
|
|
226
|
+
* For now this throws — earlier we returned `this` unchanged, which
|
|
227
|
+
* meant `asUser('user_123').collections.insert(...)` silently wrote
|
|
228
|
+
* under the *current* authenticated user, a high-severity data
|
|
229
|
+
* integrity footgun. A loud failure is the right interim.
|
|
230
|
+
*
|
|
231
|
+
* If you need per-user writes today, route them through your service
|
|
232
|
+
* identity and store an explicit `user_id` column.
|
|
233
|
+
*/
|
|
234
|
+
asUser(_userId: string): AmbaClient;
|
|
235
|
+
/**
|
|
236
|
+
* Build a Connect/Express-style middleware that attaches `req.amba`
|
|
237
|
+
* to every request. Wraps the SDK so handlers can call amba inline.
|
|
238
|
+
*/
|
|
239
|
+
middleware(): (req: Record<string, unknown>, _res: unknown, next: () => void) => void;
|
|
240
|
+
}
|
|
241
|
+
/** Convenience alias matching `@layers/amba-web`'s `Amba.configure` shape. */
|
|
242
|
+
declare const Amba: {
|
|
243
|
+
configure: typeof AmbaClient.configure;
|
|
244
|
+
};
|
|
245
|
+
declare const SDK_VERSION = "0.1.0";
|
|
246
|
+
//#endregion
|
|
247
|
+
export { AiMessage, AiMessageRequest, AiMessageResponse, AiUsage, Amba, AmbaClient, AmbaConfig, AndFilter, AuthResult, ConditionFilter, ConfigBundle, EntitlementSource, Filter, FilterValue, FindOptions, FindResponse, FlagAssignment, MediaAsset, NotFilter, OrFilter, OrderBy, PresignData, PushPlatform, PushToken, SDK_VERSION, SocialProvider, User, UserEntitlement };
|
|
248
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import init, { AmbaCoreWasm } from "@layers/amba-core-wasm";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
var AmbaClient = class AmbaClient {
|
|
5
|
+
constructor(core) {
|
|
6
|
+
this.core = core;
|
|
7
|
+
}
|
|
8
|
+
static async configure(config) {
|
|
9
|
+
if (!config.apiKey || config.apiKey.trim() === "") throw new Error("AmbaClient.configure: apiKey is required");
|
|
10
|
+
const [{ readFile }, { fileURLToPath, pathToFileURL }, { createRequire }] = await Promise.all([
|
|
11
|
+
import("node:fs/promises"),
|
|
12
|
+
import("node:url"),
|
|
13
|
+
import("node:module")
|
|
14
|
+
]);
|
|
15
|
+
const resolveFn = import.meta.resolve;
|
|
16
|
+
let wasmFileUrl;
|
|
17
|
+
if (resolveFn) wasmFileUrl = await resolveFn("@layers/amba-core-wasm/wasm");
|
|
18
|
+
else wasmFileUrl = pathToFileURL(createRequire(import.meta.url).resolve("@layers/amba-core-wasm/wasm")).href;
|
|
19
|
+
await init(await readFile(fileURLToPath(wasmFileUrl)));
|
|
20
|
+
return new AmbaClient(AmbaCoreWasm.init(JSON.stringify({
|
|
21
|
+
api_key: config.apiKey,
|
|
22
|
+
base_url: config.baseUrl,
|
|
23
|
+
sdk_platform: "node",
|
|
24
|
+
sdk_wrapper_version: `amba-node/${SDK_VERSION}`,
|
|
25
|
+
consent_required: config.consentRequired,
|
|
26
|
+
debug: config.debug
|
|
27
|
+
}), globalThis.fetch.bind(globalThis)));
|
|
28
|
+
}
|
|
29
|
+
get anonymousId() {
|
|
30
|
+
return this.core.anonymousId();
|
|
31
|
+
}
|
|
32
|
+
get appUserId() {
|
|
33
|
+
return this.core.appUserId() ?? void 0;
|
|
34
|
+
}
|
|
35
|
+
get isAuthenticated() {
|
|
36
|
+
return this.core.isAuthenticated();
|
|
37
|
+
}
|
|
38
|
+
setDebug(enabled) {
|
|
39
|
+
this.core.setDebug(enabled);
|
|
40
|
+
}
|
|
41
|
+
events = { track: async (event, properties) => {
|
|
42
|
+
await this.core.track(event, properties ? JSON.stringify(properties) : void 0);
|
|
43
|
+
} };
|
|
44
|
+
auth = {
|
|
45
|
+
signInAnonymously: async () => await this.core.signInAnonymously(),
|
|
46
|
+
signInWithEmail: async (email, password) => await this.core.signInWithEmail(email, password),
|
|
47
|
+
signUpWithEmail: async (email, password) => await this.core.signUpWithEmail(email, password),
|
|
48
|
+
signInWithSocial: async (provider, idToken) => await this.core.signInWithSocial(provider, idToken),
|
|
49
|
+
signOut: async (rotateAnonymousId = false) => {
|
|
50
|
+
await this.core.signOut(rotateAnonymousId);
|
|
51
|
+
},
|
|
52
|
+
refresh: async () => await this.core.refreshSession(),
|
|
53
|
+
me: async () => await this.core.me()
|
|
54
|
+
};
|
|
55
|
+
collections = {
|
|
56
|
+
find: async (name, options = {}) => await this.core.collectionsFind(name, JSON.stringify(options)),
|
|
57
|
+
findOne: async (name, id) => await this.core.collectionsFindOne(name, id),
|
|
58
|
+
insert: async (name, row) => await this.core.collectionsInsert(name, JSON.stringify(row)),
|
|
59
|
+
update: async (name, id, set) => await this.core.collectionsUpdate(name, id, JSON.stringify(set)),
|
|
60
|
+
delete: async (name, id) => await this.core.collectionsDelete(name, id),
|
|
61
|
+
where: {
|
|
62
|
+
eq: (column, value) => ({
|
|
63
|
+
column,
|
|
64
|
+
op: "eq",
|
|
65
|
+
value
|
|
66
|
+
}),
|
|
67
|
+
ne: (column, value) => ({
|
|
68
|
+
column,
|
|
69
|
+
op: "ne",
|
|
70
|
+
value
|
|
71
|
+
}),
|
|
72
|
+
gt: (column, value) => ({
|
|
73
|
+
column,
|
|
74
|
+
op: "gt",
|
|
75
|
+
value
|
|
76
|
+
}),
|
|
77
|
+
gte: (column, value) => ({
|
|
78
|
+
column,
|
|
79
|
+
op: "gte",
|
|
80
|
+
value
|
|
81
|
+
}),
|
|
82
|
+
lt: (column, value) => ({
|
|
83
|
+
column,
|
|
84
|
+
op: "lt",
|
|
85
|
+
value
|
|
86
|
+
}),
|
|
87
|
+
lte: (column, value) => ({
|
|
88
|
+
column,
|
|
89
|
+
op: "lte",
|
|
90
|
+
value
|
|
91
|
+
}),
|
|
92
|
+
in: (column, values) => ({
|
|
93
|
+
column,
|
|
94
|
+
op: "in",
|
|
95
|
+
value: values
|
|
96
|
+
}),
|
|
97
|
+
notIn: (column, values) => ({
|
|
98
|
+
column,
|
|
99
|
+
op: "not_in",
|
|
100
|
+
value: values
|
|
101
|
+
}),
|
|
102
|
+
like: (column, pattern) => ({
|
|
103
|
+
column,
|
|
104
|
+
op: "like",
|
|
105
|
+
value: pattern
|
|
106
|
+
}),
|
|
107
|
+
ilike: (column, pattern) => ({
|
|
108
|
+
column,
|
|
109
|
+
op: "ilike",
|
|
110
|
+
value: pattern
|
|
111
|
+
}),
|
|
112
|
+
isNull: (column) => ({
|
|
113
|
+
column,
|
|
114
|
+
op: "is_null"
|
|
115
|
+
}),
|
|
116
|
+
isNotNull: (column) => ({
|
|
117
|
+
column,
|
|
118
|
+
op: "is_not_null"
|
|
119
|
+
}),
|
|
120
|
+
and: (...filters) => ({ and: filters }),
|
|
121
|
+
or: (...filters) => ({ or: filters }),
|
|
122
|
+
not: (filter) => ({ not: filter })
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
storage = {
|
|
126
|
+
presign: async (params) => await this.core.storagePresign(params.bucket, params.filename, params.mimeType, params.sizeBytes, params.retentionDays),
|
|
127
|
+
commit: async (uploadId, assetId) => await this.core.storageCommit(uploadId, assetId)
|
|
128
|
+
};
|
|
129
|
+
push = {
|
|
130
|
+
register: async (token, platform, bundleId) => await this.core.pushRegister(token, platform, bundleId),
|
|
131
|
+
subscribe: async (topic) => {
|
|
132
|
+
await this.core.pushSubscribe(topic);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
entitlements = {
|
|
136
|
+
list: async () => await this.core.entitlementsList(),
|
|
137
|
+
has: async (name) => await this.core.entitlementsHas(name)
|
|
138
|
+
};
|
|
139
|
+
ai = { anthropic: { messages: { create: async (request) => await this.core.aiAnthropicMessages(JSON.stringify(request)) } } };
|
|
140
|
+
config = { fetch: async () => await this.core.configFetch() };
|
|
141
|
+
flags = { fetch: async () => await this.core.flagsFetch() };
|
|
142
|
+
/**
|
|
143
|
+
* Per-user scoped handle. **Not yet implemented.** A forthcoming
|
|
144
|
+
* release will mint a per-user core with a Bearer token override.
|
|
145
|
+
*
|
|
146
|
+
* For now this throws — earlier we returned `this` unchanged, which
|
|
147
|
+
* meant `asUser('user_123').collections.insert(...)` silently wrote
|
|
148
|
+
* under the *current* authenticated user, a high-severity data
|
|
149
|
+
* integrity footgun. A loud failure is the right interim.
|
|
150
|
+
*
|
|
151
|
+
* If you need per-user writes today, route them through your service
|
|
152
|
+
* identity and store an explicit `user_id` column.
|
|
153
|
+
*/
|
|
154
|
+
asUser(_userId) {
|
|
155
|
+
throw new Error("asUser is not yet implemented — minting a per-user core with a Bearer token override is planned for a forthcoming release. For now, route per-user writes through your service identity plus an explicit `user_id` column.");
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build a Connect/Express-style middleware that attaches `req.amba`
|
|
159
|
+
* to every request. Wraps the SDK so handlers can call amba inline.
|
|
160
|
+
*/
|
|
161
|
+
middleware() {
|
|
162
|
+
const self = this;
|
|
163
|
+
return function ambaMiddleware(req, _res, next) {
|
|
164
|
+
req.amba = self;
|
|
165
|
+
next();
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
/** Convenience alias matching `@layers/amba-web`'s `Amba.configure` shape. */
|
|
170
|
+
const Amba = { configure: AmbaClient.configure.bind(AmbaClient) };
|
|
171
|
+
const SDK_VERSION = "0.1.0";
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
export { Amba, AmbaClient, SDK_VERSION };
|
|
175
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["core: InternalCore","wasmFileUrl: string"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @layers/amba-node — Node.js server SDK for the amba platform.\n *\n * Server-mode differences from `@layers/amba-web`:\n * - Bound to the running process, not a browser tab — typically a single\n * instance per service.\n * - `Amba.asUser(userId)` is **planned** (forthcoming release) — it will\n * return a per-user scoped handle that mints an independent core with a\n * Bearer token override. Today it throws `Error(\"asUser is not yet\n * implemented\")` so server callers fail loudly instead of silently\n * writing data under the wrong user identity. Track in the SDK roadmap.\n * - No localStorage; identity persists in memory only (servers usually\n * re-authenticate with PATs or service tokens on every request).\n * - Built-in Connect-style middleware factory at `amba.middleware()`.\n *\n * @example\n * ```ts\n * import { Amba } from '@layers/amba-node';\n *\n * const amba = await Amba.configure({\n * apiKey: process.env.AMBA_API_KEY,\n * });\n *\n * // Per-user scoped calls: `asUser` is planned but not yet implemented.\n * // Calling it today throws. For now, route per-user writes through your\n * // own service identity + an explicit `user_id` column.\n *\n * // Connect-style middleware\n * import express from 'express';\n * const app = express();\n * app.use(amba.middleware());\n * app.post('/webhook', (req, res) => {\n * req.amba.events.track('webhook_received');\n * res.sendStatus(204);\n * });\n * ```\n */\n\nimport init, { AmbaCoreWasm } from \"@layers/amba-core-wasm\";\n\nimport type {\n AmbaConfig,\n AuthResult,\n User,\n FindOptions,\n FindResponse,\n Filter,\n FilterValue,\n ConfigBundle,\n FlagAssignment,\n UserEntitlement,\n MediaAsset,\n PresignData,\n PushPlatform,\n PushToken,\n AiMessageRequest,\n AiMessageResponse,\n SocialProvider,\n} from \"./types\";\n\nexport type * from \"./types\";\n\ninterface InternalCore {\n track(event: string, properties_json?: string): Promise<unknown>;\n signInAnonymously(): Promise<unknown>;\n signInWithEmail(email: string, password: string): Promise<unknown>;\n signUpWithEmail(email: string, password: string): Promise<unknown>;\n signInWithSocial(provider: string, idToken: string): Promise<unknown>;\n signOut(rotateAnonymousId: boolean): Promise<unknown>;\n refreshSession(): Promise<unknown>;\n me(): Promise<unknown>;\n collectionsFind(collection: string, options_json: string): Promise<unknown>;\n collectionsFindOne(collection: string, id: string): Promise<unknown>;\n collectionsInsert(collection: string, row_json: string): Promise<unknown>;\n collectionsUpdate(\n collection: string,\n id: string,\n set_json: string,\n ): Promise<unknown>;\n collectionsDelete(collection: string, id: string): Promise<unknown>;\n storagePresign(\n bucket: string,\n filename: string,\n mimeType: string,\n sizeBytes: number,\n retentionDays?: number,\n ): Promise<unknown>;\n storageCommit(uploadId: string, assetId: string): Promise<unknown>;\n pushRegister(\n token: string,\n platform: string,\n bundleId?: string,\n ): Promise<unknown>;\n pushSubscribe(topic: string): Promise<unknown>;\n entitlementsList(): Promise<unknown>;\n entitlementsHas(name: string): Promise<unknown>;\n aiAnthropicMessages(request_json: string): Promise<unknown>;\n configFetch(): Promise<unknown>;\n flagsFetch(): Promise<unknown>;\n anonymousId(): string;\n appUserId(): string | undefined;\n isAuthenticated(): boolean;\n setDebug(enabled: boolean): void;\n}\n\nexport class AmbaClient {\n private constructor(private readonly core: InternalCore) {}\n\n static async configure(config: AmbaConfig): Promise<AmbaClient> {\n if (!config.apiKey || config.apiKey.trim() === \"\") {\n throw new Error(\"AmbaClient.configure: apiKey is required\");\n }\n // wasm-pack `--target web` (the shipped @layers/amba-core-wasm) defers\n // wasm instantiation to a `fetch(new URL(\"./amba_core_bg.wasm\", import.meta.url))`\n // call that Node's undici cannot satisfy (file:// scheme unsupported).\n // We're always in Node here, so read the wasm via fs and seed init()\n // with the bytes — matches @layers/amba-web's customer-shoes path.\n const [{ readFile }, { fileURLToPath, pathToFileURL }, { createRequire }] =\n await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:url\"),\n import(\"node:module\"),\n ]);\n // Resolution strategy, in order:\n // 1. `import.meta.resolve` (Node ≥20.6, stable in 22). Async or sync\n // depending on Node version — both return a string when awaited.\n // 2. `require.resolve` via `createRequire(import.meta.url)`. Uses\n // Node's standard module resolution which honors pnpm's\n // `.pnpm/<pkg>@<ver>/node_modules/<pkg>` layout. The previous\n // `../node_modules/...` hard-coded fallback failed on pnpm.\n const resolveFn = (\n import.meta as unknown as {\n resolve?: (s: string) => string | Promise<string>;\n }\n ).resolve;\n let wasmFileUrl: string;\n if (resolveFn) {\n wasmFileUrl = await resolveFn(\"@layers/amba-core-wasm/wasm\");\n } else {\n const req = createRequire(import.meta.url);\n // `require.resolve` returns a filesystem path; convert to a\n // file:// URL so `fileURLToPath` below works uniformly with the\n // `import.meta.resolve` branch.\n wasmFileUrl = pathToFileURL(\n req.resolve(\"@layers/amba-core-wasm/wasm\"),\n ).href;\n }\n const bytes = await readFile(fileURLToPath(wasmFileUrl));\n await init(bytes);\n\n const core = AmbaCoreWasm.init(\n JSON.stringify({\n api_key: config.apiKey,\n base_url: config.baseUrl,\n sdk_platform: \"node\",\n sdk_wrapper_version: `amba-node/${SDK_VERSION}`,\n consent_required: config.consentRequired,\n debug: config.debug,\n }),\n // Node 20+ has a global fetch — bind it for the Rust core.\n globalThis.fetch.bind(globalThis),\n ) as unknown as InternalCore;\n return new AmbaClient(core);\n }\n\n get anonymousId(): string {\n return this.core.anonymousId();\n }\n get appUserId(): string | undefined {\n return this.core.appUserId() ?? undefined;\n }\n get isAuthenticated(): boolean {\n return this.core.isAuthenticated();\n }\n setDebug(enabled: boolean): void {\n this.core.setDebug(enabled);\n }\n\n events = {\n track: async (\n event: string,\n properties?: Record<string, unknown>,\n ): Promise<void> => {\n await this.core.track(\n event,\n properties ? JSON.stringify(properties) : undefined,\n );\n },\n };\n\n auth = {\n signInAnonymously: async (): Promise<AuthResult> =>\n (await this.core.signInAnonymously()) as AuthResult,\n signInWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> =>\n (await this.core.signInWithEmail(email, password)) as AuthResult,\n signUpWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> =>\n (await this.core.signUpWithEmail(email, password)) as AuthResult,\n signInWithSocial: async (\n provider: SocialProvider,\n idToken: string,\n ): Promise<AuthResult> =>\n (await this.core.signInWithSocial(provider, idToken)) as AuthResult,\n signOut: async (rotateAnonymousId = false): Promise<void> => {\n await this.core.signOut(rotateAnonymousId);\n },\n refresh: async (): Promise<AuthResult> =>\n (await this.core.refreshSession()) as AuthResult,\n me: async (): Promise<User> => (await this.core.me()) as User,\n };\n\n collections = {\n find: async <T = unknown>(\n name: string,\n options: FindOptions = {},\n ): Promise<FindResponse<T>> =>\n (await this.core.collectionsFind(\n name,\n JSON.stringify(options),\n )) as FindResponse<T>,\n findOne: async <T = unknown>(name: string, id: string): Promise<T> =>\n (await this.core.collectionsFindOne(name, id)) as T,\n insert: async <T = unknown>(\n name: string,\n row: Record<string, unknown>,\n ): Promise<T> =>\n (await this.core.collectionsInsert(name, JSON.stringify(row))) as T,\n update: async <T = unknown>(\n name: string,\n id: string,\n set: Record<string, unknown>,\n ): Promise<T> =>\n (await this.core.collectionsUpdate(name, id, JSON.stringify(set))) as T,\n delete: async (\n name: string,\n id: string,\n ): Promise<{ data: { deleted: boolean } }> =>\n (await this.core.collectionsDelete(name, id)) as {\n data: { deleted: boolean };\n },\n where: {\n eq: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"eq\",\n value,\n }),\n ne: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"ne\",\n value,\n }),\n gt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gt\",\n value,\n }),\n gte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gte\",\n value,\n }),\n lt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lt\",\n value,\n }),\n lte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lte\",\n value,\n }),\n in: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"in\",\n value: values,\n }),\n notIn: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"not_in\",\n value: values,\n }),\n like: (column: string, pattern: string): Filter => ({\n column,\n op: \"like\",\n value: pattern,\n }),\n ilike: (column: string, pattern: string): Filter => ({\n column,\n op: \"ilike\",\n value: pattern,\n }),\n isNull: (column: string): Filter => ({ column, op: \"is_null\" }),\n isNotNull: (column: string): Filter => ({ column, op: \"is_not_null\" }),\n and: (...filters: Filter[]): Filter => ({ and: filters }),\n or: (...filters: Filter[]): Filter => ({ or: filters }),\n not: (filter: Filter): Filter => ({ not: filter }),\n },\n };\n\n storage = {\n presign: async (params: {\n bucket: string;\n filename: string;\n mimeType: string;\n sizeBytes: number;\n retentionDays?: number;\n }): Promise<PresignData> =>\n (await this.core.storagePresign(\n params.bucket,\n params.filename,\n params.mimeType,\n params.sizeBytes,\n params.retentionDays,\n )) as PresignData,\n commit: async (uploadId: string, assetId: string): Promise<MediaAsset> =>\n (await this.core.storageCommit(uploadId, assetId)) as MediaAsset,\n };\n\n push = {\n register: async (\n token: string,\n platform: PushPlatform,\n bundleId?: string,\n ): Promise<PushToken> =>\n (await this.core.pushRegister(token, platform, bundleId)) as PushToken,\n subscribe: async (topic: string): Promise<void> => {\n await this.core.pushSubscribe(topic);\n },\n };\n\n entitlements = {\n list: async (): Promise<UserEntitlement[]> =>\n (await this.core.entitlementsList()) as UserEntitlement[],\n has: async (name: string): Promise<boolean> =>\n (await this.core.entitlementsHas(name)) as boolean,\n };\n\n ai = {\n anthropic: {\n messages: {\n create: async (request: AiMessageRequest): Promise<AiMessageResponse> =>\n (await this.core.aiAnthropicMessages(\n JSON.stringify(request),\n )) as AiMessageResponse,\n },\n },\n };\n\n config = {\n fetch: async (): Promise<ConfigBundle> =>\n (await this.core.configFetch()) as ConfigBundle,\n };\n\n flags = {\n fetch: async (): Promise<FlagAssignment[]> =>\n (await this.core.flagsFetch()) as FlagAssignment[],\n };\n\n /**\n * Per-user scoped handle. **Not yet implemented.** A forthcoming\n * release will mint a per-user core with a Bearer token override.\n *\n * For now this throws — earlier we returned `this` unchanged, which\n * meant `asUser('user_123').collections.insert(...)` silently wrote\n * under the *current* authenticated user, a high-severity data\n * integrity footgun. A loud failure is the right interim.\n *\n * If you need per-user writes today, route them through your service\n * identity and store an explicit `user_id` column.\n */\n asUser(_userId: string): AmbaClient {\n throw new Error(\n \"asUser is not yet implemented — minting a per-user core with a \" +\n \"Bearer token override is planned for a forthcoming release. \" +\n \"For now, route per-user writes through your service identity \" +\n \"plus an explicit `user_id` column.\",\n );\n }\n\n /**\n * Build a Connect/Express-style middleware that attaches `req.amba`\n * to every request. Wraps the SDK so handlers can call amba inline.\n */\n middleware() {\n const self = this;\n return function ambaMiddleware(\n req: Record<string, unknown>,\n _res: unknown,\n next: () => void,\n ) {\n (req as { amba: AmbaClient }).amba = self;\n next();\n };\n }\n}\n\n/** Convenience alias matching `@layers/amba-web`'s `Amba.configure` shape. */\nexport const Amba = {\n configure: AmbaClient.configure.bind(AmbaClient),\n};\n\nexport const SDK_VERSION = \"0.1.0\";\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@layers/amba-node",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "amba SDK for Node.js server apps — full 25-namespace surface for backend integration with amba",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/layers/amba-sdks.git",
|
|
23
|
+
"directory": "packages/node"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@layers/amba-core-wasm": "^1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^22.13.14",
|
|
34
|
+
"tsdown": "^0.15.2",
|
|
35
|
+
"typescript": "^5.8.3",
|
|
36
|
+
"vitest": "^3.1.1"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=20.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsdown",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:watch": "vitest"
|
|
45
|
+
}
|
|
46
|
+
}
|