arangojs

repository·main·Indexed 20 days ago

https://github.com/arangodb/arangojs

The official ArangoDB JavaScript driver for Node.js and the browser. It provides a high-level API for interacting with ArangoDB databases via AQL and standard CRUD operations, supporting modern async/await and ES Modules as well as CommonJS.

Tokens
27.7K
Snippets
80
Records
117
Agent score
69%

What's inside arangojs

  1. Avoid streaming transaction leaks in transaction.step()

    main

    When using transaction.step(), you must ensure that each step performs exactly one operation. If you perform multiple operations within a single await trx.step(async () => { ... }) block, subsequent operations may execute outside the transaction context, leading to leaks or unexpected behavior.

    Correct Pattern: Always perform a single operation per step.

    const collection = db.collection(collectionName);
    const trx = db.transaction(transactionId);
    
    // CORRECT: Perform a single operation per step
    await trx.step(() => collection.save(doc1));
    await trx.step(() => collection.save(doc2));
  2. Manage Unicode normalization in v8 to v9 migration

    main

    Starting with version 9, arangojs no longer automatically performs NFC normalization on Unicode names and identifiers (collections, graphs, indexes, views, users, databases, etc.). To ensure compatibility with ArangoDB if you require normalization, manually call the .normalize("NFC") method on your strings.

     import { Database } from "arangojs";
     
     const db = new Database();
    -const collection = db.collection(myUnicodeName);
    +const collection = db.collection(myUnicodeName.normalize("NFC"));
  3. Understand arangojs error types

    main

    The driver categorizes errors into three main types based on their origin:

    1. ArangoError: Thrown when the ArangoDB server returns an error response. It includes an errorNum property (the ArangoDB error code) and a response property containing the response body.
    2. NetworkError: Thrown for errors occurring during the request/response cycle (e.g., connection issues). It includes a request property.
      • HttpError: A subclass of NetworkError thrown when the server responds with a non-2xx status code. It includes a code property (HTTP status code) and a response property.
    3. Exception-based errors: If an error is caused by an exception, it is exposed via the cause property of the thrown error object.
  4. Use arangojs in the browser via CDN

    main

    For browser-based development without a bundler, you can use an import map with the jsDelivr CDN to load the ESM version of arangojs.

    <script type="importmap">
      {
        "imports": {
          "arangojs": "https://cdn.jsdelivr.net/npm/arangojs@10.0.0/esm/index.js?+esm"
        }
      }
    </script>
    <script type="module">
      import { Database } from "arangojs";
      const db = new Database();
      // ...
    </script>
  5. Migrate from v8 to v9

    main

    When upgrading to version 9, note the following breaking changes:

    Default URL Change

    • The default URL changed from http://localhost:8529 to http://127.0.0.1:8529. If you require localhost resolution (e.g., for IPv6 support), specify the URL explicitly in the Database constructor.

    Database Instance Management

    • The db.useDatabase method is deprecated. To interact with a different database, use db.database(name) to create a new Database instance.

    Queries and Users

    • aql.literal and aql.join must be imported separately from arangojs/aql rather than accessed via the aql template handler.
    • db.getUserDatabases and db.getUserAccessLevel return values have changed; they no longer wrap results in a .result object.
     import { Database } from "arangojs";
    
     const db = new Database({
    +  url: "http://localhost:8529"
     });
    
     // Instead of db.useDatabase("database2")
    +const db2 = db.database("database2");
  6. Update module imports for v10 resource types

    main

    In version 10, module names referring to resource types (analyzers, collections, databases, or views) have been changed from singular to plural forms. Note that aql and foxx-manifest modules remain unchanged as they are utility modules.

    -import { Database } from "arangojs/database";
    +import { Database } from "arangojs/databases";
  7. Migrate from v9 to v10

    main

    When upgrading to version 10, note the following breaking changes:

    Module name changes

    • The Dict<T> type from arangojs/connection is removed. Use the built-in TypeScript Record<string, T> instead.
    • The GraphCreateOptions type has been renamed to CreateGraphOptions in arangojs/graph.
    • Enums CollectionStatus and CollectionType must now be imported from arangojs/collection instead of the main arangojs module.
    • The ViewType enum has been removed; use the string literal "arangosearch" for ArangoSearch views.

    AQL and Queries

    • aql.join is no longer a method on the aql template handler. Import join separately from arangojs/aql.

    User Management

    • db.getUserDatabases and db.getUserAccessLevel no longer return a .result property. They now return the result directly.
     import { Database } from "arangojs";
    -import type { Dict } from "arangojs/connection";
    
     const db = new Database();
    -let deps: Dict<string | string[] | undefined>;
    +let deps: Record<string, string | string[] | undefined>;
     deps = await db.getServiceDependencies("/my-foxx-service", true);
  8. Configure Unix domain sockets and self-signed HTTPS in Node.js

    main

    To use Unix domain sockets or support self-signed HTTPS certificates in Node.js, you must install undici as a peer dependency:

    npm install --save undici

    Using self-signed certificates

    You can provide CA certificates via the agentOptions configuration in the Database constructor:

    import { Database } from "arangojs";
    import fs from "fs";
    
    const db = new Database({
      url: ARANGODB_SERVER,
      agentOptions: {
        ca: [
          fs.readFileSync(".ssl/sub.class1.server.ca.pem"),
          fs.readFileSync(".ssl/ca.pem"),
        ],
      },
    });

    Alternatively, you can use undici's setGlobalDispatcher to override the global fetch agent.

  9. Migrate from v6 to v7

    main

    When upgrading to version 7, note the following breaking changes:

    Configuration and Connections

    • db.useDatabase is deprecated. Specify the database name using the databaseName option in the Database configuration.
    • You can now share a connection pool by creating multiple Database objects from the same instance using db.database(name).

    Collections and Indexes

    • Specific index helper methods (e.g., createHashIndex) are removed. Use the generic ensureIndex method with a type option.
    • db.edgeCollection is removed. Use db.collection for all collection types. In TypeScript, you can cast to EdgeCollection<T> or DocumentCollection<T> if needed.
    • db.edge(id) is removed; use db.collection(name).document(id) instead.
    • For Graph collections, use the .vertex() or .edge() methods for high-level access, or access the low-level API via the .collection property.

    Data Operations

    • save for edges no longer accepts positional _from and _to arguments. These must be included in the document object.
    • bulkUpdate is removed. Use saveAll, updateAll, replaceAll, or removeAll for bulk operations.
    • db.truncate() is removed. To truncate all collections, iterate through db.collections() and call .truncate() on each.

    Cursors and Queries

    • cursor.each is renamed to cursor.forEach.
    • cursor.hasNext() is replaced by the hasNext getter.
    • cursor.some() and cursor.every() are removed. Emulate them using forEach or, preferably, more efficient AQL queries.
    • Batch API: cursor.hasMore() and cursor.nextBatch() are replaced by cursor.batches.hasMore (getter) and cursor.batches.next().
    • db.query options are now flattened. Nested options properties are no longer used.

    Other Changes

    • ArangoSearch: db.arangoSearchView and db.createArangoSearchView are renamed to db.view and db.createView.
    • Transactions: db.transaction is no longer an alias for db.executeTransaction. Use db.executeTransaction explicitly.
    • Graph Creation: db.createGraph and graph.create now take an array of edge definitions as the first argument.
     // Instead of db.useDatabase("database1")
    +const db1 = new Database({ databaseName: "database1" });
    +const db2 = db1.database("database2");
    
     // Instead of collection.createGeoIndex(["lat", "lng"])
    +await collection.ensureIndex({ type: "geo", fields: ["lat", "lng"] });
    
     // Instead of edges.save("v1", "v2", { color: "red" })
    +await edges.save({ _from: "v1", _to: "v2", color: "red" });
  10. Configure Database connection in v9 (Fetch API migration)

    main

    Version 9 transitioned to using the native fetch API in all environments. Consequently, agentOptions and agent configuration options have been removed. These have been replaced by properties within the main configuration object:

    • maxSockets is now poolSize
    • keepAlive is now keepalive
    • before is now beforeRequest
    • after is now afterResponse

    If you need to customize the underlying Node.js agent beyond these options, you must use the undici module to set a global dispatcher.

      const db = new Database({
        url: "http://localhost:8529",
    -   agentOptions: {
    -     maxSockets: 10,
    -     keepAlive: true,
    -     before: (req) => console.log(String(new Date()), 'requesting', req.url),
    -     after: (res) => console.log(String(new Date()), 'received', res.request.url)
    -   }
    +   poolSize: 10,
    +   keepalive: true,
    +   beforeRequest: (req) => console.log(String(new Date()), 'requesting', req.url),
    +   afterResponse: (res) => console.log(String(new Date()), 'received', res.request.url)
      });

    To use a custom agent in Node.js:

    const { Agent, setGlobalDispatcher } = require("undici");
    
    setGlobalDispatcher(
      new Agent({
        // your agent options here
      })
    );
  11. Create and manage ArangoDB access tokens

    main

    Access tokens allow for authentication without using a password.

    Creating a token

    When creating a token using CreateAccessTokenOptions, provide a unique name. You can optionally provide valid_until as a Unix timestamp (in seconds). If valid_until is not provided, the token does not expire. Note that Date objects are not accepted; you must use a number.

    Token lifecycle and visibility

    • Creation: The AccessToken object returned immediately after creation is the only time the actual token string value is visible.
    • Listing: When listing tokens, you receive AccessTokenMetadata, which contains all information (ID, name, expiration, fingerprint, etc.) except the actual token value. This is a security measure; the token cannot be retrieved again once lost.