/mlxprs

MarkLogic Extension for Visual Studio Code

Primary LanguageTypeScriptOtherNOASSERTION

MarkLogic Extension for Visual Studio Code

Develop, run, and debug code for MarkLogic in the popular VS Code IDE

Visual Studio Code is a free, cross-platform code editor and development tool from Microsoft. The free, open-source MarkLogic extension for VS Code integrates MarkLogic in the cloud or on your laptop into this modern development environment.

Features

  • Syntax highlighting and IntelliSense for MarkLogic Server-Side JavaScript and XQuery
  • Interactive debugging of JavaScript and XQuery running in MarkLogic, including attaching to in-flight requests and inspecting live variables
  • Real-time query evaluation of JavaScript, XQuery, SQL, and SPARQL against a live Data Hub Service or MarkLogic instance
  • View modules (read-only) in the editor

JavaScript debugging requires version 2.0.0+ of the MarkLogic extension and MarkLogic 10.0-4+.

Getting started

Install this tool using the VS Code built-in marketplace. Search “MarkLogic” from the Extension tab of the activity bar. Click “Install” to download and install the extension.

Configuration

The MarkLogic extension exposes several configuration options from the standard VS Code settings.json file (Cmd-,),

{
  "marklogic.host": "marklogic-instance.geocities.com",
  "marklogic.port": 8040,
  "marklogic.username": "username",
  "marklogic.password": "****************",
  "marklogic.documentsDb": "myproject-content",
  "marklogic.modulesDb": "myproject-modules"
}

You can also set marklogic.authType to DIGEST or BASIC. Digest is the default, and works even if the server is running basic authentication.

Connect and query

To evaluate JavaScript

  1. Type a valid JavaScript query in the editor.
  2. Open the command palette (Shift+Cmd+P)
  3. Select MarkLogic: Eval JS

Query results will open in a new document in the current workspace. Eval XQuery, Eval SQL and Eval SPARQL work the same way.

Inspect a module

To view a module from the configured modules database:

  1. Open the command palette (Shift+Cmd+P)
  2. Select MarkLogic: Show module from the list
  3. Choose the module you'd like to view from the resulting list. The list searches and filters as you type.

The module will appear read-only in a new text buffer.

SSL Configuration

You can turn on SSL with the marklogic.ssl configuration property. If the CA is not in your chain of trust (for example, if the certificate is self-signed), you need to point to the CA in your configuration as well using marklogic.pathToCa. The configuration will look something like this:

{
  "marklogic.ssl": true,
  "marklogic.pathToCa": "/Users/myself/certs/my.own.ca.crt"
}

You can acquire the CA file from the MarkLogic admin pane (usually port 8001), by going to 'Security' -> 'Certificate Templates' -> (cert host name), and then selecting the "Status" tab. There is an "download" button in the "certificate template status" section. Click the "download" button to download a copy of your root CA.

Alternatively, you can turn off client certificate checks altogether. Set marklogic.rejectUnauthorized to false in your VS Code configuration. This is less secure, but may be useful for situations where you can't obtain or use a your own CA, such as when connecting to a IP address rather than a hostname.

Per-query configuration override

You can override your VS Code configured settings by using a block comment as the first language token in a JavaScript or XQuery query. The comment should conform to the following:

  • First line includes the string mlxprs:settings
  • The rest of the comment is valid JSON
  • Includes at least one of the following keys: host, port, user, pwd, contentDb, modulesDb, authType, ssl, pathToCa
  • The corresponding value should be of the right type for the configuration (number for port, boolean for ssl, string otherwise)

The values defined in the JSON will override VS Code's MarkLogic client configuration.

For example:

/* mlxprs:settings
{
  "host": "my-test-host",
  "port": 8079,
  "contentDb": "unit-test-database",
  "note": "These settings are for testing only"
}
*/
'use strict';
cts.doc('/my-testing-doc.json');

or:

(: mlxprs:settings
{
  "host": "my-test-host",
  "contentDb": "unit-test-database",
  "modulesDb": "unit-test-MODULES",
  "user": "unit-tester",
  "pwd": "red,green,refactor",
  "note": "These settings are for testing only"
}
:)
xquery version "1.0-ml";
fn:doc('/my-testing-doc.json')

When this query runs, it will use the host, port, and contentDb specified in the comment, along with the VS Code configuration parameters for the rest of the MarkLogic client definition. (The "note" will be ignored.) Other queries in other editor tabs will not be affected.

Debugging

Both JavaScript and XQuery debuggers support two modes of debugging:

  1. Launch: Evaluates a main module (for JavaScript) or non-library module (for XQuery)
  2. Attach: Intecepts an existing request, such as from an integration test

Where it can, query debugging uses the same VS Code settings used for running queries (for example, marklogic.host, marklogic.username). In addition to these code settings, you will need a launch config in your project (under .vscode/launch.json) for debug-specific parameters.

Open the launch.json from the VS Code command palette with the command: “Debug: Open launch.json” or "Debug.

Below is an example of a launch.json file, with JavaScript and XQuery configurations for both launch and attach:

{
  "version": "2.0.0",
  "configurations": [
    {
      "request": "launch",
      "type": "ml-jsdebugger",
      "name": "Evaluate Current JavaScript Module"
    },
    {
      "request": "attach",
      "type": "ml-jsdebugger",
      "name": "Attach to Debug Request",
      "root": "${workspaceFolder}/src/main/ml-modules/root",
      "debugServerName": "Enter debug server name"
    },
    {
      "request": "launch",
      "type": "xquery-ml",
      "name": "Launch XQY Debug Request",
      "program": "",
      "root": "${workspaceFolder}/src/main/ml-modules/root"
    },
    {
      "request": "attach",
      "type": "xquery-ml",
      "name": "Attach to XQY Debug request",
      "root": "${workspaceFolder}/plugins"
    }
  ]
}

VS Code is syntax-aware of what information should go into launch.json, so take advantage of auto-complete and hover hints as you edit.

Launch

Example 'launch' type configuration items for JavaScript and XQuery:

    {
      "type": "ml-jsdebugger",
      "request": "launch",
      "name": "Evaluate Current JavaScript Module"
    },
    {
      "type": "xquery-ml",
      "request": "launch",
      "name": "Launch XQY Debug Request",
      "program": "",
      "root": "${workspaceFolder}/src/main/ml-modules/root"
    }

By default, launch mode will launch the currently opened file for debugging. An optional "path" (for JavaScript) or "program" (for XQuery) can be provided to specify another file for debugging.

Attach

Here's an example of attach configurations for JavaScript and XQuery:

    {
      "type": "ml-jsdebugger",
      "request": "attach",
      "name": "Attach to Remote JavaScript Request",
      "debugServerName": "jsdbg",
      "path": "${workspaceFolder}/src/main/ml-modules/root"
    },
    {
      "type": "xquery-ml",
      "request": "attach",
      "name": "Attach to XQY Debug request",
      "root": "${workspaceFolder}/plugins"
    }

Attach mode intercepts a paused request in a given debug server, an app server connected to the VS Code debugger. To connect to an app server for debugging:

  1. open the command palette, start typing MarkLogic: Connect... until autocomplete prompts you with "MarkLogic: Connect JavaScript Debug Server" or "MarkLogic: Connect XQuery Debug Server", and choose the command you want.
  2. You'll be prompted to choose a server. Use the name of the app server in the MarkLogic configuration, not its hostname or IP address.
  3. You should see a confirmation message once you're connected

Connecting a server will automatically pause all requests so that you can attach the debugger. When you're done, use either MarkLogic: Disconnect... command to disable debugging and resume handling requests as normal.

Note: Only requests that are launched after a server is connected/made debug server can be attached.

Once you start debugging, a dropdown menu will pop up listing all paused requests on the debug server. Choose the one you want to debug.

Attach screenshot

Use the optional parameter rid to specify a request ID in advance and avoid being prompted for it.

In attach mode for JavaScript, debugServerName is a required parameter in the launch.json. This should be the same server (by name) that you connected to in the Attach section. XQuery attach mode will simply list all attachable queries.

Notes

Debugger module mapping

In order to step through modules that get imported in your code, you need to tell the debugger where to find the modules root in your local project. This is the path parameter (for JavaScript) and root (for XQuery). These parameters are required.

Debugging Limitations

In XQuery attach-mode debugging, you should not 'connect' to the same server you use for queries. Since connecting stops all requests on that app server, you'd lock yourself out. For this reason, the extension will not offer to connect to your configured query client's port. Admin, Manage, HealthCheck, and App-Services are also excluded from debugging.

'Launch' debugging initiated from an unsaved ('Untitled') buffer in VS Code will not work. If you want to launch and debug an ad-hoc query, save it somewhere on disk beforehand.

Neither debugger can cross from one server-side language mode into another. XQuery debugging cannot step into xdmp:javascript-eval() calls, and JavaScript debugging cannot step into xdmp.xqueryEval(). The debugger should step over these calls if you try to step into them.

Evaluating variables in module scope may throw reference error. Possible workarounds:

  • use the variables of interest inside a function, and inspect
  • place an eval() statement inside the affected module

Required Privileges for Evaluation and Debugging

To run queries with the MarkLogic JavaScript and XQuery Debugger, a user will need eval priviliges on your MarkLogic server. These include:

  • xdmp-eval: absolute minimum
  • xdmp-eval-in: to use a non-default content database
  • xdmp-eval-modules-change: to use a non-default modules database or modules root
  • xdmp-eval-modules-change-file: to use the filesystem for modules

For debugging, a user must also have at least one of these privileges:

  • debug-my-request: for debugging requests launched by the debug user only
  • debug-any-request: for debugging requests launched by any user

For more about privileges, see xdmp:eval and Debug functions in the API docs, along with Pre-defined Executive Privileges in the MarkLogic server documentation.

Credit

Aside from excellent development and extension support from Visual Studio Code,

  • Portions of Josh Johnson's vscode-xml project are re-used for XML formatting. The MIT license and source code are kept in the client/xmlFormatting folder of this project.
  • Christy Haragan's marklogic-node-typescript-definitions made this project possible.
  • Paxton Hare's marklogic-sublime xquery-ml.tmLanguage code is used for XQuery-ML syntax and snippets, and the MarkLogic Sublime project inspired this one.