feat: add TablesDB API coverage and Transactions API support#32
feat: add TablesDB API coverage and Transactions API support#32Divyansha23 wants to merge 1 commit intomasterfrom
Conversation
WalkthroughThis change integrates TablesDB functionality into the application. The import statement is expanded to include the TablesDB client from node-appwrite, and a new TablesDB instance is created. Configuration values (endpoint, project ID, API key) are updated to read from environment variables with fallback values. Over 30 new public API functions are added to support TablesDB operations including databases, tables, columns, indexes, rows, and transactions. The Node.js runtime version is updated from 20 to 22 in both function creation and update calls. The runAllTasks function is extended to execute the new TablesDB API sequences alongside existing API demonstrations. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/app.js (3)
9-11: Fail fast when required Appwrite env vars are missing.Lines 9-11 silently fall back to placeholders, which delays failure until the first API call and makes setup errors less obvious.
🛠️ Suggested fail-fast config
+const endpoint = process.env.APPWRITE_ENDPOINT; +const projectId = process.env.APPWRITE_PROJECT_ID; +const apiKey = process.env.APPWRITE_API_KEY; + +if (!endpoint || !projectId || !apiKey) { + throw new Error('Missing APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, or APPWRITE_API_KEY'); +} + const client = new Client() - .setEndpoint(process.env.APPWRITE_ENDPOINT || 'YOUR_ENDPOINT') // Replace with your endpoint - .setProject(process.env.APPWRITE_PROJECT_ID || 'YOUR_PROJECT_ID') // Replace with your project ID - .setKey(process.env.APPWRITE_API_KEY || 'YOUR_API_KEY'); // Replace with your API Key + .setEndpoint(endpoint) + .setProject(projectId) + .setKey(apiKey);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app.js` around lines 9 - 11, Replace the silent placeholder defaults for Appwrite configuration with a fail-fast check: before calling setEndpoint, setProject, and setKey in the client initialization (the code around setEndpoint(...), setProject(...), setKey(...)), validate that process.env.APPWRITE_ENDPOINT, process.env.APPWRITE_PROJECT_ID, and process.env.APPWRITE_API_KEY are present and non-empty and throw an Error or exit with a clear message listing the missing variables; only call client.setEndpoint(...).setProject(...).setKey(...) when all required env vars are provided to ensure immediate, explicit failure on misconfiguration.
1283-1320: Wrap the new TablesDB flow intry/finallyso cleanup still runs on failures.If one TablesDB/transaction call fails, the current sequence skips all subsequent delete calls and leaves test resources behind.
♻️ Suggested cleanup guard
+const safeRun = async (fn) => { + try { await fn(); } catch (err) { console.log(chalk.yellow(`Cleanup skipped: ${err.message}`)); } +}; const runAllTasks = async () => { @@ - await createTablesDatabase(); - await listTablesDatabases(); - await getTablesDatabase(); - await updateTablesDatabase(); - - await createTable(); - await listTables(); - await getTable(); - await updateTable(); - - await createColumns(); - await listTableColumns(); - await getTableColumn(); - - await createTableIndex(); - await listTableIndexes(); - - await createTableRow(); - await listTableRows(); - await getTableRow(); - await updateTableRow(); - - // Transactions API - await createTransaction(); - await getTransaction(); - await listTransactions(); - await stageCreateRow(); - await stageUpdateRow(); - await stageOperations(); - await commitTransaction(); - await rollbackTransactionDemo(); - await deleteTransaction(); - - await deleteTableRow(); - await deleteTableIndex(); - await deleteTableColumn(); - await deleteTable(); - await deleteTablesDatabase(); + await createTablesDatabase(); + try { + await listTablesDatabases(); + await getTablesDatabase(); + await updateTablesDatabase(); + await createTable(); + await listTables(); + await getTable(); + await updateTable(); + await createColumns(); + await listTableColumns(); + await getTableColumn(); + await createTableIndex(); + await listTableIndexes(); + await createTableRow(); + await listTableRows(); + await getTableRow(); + await updateTableRow(); + await createTransaction(); + await getTransaction(); + await listTransactions(); + await stageCreateRow(); + await stageUpdateRow(); + await stageOperations(); + await commitTransaction(); + await rollbackTransactionDemo(); + await deleteTransaction(); + } finally { + await safeRun(deleteTableRow); + await safeRun(deleteTableIndex); + await safeRun(deleteTableColumn); + await safeRun(deleteTable); + await safeRun(deleteTablesDatabase); + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app.js` around lines 1283 - 1320, The sequence of TablesDB and transaction calls (e.g., createTablesDatabase, createTable, createColumns, createTableIndex, createTableRow, createTransaction, stageCreateRow, commitTransaction, etc.) must be wrapped in a try/finally so cleanup always runs; move all setup and test operations into the try block and place all teardown calls (deleteTableRow, deleteTableIndex, deleteTableColumn, deleteTable, deleteTablesDatabase, plus deleteTransaction/rollback if needed) into the finally block so that even if any intermediate await throws, the deleteTablesDatabase and related cleanup functions still execute; ensure awaits remain and consider guarding deletes with existence checks if necessary.
891-893: Prefer readiness polling over fixed sleeps for schema/index creation.The hardcoded 2-second waits can be flaky on slower instances. Poll for
availablestatus with timeout instead of sleeping blindly.♻️ Suggested refactor sketch
+const waitUntil = async (check, label, timeoutMs = 30000, intervalMs = 1000) => { + const start = Date.now(); + while (Date.now() - start < timeoutMs) { + if (await check()) return; + await new Promise((resolve) => setTimeout(resolve, intervalMs)); + } + throw new Error(`${label} did not become ready in time`); +}; - console.log("Waiting a little to ensure columns are created ..."); - await new Promise((resolve) => setTimeout(resolve, 2000)); + await waitUntil(async () => { + const cols = await tablesDB.listColumns({ databaseId: tablesDatabaseId, tableId }); + return cols.columns?.every((c) => c.status === 'available'); + }, 'TablesDB columns'); - console.log("Waiting a little to ensure index is created ..."); - await new Promise((resolve) => setTimeout(resolve, 2000)); + await waitUntil(async () => { + const idx = await tablesDB.listIndexes({ databaseId: tablesDatabaseId, tableId }); + return idx.indexes?.some((i) => i.key === 'idx_year' && i.status === 'available'); + }, 'TablesDB index idx_year');Also applies to: 930-932
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app.js` around lines 891 - 893, Replace the hardcoded 2s sleep used after the console.log("Waiting a little to ensure columns are created ...") and the similar sleep at the later occurrence with a readiness polling approach: implement a small helper (e.g., waitForAvailability(checkerFn, timeoutMs = 30000, intervalMs = 500)) that repeatedly calls a checker function (a function that queries the schema/index status — e.g., describeTable(), getIndexStatus() or the existing API you already use) until it returns an "available" truthy result or the timeout elapses, and use this helper in place of the await new Promise(...) calls so both the original sleep and the second instance (the one at 930-932) poll for availability with a reasonable timeout and interval rather than sleeping a fixed duration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/app.js`:
- Around line 9-11: Replace the silent placeholder defaults for Appwrite
configuration with a fail-fast check: before calling setEndpoint, setProject,
and setKey in the client initialization (the code around setEndpoint(...),
setProject(...), setKey(...)), validate that process.env.APPWRITE_ENDPOINT,
process.env.APPWRITE_PROJECT_ID, and process.env.APPWRITE_API_KEY are present
and non-empty and throw an Error or exit with a clear message listing the
missing variables; only call client.setEndpoint(...).setProject(...).setKey(...)
when all required env vars are provided to ensure immediate, explicit failure on
misconfiguration.
- Around line 1283-1320: The sequence of TablesDB and transaction calls (e.g.,
createTablesDatabase, createTable, createColumns, createTableIndex,
createTableRow, createTransaction, stageCreateRow, commitTransaction, etc.) must
be wrapped in a try/finally so cleanup always runs; move all setup and test
operations into the try block and place all teardown calls (deleteTableRow,
deleteTableIndex, deleteTableColumn, deleteTable, deleteTablesDatabase, plus
deleteTransaction/rollback if needed) into the finally block so that even if any
intermediate await throws, the deleteTablesDatabase and related cleanup
functions still execute; ensure awaits remain and consider guarding deletes with
existence checks if necessary.
- Around line 891-893: Replace the hardcoded 2s sleep used after the
console.log("Waiting a little to ensure columns are created ...") and the
similar sleep at the later occurrence with a readiness polling approach:
implement a small helper (e.g., waitForAvailability(checkerFn, timeoutMs =
30000, intervalMs = 500)) that repeatedly calls a checker function (a function
that queries the schema/index status — e.g., describeTable(), getIndexStatus()
or the existing API you already use) until it returns an "available" truthy
result or the timeout elapses, and use this helper in place of the await new
Promise(...) calls so both the original sleep and the second instance (the one
at 930-932) poll for availability with a reasonable timeout and interval rather
than sleeping a fixed duration.
What does this PR do?
Adds full TablesDB and Transactions API coverage to the Node.js playground.
TablesDB API
Added complete CRUD coverage for the
TablesDBservice — a new Appwrite database type (type: "tablesdb") distinct from the legacyDatabasesservice:create,list,get,update,deletecreateTable,listTables,getTable,updateTable,deleteTablecreateStringColumn,createIntegerColumn,createFloatColumn,createBooleanColumn,listColumns,getColumn,deleteColumncreateIndex,listIndexes,deleteIndexcreateRow,listRows(withQuery.equal),getRow,updateRow,deleteRowTransactions API
Implemented the full TablesDB Transactions lifecycle, demonstrating the three-step pattern:
tablesDB.createTransaction({ ttl: 60 })transactionIdto row methods, or batch-stage viacreateOperationstablesDB.updateTransaction({ transactionId, commit: true })or{ rollback: true }createTransactiongetTransactionlistTransactionsstageCreateRowtransactionIdtocreateRowstageUpdateRowtransactionIdtoupdateRowstageOperationscreateOperationscommitTransactionrollbackTransactionDemo"failed"= successful rollback, staged data discarded)deleteTransactionOther changes
APPWRITE_ENDPOINT,APPWRITE_PROJECT_ID,APPWRITE_API_KEY) with fallback placeholders.Runtime.Node200toRuntime.Node22.Testing
Ran the full playground end-to-end against Appwrite Cloud — all 60+ API calls passed successfully, including TablesDB CRUD and the complete Transactions flow (create → stage → commit, rollback demo, delete).
Summary by CodeRabbit
New Features
Updates