@eik/common 2.0.3 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +13 -11
  3. package/eikjson.d.ts +41 -0
  4. package/lib/classes/custom-error.js +3 -0
  5. package/lib/classes/eik-config.js +108 -47
  6. package/lib/classes/file-mapping.js +40 -0
  7. package/lib/classes/invalid-config-error.js +3 -0
  8. package/lib/classes/local-file-location.js +59 -0
  9. package/lib/classes/missing-config-error.js +3 -0
  10. package/lib/classes/no-files-matched-error.js +3 -0
  11. package/lib/classes/read-file.js +4 -8
  12. package/lib/classes/remote-file-location.js +41 -0
  13. package/lib/classes/resolved-files.js +56 -0
  14. package/lib/classes/single-dest-multiple-source-error.js +3 -0
  15. package/lib/helpers/config-store.js +22 -5
  16. package/lib/helpers/get-defaults.js +4 -2
  17. package/lib/helpers/index.js +21 -2
  18. package/lib/helpers/local-assets.js +44 -48
  19. package/lib/helpers/path-slashes.js +43 -0
  20. package/lib/helpers/resolve-files.js +81 -0
  21. package/lib/helpers/type-slug.js +6 -0
  22. package/lib/helpers/type-title.js +7 -0
  23. package/lib/schemas/assert.js +11 -9
  24. package/lib/schemas/eikjson.schema.json +10 -5
  25. package/lib/schemas/index.js +1 -1
  26. package/lib/schemas/validate.js +1 -2
  27. package/lib/schemas/validation-error.js +6 -2
  28. package/lib/stream.js +9 -2
  29. package/lib/validators/index.js +8 -8
  30. package/package.json +33 -23
  31. package/types/classes/custom-error.d.ts +7 -0
  32. package/types/classes/eik-config.d.ts +58 -0
  33. package/types/classes/file-mapping.d.ts +21 -0
  34. package/types/classes/invalid-config-error.d.ts +4 -0
  35. package/types/classes/local-file-location.d.ts +36 -0
  36. package/types/classes/missing-config-error.d.ts +4 -0
  37. package/types/classes/multiple-config-sources-error.d.ts +5 -0
  38. package/types/classes/no-files-matched-error.d.ts +4 -0
  39. package/types/classes/read-file.d.ts +15 -0
  40. package/types/classes/remote-file-location.d.ts +21 -0
  41. package/types/classes/resolved-files.d.ts +20 -0
  42. package/types/classes/single-dest-multiple-source-error.d.ts +4 -0
  43. package/types/helpers/config-store.d.ts +31 -0
  44. package/types/helpers/get-defaults.d.ts +2 -0
  45. package/types/helpers/index.d.ts +11 -0
  46. package/types/helpers/local-assets.d.ts +8 -0
  47. package/types/helpers/path-slashes.d.ts +32 -0
  48. package/types/helpers/resolve-files.d.ts +13 -0
  49. package/types/helpers/type-slug.d.ts +2 -0
  50. package/types/helpers/type-title.d.ts +2 -0
  51. package/types/index.d.ts +7 -0
  52. package/types/schemas/assert.d.ts +8 -0
  53. package/types/schemas/index.d.ts +71 -0
  54. package/types/schemas/validate.d.ts +26 -0
  55. package/types/schemas/validation-error.d.ts +8 -0
  56. package/types/stream.d.ts +2 -0
  57. package/types/validators/index.d.ts +8 -0
  58. package/lib/helpers/package-url.js +0 -20
package/CHANGELOG.md CHANGED
@@ -1,3 +1,91 @@
1
+ ## [3.0.1](https://github.com/eik-lib/common/compare/v3.0.0...v3.0.1) (2022-05-04)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update dependency glob to v8 ([#225](https://github.com/eik-lib/common/issues/225)) ([fd01a56](https://github.com/eik-lib/common/commit/fd01a566b404164bdc847cc7a1803b124e131e41))
7
+ * **deps:** update dependency validate-npm-package-name to v4 ([#222](https://github.com/eik-lib/common/issues/222)) ([c3721ab](https://github.com/eik-lib/common/commit/c3721abf058c93d4e500945c3c014c748c1f2acd))
8
+
9
+ # [3.0.0](https://github.com/eik-lib/common/compare/v2.0.3...v3.0.0) (2021-08-12)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * ensure absolute file paths work as expected ([4f6ce5e](https://github.com/eik-lib/common/commit/4f6ce5e251dcbf0df0b51cc36f73b10585b96538))
15
+ * include eik json schema file in package when publishing ([f0c3c45](https://github.com/eik-lib/common/commit/f0c3c45439a637e8a3cb3a475bca70f2a77c1901))
16
+ * update require statements to avoid circular dependencies ([4359bec](https://github.com/eik-lib/common/commit/4359bec140539c6144be48f7b9ff774b9601d068))
17
+
18
+
19
+ ### Features
20
+
21
+ * add extension, mime-type and content-type to file location ([a9b4fe1](https://github.com/eik-lib/common/commit/a9b4fe15cf39425070b9bd260183656933d94c5d))
22
+ * Add hapi support for local assets ([7528c32](https://github.com/eik-lib/common/commit/7528c3277c537e7e0a4228c949988bc7e7a90074))
23
+ * add mappings() method to eik config object ([f989ae0](https://github.com/eik-lib/common/commit/f989ae0e2de0aa5646fd33d0f5854bc7e74c8734)), closes [/github.com/eik-lib/issues/issues/2#issuecomment-779099732](https://github.com//github.com/eik-lib/issues/issues/2/issues/issuecomment-779099732)
24
+
25
+
26
+ * refactor!: packageURL removed, localAssets fixed and updated ([90fd181](https://github.com/eik-lib/common/commit/90fd1818f69384d4edeb056dc2c8367e51b21d44))
27
+ * refactor!: remove pathsAndFiles methods ([90d8a12](https://github.com/eik-lib/common/commit/90d8a12e4df8e3a37f295c6136e94bf4ade68cb4))
28
+ * feat!: preserve directory structure when globbing in config ([dff2830](https://github.com/eik-lib/common/commit/dff28301f9bc6e37ef9db32455fa64f5a7a9e80a))
29
+
30
+
31
+ ### BREAKING CHANGES
32
+
33
+ * packageURL was removed as it no longer makes sense given the changes to eik json files config
34
+
35
+ localAssets has been refactored to use the new mappings method of eik config
36
+ * Consumers of the Eik Config class will all need to be updated to use the newer .mappings() method instead.
37
+ * directory structures are no longer flattened
38
+
39
+ # [4.0.0-next.4](https://github.com/eik-lib/common/compare/v4.0.0-next.3...v4.0.0-next.4) (2021-02-23)
40
+
41
+
42
+ ### Bug Fixes
43
+
44
+ * include eik json schema file in package when publishing ([f0c3c45](https://github.com/eik-lib/common/commit/f0c3c45439a637e8a3cb3a475bca70f2a77c1901))
45
+
46
+ # [4.0.0-next.3](https://github.com/eik-lib/common/compare/v4.0.0-next.2...v4.0.0-next.3) (2021-02-23)
47
+
48
+
49
+ ### Bug Fixes
50
+
51
+ * update require statements to avoid circular dependencies ([4359bec](https://github.com/eik-lib/common/commit/4359bec140539c6144be48f7b9ff774b9601d068))
52
+
53
+ # [4.0.0-next.2](https://github.com/eik-lib/common/compare/v4.0.0-next.1...v4.0.0-next.2) (2021-02-23)
54
+
55
+
56
+ ### Bug Fixes
57
+
58
+ * ensure absolute file paths work as expected ([4f6ce5e](https://github.com/eik-lib/common/commit/4f6ce5e251dcbf0df0b51cc36f73b10585b96538))
59
+
60
+ # [4.0.0-next.1](https://github.com/eik-lib/common/compare/v3.0.0-next.1...v4.0.0-next.1) (2021-02-19)
61
+
62
+
63
+ ### Features
64
+
65
+ * Add hapi support for local assets ([7528c32](https://github.com/eik-lib/common/commit/7528c3277c537e7e0a4228c949988bc7e7a90074))
66
+
67
+ # [3.0.0-next.1](https://github.com/eik-lib/common/compare/v2.0.3...v3.0.0-next.1) (2021-02-18)
68
+
69
+
70
+ ### Features
71
+
72
+ * add extension, mime-type and content-type to file location ([a9b4fe1](https://github.com/eik-lib/common/commit/a9b4fe15cf39425070b9bd260183656933d94c5d))
73
+ * add mappings() method to eik config object ([f989ae0](https://github.com/eik-lib/common/commit/f989ae0e2de0aa5646fd33d0f5854bc7e74c8734)), closes [/github.com/eik-lib/issues/issues/2#issuecomment-779099732](https://github.com//github.com/eik-lib/issues/issues/2/issues/issuecomment-779099732)
74
+
75
+
76
+ * refactor!: packageURL removed, localAssets fixed and updated ([90fd181](https://github.com/eik-lib/common/commit/90fd1818f69384d4edeb056dc2c8367e51b21d44))
77
+ * refactor!: remove pathsAndFiles methods ([90d8a12](https://github.com/eik-lib/common/commit/90d8a12e4df8e3a37f295c6136e94bf4ade68cb4))
78
+ * feat!: preserve directory structure when globbing in config ([dff2830](https://github.com/eik-lib/common/commit/dff28301f9bc6e37ef9db32455fa64f5a7a9e80a))
79
+
80
+
81
+ ### BREAKING CHANGES
82
+
83
+ * packageURL was removed as it no longer makes sense given the changes to eik json files config
84
+
85
+ localAssets has been refactored to use the new mappings method of eik config
86
+ * Consumers of the Eik Config class will all need to be updated to use the newer .mappings() method instead.
87
+ * directory structures are no longer flattened
88
+
1
89
  ## [2.0.3](https://github.com/eik-lib/common/compare/v2.0.2...v2.0.3) (2021-02-11)
2
90
 
3
91
 
package/README.md CHANGED
@@ -8,7 +8,7 @@ This package contains common utilities and schemas
8
8
 
9
9
  #### eik.json
10
10
 
11
- Importing schemas
11
+ Importing schemas
12
12
 
13
13
  ```js
14
14
  const { schemas, assert } = require('@eik/common');
@@ -24,7 +24,7 @@ const { error, value } = schemas.validate.eikJSON({
24
24
  files: [],
25
25
  });
26
26
 
27
- //or
27
+ //or
28
28
 
29
29
  assert.eikJSON({
30
30
  name: 'my-app',
@@ -75,24 +75,27 @@ const { error, value } = schemas.validate.server('http://myeikserver.com');
75
75
 
76
76
  assert.server('http://myeikserver.com');
77
77
  ```
78
+
78
79
  ##### files
79
80
 
80
81
  ```js
81
82
  const { error, value } = schemas.validate.files({
82
- './index.js': '/path/to/file.js'
83
+ './index.js': '/path/to/file.js',
83
84
  });
84
85
 
85
86
  // or
86
87
 
87
88
  assert.files({
88
- './index.js': '/path/to/file.js'
89
+ './index.js': '/path/to/file.js',
89
90
  });
90
91
  ```
91
92
 
92
93
  ##### import map
93
94
 
94
95
  ```js
95
- const { error, value } = schemas.validate.importMap('http://meserver.com/map.json');
96
+ const { error, value } = schemas.validate.importMap(
97
+ 'http://meserver.com/map.json',
98
+ );
96
99
 
97
100
  const { error, value } = schemas.validate.importMap([
98
101
  'http://meserver.com/map1.json',
@@ -137,10 +140,10 @@ For an `eik.json` file such as
137
140
  "name": "my-app",
138
141
  "version": "1.0.0",
139
142
  "server": "https://assets.myeikserver.com",
140
- "files" :{
143
+ "files": {
141
144
  "esm.js": "./assets/esm.js",
142
145
  "esm.css": "./assets/esm.css",
143
- "/": "./assets/**/*.map",
146
+ "/": "./assets/**/*.map"
144
147
  }
145
148
  }
146
149
  ```
@@ -156,7 +159,7 @@ A number of routes would be mounted into your app.
156
159
 
157
160
  #### packageURL
158
161
 
159
- This helper function can be used to build URLs for given entries in an `eik.json` files section.
162
+ This helper function can be used to build URLs for given entries in an `eik.json` files section.
160
163
 
161
164
  Given the following `eik.json` file:
162
165
 
@@ -165,10 +168,10 @@ Given the following `eik.json` file:
165
168
  "name": "my-app",
166
169
  "version": "1.0.0",
167
170
  "server": "https://assets.myeikserver.com",
168
- "files" :{
171
+ "files": {
169
172
  "esm.js": "./assets/esm.js",
170
173
  "esm.css": "./assets/esm.css",
171
- "/": "./assets/**/*.map",
174
+ "/": "./assets/**/*.map"
172
175
  }
173
176
  }
174
177
  ```
@@ -181,4 +184,3 @@ const url = await helpers.packageURL('esm.js');
181
184
  ```
182
185
 
183
186
  The URL returned will be `https://assets.myeikserver.com/pkg/my-app/1.0.0/esm.js`
184
-
package/eikjson.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /* tslint:disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export interface EikjsonSchema {
9
+ /**
10
+ * The URL address of the Eik server where packages are published to.
11
+ */
12
+ server: string;
13
+ /**
14
+ * The name of the Eik package. Follows the same rules as for NPM package names. Must be parseable by validate-npm-package-name package, which is bundled with npm as a dependency.
15
+ */
16
+ name: string;
17
+ /**
18
+ * The version of the Eik package. Follows the same rules as for NPM package versions. Must be parseable by node-semver, which is bundled with npm as a dependency.
19
+ */
20
+ version: string;
21
+ /**
22
+ * The type of the Eik package. Must be one of 'package', 'npm' or 'map'. Setting this value changes the URL publish namespace between '/pkg' (default), '/npm' and '/map', use 'npm' when publishing NPM packages. Use 'map' when publishing import maps.
23
+ */
24
+ type?: "package" | "npm" | "map";
25
+ /**
26
+ * File mapping definition for the package. Keys represent files or paths to be created on the Eik Server. Values represent paths to local files to be published.
27
+ */
28
+ files:
29
+ | {
30
+ [k: string]: string;
31
+ }
32
+ | string;
33
+ /**
34
+ * Import map files given by URL(s) to be used during package bundling. Specified as a URL or array of URLs. URLs are locations of import map files that follow the W3C import map spec.
35
+ */
36
+ "import-map"?: string | string[];
37
+ /**
38
+ * Location of local Eik build directory (defaults to .eik). Used by Eik client.
39
+ */
40
+ out?: string;
41
+ }
@@ -1,4 +1,7 @@
1
1
  module.exports = class CustomError extends Error {
2
+ /**
3
+ * @param {string} message
4
+ */
2
5
  constructor(message) {
3
6
  super(message);
4
7
  this.name = this.constructor.name;
@@ -1,38 +1,77 @@
1
- const { promisify } = require('util');
2
- const path = require('path');
3
- const glob = promisify(require('glob'));
1
+ /* eslint-disable no-continue */
2
+
3
+ /**
4
+ * @type {(value: unknown, message?: string) => asserts value}
5
+ */
6
+ const assert = require('assert');
7
+ const { extname, join, isAbsolute } = require('path');
4
8
  const NoFilesMatchedError = require('./no-files-matched-error');
5
9
  const SingleDestMultipleSourcesError = require('./single-dest-multiple-source-error');
6
- const { assert, schema } = require('../schemas');
10
+ const FileMapping = require('./file-mapping');
11
+ const RemoteFileLocation = require('./remote-file-location');
12
+ const schemas = require('../schemas');
13
+ const { removeTrailingSlash } = require('../helpers/path-slashes');
14
+ const typeSlug = require('../helpers/type-slug');
15
+ const resolveFiles = require('../helpers/resolve-files');
7
16
 
8
17
  const _config = Symbol('config');
9
18
  const _tokens = Symbol('tokens');
10
19
 
20
+ /**
21
+ * Normalizes Eik JSON "files" definition to object form if in string form
22
+ *
23
+ * @param {EikjsonSchema["files"]} files
24
+ *
25
+ * @returns {{[k: string]: string;}}
26
+ */
27
+ const normalizeFilesDefinition = (files) =>
28
+ typeof files === 'string' ? { '/': files } : files;
29
+
30
+ /**
31
+ * @typedef {import ("../../eikjson").EikjsonSchema} EikjsonSchema
32
+ */
33
+
11
34
  module.exports = class EikConfig {
12
- constructor(configHash, tokens, configRootDir) {
13
- this[_config] = configHash;
35
+ /**
36
+ * @param {EikjsonSchema?} configHash
37
+ * @param {[string, string][]?} tokens
38
+ * @param {string?} configRootDir
39
+ */
40
+ constructor(configHash, tokens = null, configRootDir = process.cwd()) {
41
+ /** @type EikjsonSchema */
42
+ this[_config] = JSON.parse(JSON.stringify(configHash)) || {};
14
43
  this[_tokens] = new Map(tokens);
15
- this.cwd = configRootDir;
16
- this.map = [].concat(configHash['import-map'] || []);
44
+
45
+ assert(
46
+ isAbsolute(configRootDir),
47
+ `"configRootDir" must be an absolute path: "${configRootDir}" given`,
48
+ );
49
+ this.cwd = removeTrailingSlash(configRootDir);
50
+ /** @type {string[]} */
51
+ this.map = [].concat(this[_config]['import-map'] || []);
17
52
  }
18
53
 
54
+ /** @type {EikjsonSchema["name"]} */
19
55
  get name() {
20
56
  return this[_config].name;
21
57
  }
22
58
 
59
+ /** @type {EikjsonSchema["version"]} */
23
60
  get version() {
24
61
  return this[_config].version;
25
62
  }
26
63
 
27
64
  set version(newVersion) {
28
- assert.version(newVersion);
65
+ schemas.assert.version(newVersion);
29
66
  this[_config].version = newVersion;
30
67
  }
31
68
 
69
+ /** @type {EikjsonSchema["type"]} */
32
70
  get type() {
33
- return this[_config].type || schema.properties.type.default;
71
+ return this[_config].type || schemas.schema.properties.type.default;
34
72
  }
35
73
 
74
+ /** @type {string} */
36
75
  get server() {
37
76
  const configuredServer = this[_config].server;
38
77
  if (configuredServer) {
@@ -41,64 +80,86 @@ module.exports = class EikConfig {
41
80
  return this[_tokens].keys().next().value;
42
81
  }
43
82
 
83
+ /** @type {[string, string][]} */
44
84
  get token() {
45
85
  return this[_tokens].get(this.server);
46
86
  }
47
87
 
88
+ /** @type {EikjsonSchema["files"]} */
48
89
  get files() {
49
90
  return this[_config].files;
50
91
  }
51
92
 
93
+ /**
94
+ * Normalized relative directory path with any leading ./ or
95
+ * trailing / characters stripped. Defaults to .eik
96
+ *
97
+ * @returns {string} out path string
98
+ */
52
99
  get out() {
53
- return this[_config].out || '.eik';
100
+ const defaulted = this[_config].out || '.eik';
101
+ const out = defaulted.startsWith('./')
102
+ ? defaulted.substr(2)
103
+ : defaulted;
104
+ return removeTrailingSlash(out);
54
105
  }
55
106
 
107
+ /**
108
+ * Serializes internal values to an object
109
+ *
110
+ * @returns {EikjsonSchema} object consistent with EikjsonSchema
111
+ */
56
112
  toJSON() {
57
113
  return { ...this[_config] };
58
114
  }
59
115
 
116
+ /**
117
+ * Validates config values against the eik JSON schema
118
+ *
119
+ * @return {void}
120
+ */
60
121
  validate() {
61
- assert.eikJSON(this[_config]);
122
+ schemas.assert.eikJSON(this[_config]);
62
123
  }
63
124
 
64
- async pathsAndFiles() {
65
- const resolvedFiles = await Promise.all(
66
- Object.entries(this.files).map(([pathname, file]) =>
67
- Promise.all([pathname, file, glob(file, { cwd: this.cwd })]),
68
- ),
69
- );
70
- return resolvedFiles.flatMap(([pathname, file, filePaths]) => {
71
- if (filePaths.length === 0) {
72
- throw new NoFilesMatchedError(file);
125
+ /**
126
+ * Resolves file locations on disk based on values defined in files property
127
+ * of config object.
128
+ *
129
+ * @returns {Promise<FileMapping[]>}
130
+ */
131
+ async mappings() {
132
+ const normalizedFiles = normalizeFilesDefinition(this.files);
133
+ const resolvedFiles = await resolveFiles(normalizedFiles, this.cwd);
134
+
135
+ return resolvedFiles.flatMap((files) => {
136
+ const { destination, source } = files;
137
+ const filesArray = Array.from(files);
138
+ if (filesArray.length === 0) {
139
+ throw new NoFilesMatchedError(source);
73
140
  }
74
141
 
75
- const url = new URL(pathname, 'http://origin');
76
- const basename = path.basename(url.pathname);
77
- const isNamedDest = basename.includes('.');
78
-
79
- if (isNamedDest) {
80
- if (filePaths.length > 1)
81
- throw new SingleDestMultipleSourcesError(pathname);
82
- return [[pathname, filePaths[0], pathname, file]];
142
+ if (extname(destination) !== '' && filesArray.length > 1) {
143
+ throw new SingleDestMultipleSourcesError(destination);
83
144
  }
84
- return filePaths.map((filePath) => [
85
- path.join(pathname, path.basename(filePath)),
86
- filePath,
87
- pathname,
88
- file,
89
- ]);
90
- });
91
- }
92
145
 
93
- async pathsAndFilesAbsolute() {
94
- const relativePathsAndFiles = await this.pathsAndFiles();
95
- return relativePathsAndFiles.reduce((acc, [destPath, srcPath]) => {
96
- const absoluteSrc = path.isAbsolute(srcPath)
97
- ? srcPath
98
- : path.join(this.cwd, srcPath);
99
- const absoluteDest = path.join(this.cwd, this.out, destPath);
100
- acc.set(absoluteSrc, absoluteDest);
101
- return acc;
102
- }, new Map());
146
+ return filesArray.map((localFile) => {
147
+ const shouldMapFilename = extname(destination);
148
+ const relativePathname = shouldMapFilename
149
+ ? destination
150
+ : join(destination, localFile.relative);
151
+ const packagePathname = join(
152
+ typeSlug(this.type),
153
+ this.name,
154
+ this.version,
155
+ );
156
+ const remoteDestination = new RemoteFileLocation(
157
+ relativePathname,
158
+ packagePathname,
159
+ this.server,
160
+ );
161
+ return new FileMapping(localFile, remoteDestination);
162
+ });
163
+ });
103
164
  }
104
165
  };
@@ -0,0 +1,40 @@
1
+ /* eslint-disable no-unused-vars */
2
+
3
+ /**
4
+ * @type {(value: unknown, message?: string) => asserts value}
5
+ */
6
+ const assert = require('assert');
7
+ const LocalFileLocation = require('./local-file-location');
8
+ const RemoteFileLocation = require('./remote-file-location');
9
+
10
+ /**
11
+ * Class containing a local file system source location and remote server destination location for a file.
12
+ */
13
+ class FileMapping {
14
+ /**
15
+ * @param {LocalFileLocation} source
16
+ * @param {RemoteFileLocation} destination
17
+ */
18
+ constructor(source, destination) {
19
+ assert(
20
+ source instanceof LocalFileLocation,
21
+ '"source" must be an instance of LocalFileLocation',
22
+ );
23
+ assert(
24
+ destination instanceof RemoteFileLocation,
25
+ '"destination" must be an instance of RemoteFileLocation',
26
+ );
27
+
28
+ /**
29
+ * @type {LocalFileLocation} source
30
+ */
31
+ this.source = source;
32
+
33
+ /**
34
+ * @type {RemoteFileLocation} destination
35
+ */
36
+ this.destination = destination;
37
+ }
38
+ }
39
+
40
+ module.exports = FileMapping;
@@ -1,6 +1,9 @@
1
1
  const CustomError = require('./custom-error');
2
2
 
3
3
  module.exports = class InvalidConfigError extends CustomError {
4
+ /**
5
+ * @param {string} msg
6
+ */
4
7
  constructor(msg) {
5
8
  super(`Eik config object was invalid: '${msg}'`);
6
9
  }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @type {(value: unknown, message?: string) => asserts value}
3
+ */
4
+ const assert = require('assert');
5
+ const { join, extname, isAbsolute } = require('path');
6
+ const mime = require('mime-types');
7
+
8
+ /**
9
+ * Class containing information about a local file
10
+ */
11
+ class LocalFileLocation {
12
+ /**
13
+ * @param {string} path path to file on disk relative to basePath
14
+ * @param {string} basePath basePath to the file's location on disk
15
+ */
16
+ constructor(path, basePath) {
17
+ assert(typeof path === 'string', '"path" must be of type "string"');
18
+ assert(
19
+ typeof basePath === 'string',
20
+ '"basePath" must be of type "string"',
21
+ );
22
+ assert(!isAbsolute(path), '"path" must be a relative path');
23
+
24
+ /**
25
+ * @type {string} path to file on disk relative to this.basePath
26
+ */
27
+ this.relative = path;
28
+
29
+ /**
30
+ * @type {string} absolute path to root files location on disk
31
+ */
32
+ this.basePath = basePath;
33
+
34
+ /**
35
+ * @type {string} absolute path to file on disk,
36
+ * this is a concatentation of this.basePath and this.relative
37
+ */
38
+ this.absolute = join(basePath, path);
39
+
40
+ /**
41
+ * @type {string} file extension with "." character included. (eg. ".json")
42
+ */
43
+ this.extension = extname(path);
44
+
45
+ /**
46
+ * @type {string} full content-type header value for file
47
+ */
48
+ this.contentType =
49
+ mime.contentType(this.extension) || 'application/octet-stream';
50
+
51
+ /**
52
+ * @type {string} mime type of file
53
+ */
54
+ this.mimeType =
55
+ mime.lookup(this.extension) || 'application/octet-stream';
56
+ }
57
+ }
58
+
59
+ module.exports = LocalFileLocation;
@@ -1,6 +1,9 @@
1
1
  const CustomError = require('./custom-error');
2
2
 
3
3
  module.exports = class MissingConfigError extends CustomError {
4
+ /**
5
+ * @param {string} dir
6
+ */
4
7
  constructor(dir) {
5
8
  super(`No package.json or eik.json file found in: '${dir}'`);
6
9
  }
@@ -1,6 +1,9 @@
1
1
  const CustomError = require('./custom-error');
2
2
 
3
3
  module.exports = class NoFilesMatchedError extends CustomError {
4
+ /**
5
+ * @param {string} file
6
+ */
4
7
  constructor(file) {
5
8
  const message = `No files found for path: '${file}'`;
6
9
  super(message);
@@ -1,12 +1,7 @@
1
- 'use strict';
2
-
3
1
  const { isReadableStream } = require('../stream');
4
2
 
5
3
  const ReadFile = class ReadFile {
6
- constructor({
7
- mimeType = '',
8
- etag = '',
9
- } = {}) {
4
+ constructor({ mimeType = '', etag = '' } = {}) {
10
5
  this._mimeType = mimeType;
11
6
  this._stream = undefined;
12
7
  this._etag = etag;
@@ -17,7 +12,8 @@ const ReadFile = class ReadFile {
17
12
  }
18
13
 
19
14
  set stream(value) {
20
- if (!isReadableStream(value)) throw new Error('Value is not a Readable stream');
15
+ if (!isReadableStream(value))
16
+ throw new Error('Value is not a Readable stream');
21
17
  this._stream = value;
22
18
  }
23
19
 
@@ -32,5 +28,5 @@ const ReadFile = class ReadFile {
32
28
  get [Symbol.toStringTag]() {
33
29
  return 'ReadFile';
34
30
  }
35
- }
31
+ };
36
32
  module.exports = ReadFile;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @type {(value: unknown, message?: string) => asserts value}
3
+ */
4
+ const assert = require('assert');
5
+ const { join } = require('path');
6
+
7
+ class RemoteFileLocation {
8
+ /**
9
+ * @param {string} filePathname pathname for file relative to package root eg. /folder/client.js
10
+ * @param {string} packagePathname pathname for package root eg. /pkg/my-pack/1.0.0
11
+ * @param {string} origin server origin eg. https://server.com
12
+ */
13
+ constructor(filePathname, packagePathname, origin) {
14
+ assert(
15
+ typeof filePathname === 'string',
16
+ '"filePathname" must be of type "string"',
17
+ );
18
+ assert(
19
+ typeof packagePathname === 'string',
20
+ '"packagePathname" must be of type "string"',
21
+ );
22
+ assert(typeof origin === 'string', '"origin" must be of type "string"');
23
+
24
+ /**
25
+ * @type {string} pathname to package root
26
+ */
27
+ this.packagePathname = new URL(packagePathname, origin).pathname;
28
+
29
+ /**
30
+ * @type {string} pathname to file relative to package root
31
+ */
32
+ this.filePathname = new URL(filePathname, origin).pathname;
33
+
34
+ /**
35
+ * @type {URL} WHATWG URL object containing the full remote URL for the file
36
+ */
37
+ this.url = new URL(join(packagePathname, filePathname), origin);
38
+ }
39
+ }
40
+
41
+ module.exports = RemoteFileLocation;