Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
Address initial review feedback
Browse files Browse the repository at this point in the history
- Update README
- Clarify change to URL escaping implementation per initial review feedback
  • Loading branch information
eyelidlessness committed Mar 2, 2023
1 parent 50d2f76 commit 13b1e9c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ ODK XForms are based off of [W3C XForms](https://en.wikipedia.org/wiki/XForms) w

Historically, forms with many questions or many translations were prohibitively slow to transform. Starting in Enketo Transformer v2.2.1 (Feb 2023), they are much faster.

In v2.3.0 (Mar 2023), a web compatibility layer was introduced so that Enketo Transformer can be run in either a web browser using native DOM/web APIs, or in Node using a partial DOM compatibility layer wrapping equivalent `libxmljs` APIs/behavior. Each respective implementation is aliased as `enketo-transformer/dom`, resolved at build time to `src/dom/web/index.ts` or `src/dom/node/index.ts` respectively. Interfaces for the subset of DOM APIs in use are defined in `src/dom/abstract`, which ensures the Node compatibility layer conforms to the same browser-native interfaces.

Our current primary goals are:

- Using standard DOM APIs so the transformation can be performed client-side.
- Rethink transformation to be as minimal as possible, ideally without XSLT, and moving most (or all) of Enketo Transformer's current responsibilities to other parts of the Enketo stack.
- Identifying and addressing remaining performance bottlenecks to remove the need for server-side caching.

Longer term, we intend to rethink transformation to be as minimal as possible, ideally without XSLT.

### Prerequisites

1. Volta (optional, but recommended)
Expand Down Expand Up @@ -57,7 +57,7 @@ const result = await transform({
// ... do something with result
```

### Web
#### Web

Enketo Transformer may also be used on the web as an ESM module. It is exported as `enketo-transformer/web`:

Expand Down Expand Up @@ -130,6 +130,20 @@ curl -d "xform=<xform>x</xform>&theme=plain&media[myfile.png]=/path/to/somefile.
}
```

### How Enketo Transformer is used by other Enketo projects

Enketo Core uses the `transform` function directly to transform XForm fixtures used in development and test modes. It also currently uses the test/dev server in development mode to transform external XForms. It does not currently use any transformation functionality in production.

Enketo Express uses the `transform` function to serve requests to its server-side transformation API endpoints, and caches transformed XForms in Redis. It also uses the `escapeURLPath` function (implemented in `url.ts`).

Neither project currently uses the following functionality:

- Media URL mapping. Enketo Express has its own implementation of this functionality, so that dynamic media replacements are not cached. This functionality is maintained for backwards compatibility.

- The `openclinica` flag. This functionality is used by OpenClinica's fork of Enketo Express.

- The deprecated `preprocess` option. This functionality _may_ be used to update XForms with deprecated content, but its use is discouraged as users can achieve the same thing by preprocessing their XForms before calling `transform`.

#### Test

- run tests with `npm test`
Expand Down
12 changes: 11 additions & 1 deletion src/url.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const TEMPORARY_HOST = 'http://example.com';

/**
* @package
*
Expand All @@ -6,9 +8,17 @@
export const escapeURLPath = (value: string): string => {
const [scheme] = value.match(/^[a-z]+:/) ?? [];
const isFullyQualified = scheme != null;

/**
* Browser implementations of `URL` do not escape URLs with unknown schemes
* like `jr:, nor do they escape known URLs without a domain like `file:`.
* To work around this limitation, we use a temporary HTTP host to escape
* `jr:` URL paths.
*/
const urlString = isFullyQualified
? value.replace(/^jr:\/*/, 'http://')
: `http://example.com/${value.replace(/^\//, '')}`;
: `${TEMPORARY_HOST}/${value.replace(/^\//, '')}`;

const url = new URL(urlString);

if (isFullyQualified) {
Expand Down

0 comments on commit 13b1e9c

Please sign in to comment.