### Serve Static Files Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md An example of how to configure a route to serve static files from a specified directory. This is commonly used for hosting frontend assets or other static content. ```javascript routerAdd("GET", "/*", $apis.staticDirectoryHandler("/path/to/public", false)); ``` -------------------------------- ### Initialize Default Application Settings Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Example of initializing default application settings within a migration file. It demonstrates using the `Dao` instance to load, modify, and save settings. ```javascript // pb_migrations/1687801090_initial_settings.js migrate((db) => { const dao = new Dao(db); const settings = dao.findSettings(); settings.meta.appName = "test"; settings.logs.maxDays = 2; dao.saveSettings(settings); }); ``` -------------------------------- ### Writing Response Body Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Provides examples for sending various types of responses from PocketBase JavaScript hooks. This includes JSON, plain strings, HTML, redirects, and responses with no content. ```javascript // send response with json body c.json(200, {"name": "John"}); // send response with string body c.string(200, "Lorem ipsum..."); // send response with html body // (check also the "Rendering templates" section) c.html(200, "

Hello!

"); // redirect c.redirect(307, "https://example.com"); // send response with no body c.noContent(204); ``` -------------------------------- ### HTML Layout Template Example Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-rendering-templates.md Defines a base HTML structure with blocks for title and body content, allowing partials to override these sections using `{{define}}` actions. Includes default content for blocks. ```html {{block "title" .}}Default app title{{end}} Header... {{block "body" .}} Default app body... {{end}} Footer... ``` -------------------------------- ### Register GET Route with Path Parameter Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Demonstrates registering a new GET route with a path parameter. It shows how to define the route path, the handler function, and access path parameters using `c.pathParam()`. ```javascript routerAdd("GET", "/hello/:name", (c) => { let name = c.pathParam("name"); return c.json(200, { "message": "Hello " + name }); }, /* optional middlewares */); ``` -------------------------------- ### HTML Partial Template Example Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-rendering-templates.md Defines content for specific named blocks within a base HTML template. Uses the `{{define "placeholderName"}}` action to provide custom content, including data passed via the render context. ```html {{define "title"}} Page 1 {{end}} {{define "body"}}

Hello from {{.name}}

{{end}} ``` -------------------------------- ### Query Builder Basic Usage Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md An example of using the PocketBase JS SDK's query builder to construct a SQL SELECT statement programmatically. It demonstrates chaining methods like `select()`, `from()`, `andWhere()`, `limit()`, and `orderBy()`. ```javascript const result = arrayOf(new DynamicModel({ "id": "", "email": "", })); $app.dao().db() .select("id", "email") .from("users") .andWhere($dbx.like("email", "example.com")) .limit(100) .orderBy("created ASC") .all(result); ``` -------------------------------- ### Register Custom Route with Template Rendering Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-rendering-templates.md Registers a GET route for `/hello/:name` that extracts the name from the path parameter, renders a custom HTML page using layout and partial templates, and returns the rendered HTML. ```javascript routerAdd("get", "/hello/:name", (c) => { const name = c.pathParam("name") const html = $template.loadFiles( `${__hooks}/views/layout.html`, `${__hooks}/views/hello.html` ).render({ "name": name, }) return c.html(200, html) }) ``` -------------------------------- ### Run Raw SQL Statement Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Example of executing a raw SQL UPDATE statement within a migration file using the `db.newQuery()` method. ```javascript // pb_migrations/1687801090_set_pending_status.js // set a default "pending" status to all empty status articles migrate((db) => { db.newQuery("UPDATE articles SET status = 'pending' WHERE status = ''") .execute() }); ``` -------------------------------- ### Write Response Header Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Provides an example of how to set a custom header in the HTTP response. This is done using the `c.response().header().set()` method. ```javascript c.response().header().set("Some-Header", "123"); ``` -------------------------------- ### PocketBase Server-Side JavaScript Hooks and Routing Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-overview.md Example of defining custom API routes and event hooks using PocketBase's embedded JavaScript engine. This code would typically reside in a `pb_hooks` directory. ```javascript // pb_hooks/main.pb.js routerAdd("GET", "/hello/:name", (c) => { let name = c.pathParam("name") return c.json(200, { "message": "Hello " + name }) }) onModelAfterUpdate((e) => { console.log("user updated...", e.model.get("email")) }, "users") ``` -------------------------------- ### PocketBase DB Expression Builders (dbx) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Provides a comprehensive guide to the `dbx` expression builders available in the PocketBase JS SDK for constructing SQL WHERE clauses. This includes methods for raw expressions, hash expressions, logical operators (AND, OR, NOT), comparisons (IN, LIKE), and existence checks. ```APIDOC dbx.Expression Builders: - $dbx.exp(raw, optParams) Generates an expression with the specified raw query fragment. Use optParams to bind parameters. Parameters: - raw: string - The raw SQL fragment. - optParams: object - Key-value pairs for parameter binding. Example: $dbx.exp("status = 'public'") $dbx.exp("total > {:min} AND total < {:max}", { min: 10, max: 30 }) - $dbx.hashExp(pairs) Generates a hash expression from a map where keys are DB column names and values are filter criteria. Parameters: - pairs: object - Map of column names to filter values. Example: // slug = "example" AND active IS TRUE AND tags in ("tag1", "tag2", "tag3") AND parent IS NULL $dbx.hashExp({ slug: "example", active: true, tags: ["tag1", "tag2", "tag3"], parent: null }); - $dbx.not(exp) Negates a single expression by wrapping it with NOT(). Parameters: - exp: dbx.Expression - The expression to negate. Example: // NOT(status = 1) $dbx.not($dbx.exp("status = 1")) - $dbx.and(...exps) Creates a new expression by concatenating specified expressions with AND. Parameters: - exps: dbx.Expression[] - One or more expressions to combine. Example: // (status = 1 AND username like "%john%") $dbx.and($dbx.exp("status = 1"), $dbx.like("username", "john")) - $dbx.or(...exps) Creates a new expression by concatenating specified expressions with OR. Parameters: - exps: dbx.Expression[] - One or more expressions to combine. Example: // (status = 1 OR username like "%john%") $dbx.or($dbx.exp("status = 1"), $dbx.like("username", "john")) - $dbx.in(col, ...values) Generates an IN expression for the specified column and list of allowed values. Parameters: - col: string - The column name. - values: any[] - The list of values to check against. Example: // status IN ("public", "reviewed") $dbx.in("status", "public", "reviewed") - $dbx.notIn(col, ...values) Generates a NOT IN expression for the specified column and list of allowed values. Parameters: - col: string - The column name. - values: any[] - The list of values to exclude. Example: // status NOT IN ("public", "reviewed") $dbx.notIn("status", "public", "reviewed") - $dbx.like(col, ...values) Generates a LIKE expression. If multiple values are present, they are combined with AND. By default, values are surrounded by '%' for partial matching. Special characters are escaped. Parameters: - col: string - The column name. - values: string[] - The strings to match against. Example: // name LIKE "%test1%" AND name LIKE "%test2%" $dbx.like("name", "test1", "test2") // name LIKE "test1%" $dbx.like("name", "test1").match(false, true) - $dbx.notLike(col, ...values) Generates a NOT LIKE expression, similar to like() but with NOT. Parameters: - col: string - The column name. - values: string[] - The strings to not match against. Example: // name NOT LIKE "%test1%" AND name NOT LIKE "%test2%" $dbx.notLike("name", "test1", "test2") // name NOT LIKE "test1%" $dbx.notLike("name", "test1").match(false, true) - $dbx.orLike(col, ...values) Generates LIKE expressions combined with OR. The column must match at least one of the provided values. Parameters: - col: string - The column name. - values: string[] - The strings to match against (OR). Example: // name LIKE "%test1%" OR name LIKE "%test2%" $dbx.orLike("name", "test1", "test2") // name LIKE "test1%" OR name LIKE "test2%" $dbx.orLike("name", "test1", "test2").match(false, true) - $dbx.orNotLike(col, ...values) Generates NOT LIKE expressions combined with OR. The column must not match any of the provided values. Parameters: - col: string - The column name. - values: string[] - The strings to not match against (OR). Example: // name NOT LIKE "%test1%" OR name NOT LIKE "%test2%" $dbx.orNotLike("name", "test1", "test2") // name NOT LIKE "test1%" OR name NOT LIKE "test2%" $dbx.orNotLike("name", "test1", "test2").match(false, true) - $dbx.exists(exp) Prefixes the specified expression (usually a subquery) with EXISTS. Parameters: - exp: dbx.Expression - The expression to check for existence. Example: // EXISTS(SELECT 1 FROM orders WHERE orders.user_id = users.id) $dbx.exists($app.dao().db().select("1").from("orders").where($dbx.exp("orders.user_id = users.id"))) ``` -------------------------------- ### Manage Record Fields with PocketBase JS SDK Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Demonstrates how to get, set, and manage individual fields within a PocketBase record object using the JavaScript SDK. It covers various getter methods for different data types and utility functions for copying and loading data. ```javascript record.publicExport() record.originalCopy() record.cleanCopy() record.set("someField", 123) record.load(data) record.get("someField") // -> as any record.getBool("someField") // -> as bool record.getString("someField") // -> as string record.getInt("someField") // -> as int record.getFloat("someField") // -> as float64 record.getTime("someField") // -> as time.Time record.getDateTime("someField") // -> as types.DateTime record.getStringSlice("someField") // -> as []string const result = new DynamicModel({}) record.unmarshalJSONField("someJsonField", result) record.expandedOne("author") // -> as null|Record record.expandedAll("categories") // -> as []Record ``` -------------------------------- ### JavaScript: onAfterBootstrap Hook Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-event-hooks.md The onAfterBootstrap hook is triggered after the main application resources have been initialized, for example, after the database has opened and initial settings are loaded. It also receives an event object with the application instance. ```javascript onAfterBootstrap((e) => { console.log(e.app) }) ``` -------------------------------- ### Delete Record (JS) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Provides a simple example of how to delete a record from PocketBase. It first retrieves the record by its ID and then uses the `$app.dao().deleteRecord()` method to remove it. ```javascript const record = $app.dao().findRecordById("articles", "RECORD_ID") $app.dao().deleteRecord(record) ``` -------------------------------- ### Create PocketBase Admin User (JS Migration) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Demonstrates creating a new admin user in PocketBase using the JavaScript SDK. It initializes a Dao, creates an Admin instance, sets the email and password, and saves it using `dao.saveAdmin()`. Includes optional revert logic to delete the admin. ```javascript // pb_migrations/1687801090_initial_admin.js migrate((db) => { const dao = new Dao(db); const admin = new Admin(); admin.email = "test@example.com"; admin.setPassword("1234567890"); dao.saveAdmin(admin); }, (db) => { // optional revert const dao = new Dao(db); try { const admin = dao.findAdminByEmail("test@example.com"); dao.deleteAdmin(admin); } catch (_) { // most likely already deleted } }); ``` -------------------------------- ### Basic Logging with $app.logger() in PocketBase JS Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-logging.md Demonstrates how to use the basic logging methods provided by the PocketBase JavaScript logger. These methods allow you to record messages at different severity levels (debug, info, warn, error) directly from your JavaScript extensions. ```javascript $app .logger() .debug("Debug message!") $app .logger() .info("Info message!") $app .logger() .warn("Warning message!") $app .logger() .error("Error message!") ``` -------------------------------- ### Render HTML Templates with JavaScript Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-rendering-templates.md Demonstrates how to load multiple HTML template files and render them with provided data using the `$template` helper in PocketBase. Supports nested and composed templates with placeholder definitions and contextual auto-escaping. ```javascript const html = $template.loadFiles( `${__hooks}/views/base.html`, `${__hooks}/views/partial1.html`, `${__hooks}/views/partial2.html` ).render(data) ``` -------------------------------- ### Execute SQL CREATE INDEX Statement Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Demonstrates how to execute a raw SQL CREATE INDEX statement using the PocketBase JS SDK's `execute()` method. This method is suitable for SQL statements that do not return data, such as CREATE, UPDATE, or DELETE operations. ```javascript $app .dao() .db() .newQuery("CREATE INDEX name_idx ON users (name)") .execute() // throw an error on db failure ``` -------------------------------- ### Send HTTP Requests with $http.send() Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-sending-http-requests.md Demonstrates the basic usage of the global `$http.send()` helper for making HTTP requests. It shows how to configure URL, method, body, headers, and timeout, and access response details like status code, headers, and parsed JSON. ```javascript const res = $http.send({ url: "", method: "GET", body: "", // ex. JSON.stringify({ "test": 123 }) or new FormData() headers: { "content-type": "application/json" }, timeout: 120, // in seconds }) console.log(res.headers) // the response headers (ex. res.headers['X-Custom'][0]) console.log(res.cookies) // the response cookies (ex. res.cookies.sessionId.value) console.log(res.statusCode) // the response HTTP status code console.log(res.raw) // the response body as plain text console.log(res.json) // the response body as parsed json array or map ``` -------------------------------- ### Built-in Middlewares Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Lists and describes PocketBase's built-in middleware functions for common tasks. These include logging, authentication checks (guest, record, admin), response compression, and request body size limits. ```javascript // logs the request in the Admin UI > Logs $apis.activityLogger($app); // requires the request client to be unauthenticated, aka guest $apis.requireGuestOnly(); // requires the request client to be authenticated as an auth record $apis.requireRecordAuth(optCollectionNames); // require the request client to be authenticated as admin $apis.requireAdminAuth(); // require the request client to be authenticated as admin OR auth record $apis.requireAdminOrRecordAuth(optCollectionNames); // require the request client to be authenticated as admin OR auth record // that matches the ownerIdParam path parameter $apis.requireAdminOrOwnerAuth(ownerIdParam = "id"); // compresses HTTP response using gzip $apis.gzip(); // sets the maximum allowed size (in bytes) for a request body $apis.bodyLimit(bytes); ``` -------------------------------- ### Define Utility Module in JavaScript Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-overview.md Defines a JavaScript module with a 'hello' function for use in PocketBase hooks. Exports the module using CommonJS. ```javascript // pb_hooks/utils.js module.exports = { hello: (name) => { console.log("Hello " + name) } } ``` -------------------------------- ### Create New Migration Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Command to create a new blank migration file. The migration name is used to generate the filename. ```bash [root@dev app]$ ./pocketbase migrate create "your_new_migration" ``` -------------------------------- ### Generate Collections Snapshot Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Command to generate a migration file that captures the current state of all collections. This is useful for versioning your schema. ```bash [root@dev app]$ ./pocketbase migrate collections ``` -------------------------------- ### from() - Specify Tables for Selection Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md The `from(...tables)` method specifies which tables to select from in a database query. Plain table names are automatically quoted. It's used to define the primary data source for your query. ```javascript $app .dao() .db() .select("table1.id", "table2.name") .from("table1", "table2") ``` -------------------------------- ### Registering Middlewares Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Explains how to attach middleware functions to routes in PocketBase. Middlewares can be registered globally using `routerUse` or to specific routes by passing them after the handler function. ```javascript // attach a middleware globally to all routes routerUse(someMiddlereFunc); // attach multiple middlewares to a single route // each route will execute their own middlewares + the global ones routerAdd("GET", "/hello", (c) => { return c.string(200, "Hello world!"); }, $apis.activityLogger($app), $apis.requireAdminAuth()); ``` -------------------------------- ### join() and Join Shortcuts - Define JOIN Clauses Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md The `join()` method adds a JOIN clause to a query, specifying the join type, target table, and ON condition using `dbx.Expression`. Shortcuts like `innerJoin()`, `leftJoin()`, and `rightJoin()` simplify common join types. ```javascript $app.dao().db() .select("users.*") .from("users") .innerJoin("profiles", $dbx.exp("profiles.user_id = users.id")) .join("FULL OUTER JOIN", "department", $dbx.exp("department.id = {:id}", { id: "someId" })); ``` -------------------------------- ### Send Custom Requests via SDKs Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Illustrates how to use the `send()` method provided by PocketBase SDKs to make requests to custom API routes. This method allows sending arbitrary data and query parameters to your backend endpoints. ```javascript import PocketBase from 'pocketbase'; const pb = new PocketBase('http://127.0.0.1:8090'); await pb.send("/old/hello", { // for all possible options check // https://developer.mozilla.org/en-US/docs/Web/API/fetch#options query: { "abc": 123, }, }); ``` ```dart import 'package:pocketbase/pocketbase.dart'; final pb = PocketBase('http://127.0.0.1:8090'); await pb.send("/old/hello", query: { "abc": 123 }); ``` -------------------------------- ### Record Auth Response Handler Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Demonstrates how to create a custom authentication route that returns a standardized JSON response containing the authentication token and record data. It uses PocketBase's internal APIs to find a user record, validate credentials, and generate the auth response. ```javascript routerAdd("GET", "/phone-login", (c) => { const data = new DynamicModel({ phone: "", password: "", }); c.bind(data); const record = $app.dao().findFirstRecordByData("users", "phone", data.phone); if (!record.validatePassword(data.password)) { throw new BadRequestError("invalid credentials"); } return $apis.recordAuthResponse($app, c, record); }, $apis.activityLogger($app)); ``` -------------------------------- ### Handle Realtime Connect Request in JavaScript Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-event-hooks.md Triggered right before establishing the SSE client connection. Allows access to HTTP context, client ID, and idle timeout. ```javascript onRealtimeConnectRequest((e) => { console.log(e.httpContext) console.log(e.client.id()) console.log(e.idleTimeout) // in nanosec }) ``` -------------------------------- ### Store and Retrieve Data in Request Context Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Shows how to use the request context's local store to share data within the scope of a single request. Data can be set using `c.set()` and retrieved using `c.get()`. ```javascript // store for the duration of the request c.set("someKey", 123); // retrieve later const val = c.get("someKey"); // 123 ``` -------------------------------- ### Database Expression Builders Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Provides methods to construct SQL expressions for database queries. Includes functions for checking existence, range comparisons, and custom expressions. ```javascript // EXISTS (SELECT 1 FROM users WHERE status = 'active') $dbx.exists($dbx.exp("SELECT 1 FROM users WHERE status = 'active'")) ``` ```javascript // NOT EXISTS (SELECT 1 FROM users WHERE status = 'active') $dbx.notExists($dbx.exp("SELECT 1 FROM users WHERE status = 'active'")) ``` ```javascript // age BETWEEN 3 and 99 $dbx.between("age", 3, 99) ``` ```javascript // age NOT BETWEEN 3 and 99 $dbx.notBetween("age", 3, 99) ``` -------------------------------- ### Transaction Management (JS) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Illustrates how to perform multiple database operations atomically using transactions. The `$app.dao().runInTransaction()` method ensures that all operations within the callback are either committed or rolled back together, maintaining data integrity. ```javascript const titles = ["title1", "title2", "title3"] const collection = $app.dao().findCollectionByNameOrId("articles") $app.dao().runInTransaction((txDao) => { // create new record for each title for (let title of titles) { const record = new Record(collection) record.set("title", title) txDao.saveRecord(record) } }) ``` -------------------------------- ### Create PocketBase Auth Record (JS Migration) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Shows how to create a new authentication record (user) in PocketBase via JavaScript migrations. It involves finding a collection, creating a Record, setting username, password, name, and email, and saving it. Includes optional revert logic to delete the record by email. ```javascript // pb_migrations/1687801090_new_users_record.js migrate((db) => { const dao = new Dao(db); const collection = dao.findCollectionByNameOrId("users"); const record = new Record(collection); record.setUsername("u_" + $security.randomStringWithAlphabet(5, "123456789")); record.setPassword("1234567890"); record.set("name", "John Doe"); record.set("email", "test@example.com"); dao.saveRecord(record); }, (db) => { // optional revert const dao = new Dao(db); try { const record = dao.findAuthRecordByEmail("users", "test@example.com"); dao.deleteRecord(record); } catch (_) { // most likely already deleted } }); ``` -------------------------------- ### Migration File Structure Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-migrations.md Defines the structure of a PocketBase migration file, including up and down migration functions. The `migrate` function takes two callbacks: one for applying changes (up) and an optional one for reverting them (down). ```javascript // pb_migrations/1687801097_your_new_migration.js migrate((db) => { // add up queries }, (db) => { // add down queries }) ``` -------------------------------- ### JavaScript: onBeforeBootstrap Hook Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-event-hooks.md The onBeforeBootstrap hook is triggered before initializing the main application resources, such as before the database opens or initial settings are loaded. It receives an event object containing the application instance. ```javascript onBeforeBootstrap((e) => { console.log(e.app) }) ``` -------------------------------- ### Building Complex WHERE Clauses Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Demonstrates how to construct SQL WHERE clauses using `where()`, `andWhere()`, and `orWhere()` methods in the PocketBase JS SDK. It shows chaining conditions and using various `dbx.Expression` builders for different logical operations and comparisons. ```javascript /* SELECT users.* FROM users WHERE id = "someId" AND status = "public" AND name like "%john%" OR ( role = "manager" AND fullTime IS TRUE AND experience > 10 ) */ $app.dao().db() .select("users.*") .from("users") .where($dbx.exp("id = {:id}", { id: "someId" })) .andWhere($dbx.hashExp({ status: "public" })) .andWhere($dbx.like("name", "john")) .orWhere($dbx.and( $dbx.hashExp({ role: "manager", fullTime: true }), $dbx.exp("experience > {:exp}", { exp: 10 }) )); ``` -------------------------------- ### Upload Files with multipart/form-data and FormData Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-sending-http-requests.md Explains how to send `multipart/form-data` requests, typically for file uploads. It shows how to create a `FormData` instance and append files using `$filesystem.fileFromBytes` for use with the `$http.send()` method. ```javascript const formData = new FormData(); formData .append("title", "Hello world!") .append("documents", $filesystem.fileFromBytes("doc1.txt", "doc1 content")) .append("documents", $filesystem.fileFromBytes("doc2.txt", "doc2 content")) const res = $http.send({ url: "https://example.com/upload", method: "POST", body: formData, }) console.log(res.statusCode); ``` -------------------------------- ### Adding Contextual Attributes with logger.with() in PocketBase JS Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-logging.md Explains how to use the `with()` method to create a new logger instance that automatically includes specified attributes in all subsequent log entries. This is ideal for setting common context for a series of related logs. ```javascript const l = $app .logger() .with("total", 123) // results in log with data {"total": 123} l.info("message A") // results in log with data {"total": 123, "name": "john"} l.info("message B", "name", "john") ``` -------------------------------- ### Fetch Multiple Rows with arrayOf DynamicModel Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Illustrates fetching multiple database rows and populating them into an array of `DynamicModel` objects. The `arrayOf` helper function is used to create the array structure that the `all()` method expects. ```javascript const result = arrayOf(new DynamicModel({ // describe the shape of the data (used also as initial values) "id": "", "status": false, "age": 0, "roles": [], // serialized json db arrays are decoded as plain arrays })); $app.dao().db() .newQuery("SELECT id, status, age, roles FROM users LIMIT 100") .all(result); // throw an error on db failure if (result.length > 0) { console.log(result[0].id); } ``` -------------------------------- ### Read Path Parameter Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Illustrates how to read a specific path parameter from the request URL. Path parameters are defined using `:paramName` placeholders in the route definition. ```javascript const id = c.pathParam("id"); ``` -------------------------------- ### Bind Named Parameters to SQL Query Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Demonstrates how to prevent SQL injection by using named parameters (`{:paramName}`) in SQL statements and binding values using the `bind()` method. This is crucial for security when incorporating user-provided input into queries. ```javascript const result = arrayOf(new DynamicModel({ "name": "", "created": "", })); $app.dao().db() .newQuery("SELECT name, created FROM posts WHERE created >= {:from} and created <= {:to}") .bind({ "from": "2023-06-25 00:00:00.000Z", "to": "2023-06-28 23:59:59.999Z", }) .all(result); console.log(result.length); ``` -------------------------------- ### Query Builder select(), andSelect(), distinct() Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Illustrates how to specify columns for a SELECT query using `select()` and `andSelect()`. The `distinct()` method can be chained to retrieve unique rows based on the selected columns. ```javascript $app .dao() .db() .select("id", "avatar as image") .andSelect("(firstName || ' ' || lastName) as fullName") .distinct() ``` -------------------------------- ### Fetch Single Row with DynamicModel Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Shows how to fetch a single database row and populate it into a `DynamicModel` object. The `DynamicModel` is used to define the expected shape of the returned data, including types and default values. ```javascript const result = new DynamicModel({ // describe the shape of the data (used also as initial values) "id": "", "status": false, "age": 0, "roles": [], // serialized json db arrays are decoded as plain arrays }); $app.dao().db() .newQuery("SELECT id, status, age, roles FROM users WHERE id = 1") .one(result); // throw an error on db failure or missing row console.log(result.id); ``` -------------------------------- ### Read Request Header Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Shows how to access request headers. It provides methods for direct retrieval using `c.request().header.get()` and accessing normalized headers via the cached request object. ```javascript const token = c.request().header.get("Some-Header"); // or via the cached request object (the header value is always normalized) const token = $apis.requestInfo(c).headers["some_header"]; ``` -------------------------------- ### Fetch and Update Collection by Name or ID Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-collections.md Retrieves a PocketBase collection using its name or ID, allows modification of its properties (like name or schema), and saves the changes via the DAO. Requires access to the `$app.dao()` instance. ```javascript const collection = $app.dao().findCollectionByNameOrId("example"); // change the collection name collection.name = "example_update"; // add new field collection.schema.addField(new SchemaField({ name: "description", type: "text", })); $app.dao().saveCollection(collection); ``` -------------------------------- ### Using TypeScript Declarations in PocketBase JS Hooks Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-overview.md Demonstrates how to reference PocketBase's ambient TypeScript declaration file (`types.d.ts`) within a JavaScript file to enable editor code completion and type checking. Renaming the file to `.pb.ts` might further assist editor integration. ```javascript /// onAfterBootstrap((e) => { console.log("App initialized!") }) ``` -------------------------------- ### Create New Collection Without Data Validations Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-collections.md Programmatically creates a new PocketBase collection with specified properties, schema fields, and indexes. The collection ID is autogenerated by default. Requires the `$app.dao()` instance to save the collection. ```javascript const collection = new Collection({ // the id is autogenerated, but you can set a specific one if you want to // id: "...", name: "example", type: "base", listRule: null, viewRule: "@request.auth.id != ''", createRule: "", updateRule: "@request.auth.id != ''", deleteRule: null, schema: [ { name: "title", type: "text", required: true, options: { max: 10, }, }, { name: "user", type: "relation", required: true, options: { maxSelect: 1, collectionId: "ae40239d2bc4477", cascadeDelete: true, }, }, ], indexes: [ "CREATE UNIQUE INDEX idx_user ON example (user)" ], options: {} }); $app.dao().saveCollection(collection); ``` -------------------------------- ### Read Query Parameter Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Demonstrates how to retrieve query parameters from the request URL. It shows direct access via `c.queryParam()` and accessing them through the cached request object. ```javascript const search = c.queryParam("search"); // or via the cached request object const search = $apis.requestInfo(c).query.search; ``` -------------------------------- ### Error Response Handling Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Details PocketBase's error handling mechanisms, including the global error handler and the `ApiError` class. It shows how to construct custom errors with status codes, messages, and validation data, or use factory methods for common HTTP errors. ```javascript // construct ApiError with custom status code and validation data error = new ApiError(500, "something went wrong", { "title": new ValidationError("invalid_title", "Invalid or missing title"), }); // if message is empty string, a default one will be set throw new BadRequestError(optMessage, optData); // 400 ApiError throw new UnauthorizedError(optMessage, optData); // 401 ApiError throw new ForbiddenError(optMessage, optData); // 403 ApiError throw new NotFoundError(optMessage, optData); // 404 ApiError ``` -------------------------------- ### Logging with Attributes in PocketBase JS Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-logging.md Shows how to include additional key-value attributes with log messages using the PocketBase JavaScript logger. This is useful for providing context, such as user IDs, request details, or error objects, alongside the log message. ```javascript $app .logger() .debug("Debug message with attributes!", "name", "John Doe", "id", 123) $app .logger() .info("Info message with attributes!", "name", "John Doe", "id", 123) $app .logger() .warn("Warning message with attributes!", "name", "John Doe", "id", 123) $app .logger() .error("Error message with attributes!", "id", 123, "error", err) ``` -------------------------------- ### Programmatic Relation Expansion (APIDOC) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Details how to expand related records for a given record or a list of records. It covers the methods `$app.dao().expandRecord()` and `$app.dao().expandRecords()` for fetching relations and accessing them via `record.expandedOne()` or `record.expandedAll()`. ```APIDOC Expand Record Relations: $app.dao().expandRecord(record, expands, customFetchFunc) - Expands relations for a single record. - Parameters: - record: The Record object to expand relations for. - expands: An array of relation names (strings) to expand. - customFetchFunc: Optional function for custom fetching logic. - Returns: The record with expanded relations. $app.dao().expandRecords(records, expands, customFetchFunc) - Expands relations for a list of records. - Parameters: - records: An array of Record objects. - expands: An array of relation names (strings) to expand. - customFetchFunc: Optional function for custom fetching logic. - Returns: The array of records with expanded relations. Accessing Expanded Relations: record.expandedOne(relName) - Retrieves a single expanded relation by its name. - Parameters: - relName: The name of the relation to retrieve. - Returns: The expanded Record object or null. record.expandedAll(relName) - Retrieves all expanded relations for a given relation name (e.g., for a 'has many' relation). - Parameters: - relName: The name of the relation to retrieve. - Returns: An array of expanded Record objects. Example: const record = $app.dao().findFirstRecordByData("articles", "slug", "lorem-ipsum") // expand the "author" and "categories" relations $app.dao().expandRecord(record, ["author", "categories"], null) // print the expanded records console.log(record.expandedOne("author")) console.log(record.expandedAll("categories")) ``` -------------------------------- ### DAO Without Event Hooks Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-database.md Allows performing DAO write operations (create, update, delete) without triggering default `onModel*` event hooks. This can be achieved by calling `Dao.withoutHooks()` or instantiating a new `Dao`. ```javascript const record = $app.dao().findRecordById("articles", "RECORD_ID") // the below WILL fire the onModelBeforeUpdate and onModelAfterUpdate hooks $app.dao().saveRecord(record) // the below WILL NOT fire the onModelBeforeUpdate and onModelAfterUpdate hooks const dao = $app.dao().withoutHooks() // or new Dao($app.dao().db()) dao.saveRecord(record); ``` -------------------------------- ### Load and Use Utility Module in PocketBase Hook Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-overview.md Loads a local JavaScript module using `require()` within a PocketBase hook and calls its exported function. Assumes the module is available via the `__hooks` path. ```javascript // pb_hooks/main.pb.js onAfterBootstrap((e) => { const utils = require(`${__hooks}/utils.js`) utils.hello("world") }) ``` -------------------------------- ### Grouping Logs with logger.withGroup() in PocketBase JS Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-logging.md Demonstrates how to use the `withGroup()` method to create a new logger that wraps all its log attributes under a specified group name. This helps organize and structure log data, especially in complex applications. ```javascript const l = $app .logger() .withGroup("sub") // results in log data {"sub": { "total": 123 }} l.info("message A", "total", 123) ``` -------------------------------- ### Custom Middlewares Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Illustrates how to create and use custom middleware functions in PocketBase. Custom middlewares can intercept requests, perform checks (e.g., header validation), and either proceed with the request chain or return an error. ```javascript function myCustomMiddleware(next) { return (c) => { // eg. inspect some header value before processing the request const header = c.request().header.get("Some-Header"); if (!header) { // throw or return an error throw new BadRequestError("Invalid request"); } return next(c); // proceed with the request chain }; } routerUse(myCustomMiddleware); ``` -------------------------------- ### Custom Record Query (Single Record) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Executes a custom query using the `Dao.recordQuery` builder to fetch a single record. The result is populated into a provided `Record` model instance. ```javascript function findTopArticle() { const record = new Record(); $app.dao().recordQuery("articles") .andWhere($dbx.hashExp({ "status": "active" })) .orderBy("rank ASC") .limit(1) .one(record); return record; } const article = findTopArticle(); ``` -------------------------------- ### Retrieve Current Auth State (Admin/Record) Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-routing.md Explains how to access the current authentication state (admin or auth record) from the request context store using special keys. It also shows an alternative method using `$apis.requestInfo()`. ```javascript const admin = c.get("admin"); // empty if not authenticated as admin const record = c.get("authRecord"); // empty if not authenticated as regular auth record // alternatively, you can also read the auth state from the cached request info const info = $apis.requestInfo(c); const admin = info.admin; // empty if not authenticated as admin const record = info.authRecord; // empty if not authenticated as regular auth record const isGuest = !admin && !record; ``` -------------------------------- ### Fetch Multiple Records by Expressions Source: https://github.com/elierhg/pocketbase-js-docs-v0.22.x/blob/main/js-records.md Fetches multiple records from a collection based on custom database expressions, allowing for complex filtering logic. Supports parameterized expressions for safe input handling. ```javascript // retrieve multiple "articles" collection records by a custom dbx expression(s) // (for all available expressions, please check the Database guide) const records = $app.dao().findRecordsByExpr( "articles", $dbx.exp("LOWER(username) = {:username}", { "username": "John.Doe" }), $dbx.hashExp({ status: "pending" }) ) ```