{"_id":"@adaiasmagdiel/loxodontu","name":"@adaiasmagdiel/loxodontu","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@adaiasmagdiel/loxodontu","version":"0.1.0","description":"JavaScript/TypeScript client for Loxodontu, an open-source Backend-as-a-Service (BaaS).","keywords":["loxodontu","baas","backend-as-a-service","rest","sdk"],"homepage":"https://adaiasmagdiel.github.io/loxodontu/","author":{"name":"Adaías Magdiel","email":"adaiasmagdiell@gmail.com"},"license":"AGPL-3.0-only","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","unpkg":"./dist/index.global.js","jsdelivr":"./dist/index.global.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"sideEffects":false,"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build"},"devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","vitest":"^2.1.9"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/adaiasmagdiel/loxodontu-js.git"},"bugs":{"url":"https://github.com/adaiasmagdiel/loxodontu-js/issues"},"gitHead":"e7f6f11ec1762897c5910d8e5184671aadc14987","_id":"@adaiasmagdiel/loxodontu@0.1.0","_nodeVersion":"24.11.1","_npmVersion":"11.12.1","dist":{"integrity":"sha512-FxQ8kS8SR3VsInQ0PBJhK4IIOBy0Tnx/b0wL+DLgkBiL+f4lUVpL9dlwaI/mkXXkLCkAcoRXwD3j9j5INyY2dQ==","shasum":"a394b5df2275e401f5d4d72d1f3e163881f55d1a","tarball":"https://registry.npmjs.org/@adaiasmagdiel/loxodontu/-/loxodontu-0.1.0.tgz","fileCount":11,"unpackedSize":220931,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAJ8igOm/FpHPmYHk6h4G3JQxjOrVigVH3JMdEk9m3pxAiAhZEaB3aX8QTYiSzBMHGp5jI0E/65hyHhQ1yT2mnW2sQ=="}]},"_npmUser":{"name":"adaias_magdiel","email":"adaiasmagdiell@gmail.com"},"directories":{},"maintainers":[{"name":"adaias_magdiel","email":"adaiasmagdiell@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/loxodontu_0.1.0_1788038985365_0.39961880359611057"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-29T21:29:45.200Z","0.1.0":"2026-08-29T21:29:45.504Z","modified":"2026-08-29T21:29:45.733Z"},"maintainers":[{"name":"adaias_magdiel","email":"adaiasmagdiell@gmail.com"}],"description":"JavaScript/TypeScript client for Loxodontu, an open-source Backend-as-a-Service (BaaS).","homepage":"https://adaiasmagdiel.github.io/loxodontu/","keywords":["loxodontu","baas","backend-as-a-service","rest","sdk"],"repository":{"type":"git","url":"git+https://github.com/adaiasmagdiel/loxodontu-js.git"},"author":{"name":"Adaías Magdiel","email":"adaiasmagdiell@gmail.com"},"bugs":{"url":"https://github.com/adaiasmagdiel/loxodontu-js/issues"},"license":"AGPL-3.0-only","readme":"# @adaiasmagdiel/loxodontu\n\nJavaScript/TypeScript client for [Loxodontu](https://adaiasmagdiel.github.io/loxodontu/), an\nopen-source Backend-as-a-Service. Works from npm (ESM/CJS, fully typed) or as a single\n`<script>` tag in the browser — no bundler, no build step — for quick prototypes.\n\n## Install\n\n```bash\nnpm install @adaiasmagdiel/loxodontu\n```\n\n```ts\nimport { createClient } from \"@adaiasmagdiel/loxodontu\";\n```\n\nOr in a plain HTML page:\n\n```html\n<script src=\"https://unpkg.com/@adaiasmagdiel/loxodontu/dist/index.global.js\"></script>\n<script>\n  const loxo = Loxodontu.createClient(\n    \"https://your-app.example.com/api/v1\",\n    \"my-project\",\n    \"PROJECT_API_KEY\",\n  );\n</script>\n```\n\n## Two clients, matching Loxodontu's two token types\n\n- **`createClient`** — app-facing. REST passthrough, edge function invocation, and end-user\n  auth for a single project. Authenticated with a project API key.\n- **`createAdminClient`** — platform-facing. Manage your account, projects, tables, keys, RLS\n  policies, cron jobs, and functions. Authenticated with your platform login.\n\n### App client\n\n```ts\nimport { createClient } from \"@adaiasmagdiel/loxodontu\";\n\nconst loxo = createClient(\n  \"https://your-app.example.com/api/v1\",\n  \"my-project\", // project id / slug\n  \"PROJECT_API_KEY\",\n);\n\n// Query builder is awaitable directly — no .execute() needed.\nconst { data: todos, error } = await loxo\n  .from(\"todos\")\n  .select()\n  .eq(\"done\", false)\n  .order(\"created_at\", { ascending: false })\n  .limit(20);\n\nawait loxo.from(\"todos\").insert({ title: \"Write docs\" });\nawait loxo.from(\"todos\").update({ id: 1, done: true }); // single row, id in the body\nawait loxo.from(\"todos\").update({ done: true }).eq(\"done\", false); // bulk, by filter\nawait loxo.from(\"todos\").delete().eq(\"id\", 1); // single row, by filter\nawait loxo.from(\"todos\").delete().lt(\"views\", 10); // bulk, by filter\nawait loxo.from(\"todos\").delete([2, 3, 4]); // bulk, by id list\n\n// End users (your app's own users, separate from your platform account)\nawait loxo.auth.register(\"user@example.com\", \"password123\");\nawait loxo.auth.login(\"user@example.com\", \"password123\"); // token stored & sent automatically\nawait loxo.auth.logout();\n\n// Edge functions\nconst { data } = await loxo.functions.invoke(\"daily-cleanup\", { body: { source: \"client\" } });\n```\n\nFilters mirror the REST passthrough API 1:1: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`\n(`*` wildcard), `in`. They work the same way on `select()`, `update()`, and `delete()`. For\n`update()`/`delete()`, in order of precedence: an array (of row objects, or ids for `delete`)\nis always a bulk write; otherwise any chained filter (`eq`, `gt`, ...) scopes a filtered\nupdate/delete over every matching row; otherwise, for `update()` only, an `id` field in the\nbody targets that single row.\n\n### Admin client\n\n```ts\nimport { createAdminClient } from \"@adaiasmagdiel/loxodontu\";\n\nconst admin = createAdminClient(\"https://your-app.example.com/api/v1\");\nawait admin.auth.login(\"me@example.com\", \"password123\");\n\nconst { data: projects } = await admin.projects.list();\nconst { data: project } = await admin.projects.create({ name: \"New project\" });\n\nconst project1 = admin.projects.for(project.id);\nawait project1.tables.create({\n  name: \"todos\",\n  columns: [{ name: \"title\", type: \"text\" }, { name: \"done\", type: \"boolean\", default_value: false }],\n});\nawait project1.keys.create({ name: \"frontend\", permissions: [\"select\", \"insert\"] });\nawait project1.tables.rlsPolicies(tableId).create({\n  name: \"owner can read\",\n  operation: \"SELECT\",\n  conditions: { user_id: \"$auth.id\" },\n});\nawait project1.sql(\"SELECT COUNT(*) FROM todos\");\n```\n\n## Responses\n\nEvery request resolves to the same envelope — nothing throws on an API error by default,\nmatching the \"check `error`\" pattern of most BaaS clients:\n\n```ts\ninterface LoxodontuResponse<T> {\n  data: T | null;\n  error: { message: string; status: number } | null;\n  count: number | null; // from X-Total-Count on paginated list endpoints\n  status: number;\n}\n```\n\nIf you'd rather throw, wrap a call in `unwrap()`... or just:\n\n```ts\nimport { LoxodontuError } from \"@adaiasmagdiel/loxodontu\";\n\nconst { data, error } = await loxo.from(\"todos\").select();\nif (error) throw new LoxodontuError(error.message, error.status);\n```\n\n## Session storage\n\n`createClient`'s end-user token and `createAdminClient`'s platform token are persisted via\n`localStorage` when available, or kept in memory otherwise (SSR, Node, workers). Pass your own\n`storage` (anything with `getItem`/`setItem`/`removeItem`) via `options.storage` to override —\nuseful for `sessionStorage`, cookies, or React Native's `AsyncStorage`.\n\n## Node / SSR\n\n`fetch` is used directly, so Node 18+ works out of the box. On older runtimes, pass one via\n`options.fetch`.\n\n## License\n\n[AGPL-3.0-only](LICENSE), matching [Loxodontu](https://github.com/adaiasmagdiel/loxodontu)\nitself.\n","readmeFilename":"README.md","_rev":"1-31250bb91a95e2666c9b3c6f951fbc64"}