diff --git a/.gitignore b/.gitignore index aa01b8e..0c770cc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ coverage .vscode dist/ .tap -types/ +types/* +!types/options.d.ts diff --git a/README.md b/README.md index d0a2b62..cdd6c6b 100644 --- a/README.md +++ b/README.md @@ -103,12 +103,13 @@ await eik.load(); ### options -| option | default | type | required | details | -| ----------- | --------------- | --------- | -------- | ------------------------------------------------------------------------------------------------ | -| base | `null` | `string` | `false` | Base root to be used for returned asset files. | -| development | `false` | `boolean` | `false` | Set the module in development mode or not. | -| loadMaps | `false` | `boolean` | `false` | Specifies whether import maps defined in the config should be loaded from the Eik server or not. | -| path | `process.cwd()` | `string` | `false` | Path to directory containing an eik.json file or package.json with eik config. | +| option | default | type | required | details | +| ----------- | --------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------- | +| base | `null` | `string` | `false` | Base root to be used for returned asset files. | +| isLocalhost | `false` | `boolean` | `false` | Determines whether the client produces links to localhost (f. ex. during development) or to the Eik server. | +| development | `false` | `boolean` | `false` | (deprecated) Same as isLocalhost | +| loadMaps | `false` | `boolean` | `false` | Specifies whether import maps defined in the config should be loaded from the Eik server or not. | +| path | `process.cwd()` | `string` | `false` | Path to directory containing an eik.json file or package.json with eik config. | ## API diff --git a/src/index.js b/src/index.js index afe635e..8249dc3 100644 --- a/src/index.js +++ b/src/index.js @@ -7,14 +7,6 @@ const trimSlash = (value = "") => { return value; }; -/** - * @typedef {object} Options - * @property {string} [base=null] - * @property {boolean} [development=false] - * @property {boolean} [loadMaps=false] - * @property {string} [path=process.cwd()] - */ - /** * @typedef {object} ImportMap * @property {Record} imports @@ -36,7 +28,7 @@ const trimSlash = (value = "") => { * @example * ```js * // Serve a local version of a file from `./public` - * // in development and from Eik in production + * // on localhost and from Eik in any other environment. * import path from "node:path"; * import Eik from "@eik/node-client"; * import fastifyStatic from "@fastify/static"; @@ -49,15 +41,15 @@ const trimSlash = (value = "") => { * }); * * const eik = new Eik({ - * development: process.env.NODE_ENV === "development", + * isLocalhost: process.env.NODE_ENV === "development", * base: "/public", * }); * * // load information from `eik.json` and the Eik server * await eik.load(); * - * // when development is true script.value will be /public/script.js. - * // when development is false script.value will be + * // when isLocalhost is true script.value will be /public/script.js. + * // when isLocalhost is false script.value will be * // https://{server}/pkg/{name}/{version}/script.js * // where {server}, {name} and {version} are read from eik.json * const script = eik.file("/script.js"); @@ -80,7 +72,7 @@ const trimSlash = (value = "") => { * ``` */ export default class Eik { - #development; + #isLocalhost; #loadMaps; #config; #path; @@ -88,15 +80,17 @@ export default class Eik { #maps; /** - * @param {Options} options + * @param {import("../types/options.js").Options} options */ constructor({ - development = false, + isLocalhost = false, + development, loadMaps = false, base = "", path = process.cwd(), } = {}) { - this.#development = development; + this.#isLocalhost = + typeof development !== "undefined" ? development : isLocalhost; this.#loadMaps = loadMaps; this.#config = {}; this.#path = path; @@ -107,7 +101,7 @@ export default class Eik { /** * Reads the Eik config from disk into the object instance, used for building {@link file} links in production. * - * If {@link Options.loadMaps} is `true` the import maps + * If `loadMaps` is `true` the import maps * defined in the Eik config will be fetched from the Eik server for * use in {@link maps}. */ @@ -172,28 +166,27 @@ export default class Eik { /** * Similar to {@link file}, this method returns a path to the base on Eik - * (ex. https://eik.store.com/pkg/my-app/1.0.0), or {@link Options.base} - * if {@link Options.development} is true. + * (ex. https://eik.store.com/pkg/my-app/1.0.0), or `base` if `isLocalhost` is true. * * You can use this instead of `file` if you have a directory full of files * and you don't need {@link Asset.integrity}. * * @returns {string} The base path for assets published on Eik - * @throws when {@link Options.development} is false if called before calling {@link load} + * @throws when `isLocalhost` is false if called before calling {@link load} */ base() { - if (this.#development) return this.#base; + if (this.#isLocalhost) return this.#base; return `${this.server}${this.pathname}`; } /** * Get a link to a file that is published on Eik when running in production. - * When {@link Options.development} is `true` the pathname is prefixed - * with the {@link Options.base} option instead of pointing to Eik. + * When `isLocalhost` is `true` the pathname is prefixed + * with the `base` option instead of pointing to Eik. * * @param {string} pathname pathname to the file relative to the base on Eik (ex: /path/to/script.js for a prod URL https://eik.store.com/pkg/my-app/1.0.0/path/to/script.js) * @returns {import('./asset.js').Asset} - * @throws when {@link Options.development} is false if called before calling {@link load} + * @throws when `isLocalhost` is false if called before calling {@link load} * * @example * ```js @@ -239,13 +232,13 @@ export default class Eik { } /** - * When {@link Options.loadMaps} is `true` and you call {@link load}, the client + * When `loadMaps` is `true` and you call {@link load}, the client * fetches the configured import maps from the Eik server. * * This method returns the import maps that were fetched during `load`. * * @returns {ImportMap[]} - * @throws if {@link Options.loadMaps} is not `true` or called before calling {@link load} + * @throws if `loadMaps` is not `true` or called before calling {@link load} * * @example * ```js diff --git a/test/index.test.js b/test/index.test.js index e6f2aed..a957162 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -209,6 +209,49 @@ tap.test( }, ); +tap.test( + 'Client - Default settings - Config is loaded and isLocalhost is set to "true"', + async (t) => { + const client = new Eik({ + isLocalhost: true, + path: t.context.fixture, + }); + await client.load(); + + t.equal(client.name, "eik-fixture", 'Should be same as "name" in eik.json'); + t.equal(client.version, "1.0.2", 'Should be same as "version" in eik.json'); + t.equal(client.type, "pkg", 'Should be "pkg" in eik.json'); + t.equal( + client.server, + t.context.address, + 'Should be same as "server" in eik.json', + ); + t.equal( + client.pathname, + "/pkg/eik-fixture/1.0.2", + 'Should be composed path based on "type", "name" and "version"', + ); + t.end(); + }, +); + +tap.test( + 'Client - Retrieve a file path - isLocalhost is set to "false"', + async (t) => { + const client = new Eik({ + path: t.context.fixture, + isLocalhost: false, + }); + await client.load(); + + const file = "/some/path/foo.js"; + const resolved = client.file(file); + + t.equal(resolved.value, `${client.server}${client.pathname}${file}`); + t.end(); + }, +); + tap.test( 'Client - Retrieve a file path - Development mode is set to "true" - Base is unset', async (t) => { diff --git a/types/options.d.ts b/types/options.d.ts new file mode 100644 index 0000000..4e7b792 --- /dev/null +++ b/types/options.d.ts @@ -0,0 +1,26 @@ +export type Options = { + /** + * Base root to be used for returned asset files. + */ + base?: string; + /** + * Determines whether the client produces links to localhost (f. ex. during development) or to the Eik server. + * @default false + */ + isLocalhost?: boolean; + /** + * @default false + * @deprecated Prefer `isLocalhost` instead for clarity. + */ + development?: boolean; + /** + * Specifies whether import maps defined in the config should be loaded from the Eik server or not. + * @default false + */ + loadMaps?: boolean; + /** + * Path to directory containing an eik.json file or package.json with eik config. + * @default process.cwd() + */ + path?: string; +};