@layers/amba-node 1.0.0 → 1.0.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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import init, { AmbaCoreWasm } from "@layers/amba-core-wasm";
1
+ import init, { AmbaCoreWasm } from "@layers/amba-core";
2
2
 
3
3
  //#region src/index.ts
4
4
  var AmbaClient = class AmbaClient {
@@ -14,8 +14,8 @@ var AmbaClient = class AmbaClient {
14
14
  ]);
15
15
  const resolveFn = import.meta.resolve;
16
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;
17
+ if (resolveFn) wasmFileUrl = await resolveFn("@layers/amba-core/wasm");
18
+ else wasmFileUrl = pathToFileURL(createRequire(import.meta.url).resolve("@layers/amba-core/wasm")).href;
19
19
  await init(await readFile(fileURLToPath(wasmFileUrl)));
20
20
  return new AmbaClient(AmbaCoreWasm.init(JSON.stringify({
21
21
  api_key: config.apiKey,
package/dist/index.js.map CHANGED
@@ -1 +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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"}
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\";\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) 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\");\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\"),\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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
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",
3
+ "version": "1.0.1",
4
+ "description": "amba SDK for Node.js server apps — full 25-namespace surface for backend integration with amba.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -19,7 +19,7 @@
19
19
  "license": "MIT",
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "https://github.com/layers/amba-sdks.git",
22
+ "url": "https://github.com/layers/amba.git",
23
23
  "directory": "packages/node"
24
24
  },
25
25
  "publishConfig": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "sideEffects": false,
29
29
  "dependencies": {
30
- "@layers/amba-core-wasm": "^1.0.0"
30
+ "@layers/amba-core": "^1.0.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.13.14",