@eik/common 4.1.1 → 5.0.0

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 (42) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/lib/classes/custom-error.js +8 -8
  3. package/lib/classes/eik-config.js +148 -150
  4. package/lib/classes/file-mapping.js +25 -25
  5. package/lib/classes/invalid-config-error.js +7 -7
  6. package/lib/classes/local-file-location.js +45 -52
  7. package/lib/classes/missing-config-error.js +7 -7
  8. package/lib/classes/multiple-config-sources-error.js +6 -6
  9. package/lib/classes/no-files-matched-error.js +8 -8
  10. package/lib/classes/read-file.js +25 -25
  11. package/lib/classes/remote-file-location.js +30 -30
  12. package/lib/classes/resolved-files.js +38 -46
  13. package/lib/classes/single-dest-multiple-source-error.js +9 -9
  14. package/lib/helpers/config-store.js +103 -103
  15. package/lib/helpers/get-defaults.js +24 -24
  16. package/lib/helpers/index.js +21 -21
  17. package/lib/helpers/local-assets.js +49 -49
  18. package/lib/helpers/path-slashes.js +8 -10
  19. package/lib/helpers/resolve-files.js +60 -65
  20. package/lib/helpers/type-slug.js +3 -3
  21. package/lib/helpers/type-title.js +4 -4
  22. package/lib/index.js +12 -12
  23. package/lib/schemas/assert.js +41 -41
  24. package/lib/schemas/index.js +7 -7
  25. package/lib/schemas/validate.js +64 -64
  26. package/lib/schemas/validation-error.js +11 -11
  27. package/lib/stream.js +11 -11
  28. package/lib/validators/index.js +37 -37
  29. package/package.json +14 -13
  30. package/types/classes/eik-config.d.ts +1 -1
  31. package/types/classes/file-mapping.d.ts +2 -2
  32. package/types/classes/invalid-config-error.d.ts +1 -1
  33. package/types/classes/missing-config-error.d.ts +1 -1
  34. package/types/classes/multiple-config-sources-error.d.ts +1 -1
  35. package/types/classes/no-files-matched-error.d.ts +1 -1
  36. package/types/classes/resolved-files.d.ts +1 -1
  37. package/types/classes/single-dest-multiple-source-error.d.ts +1 -1
  38. package/types/helpers/config-store.d.ts +1 -1
  39. package/types/helpers/index.d.ts +10 -10
  40. package/types/helpers/resolve-files.d.ts +1 -1
  41. package/types/index.d.ts +6 -6
  42. package/types/schemas/index.d.ts +3 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # [5.0.0](https://github.com/eik-lib/common/compare/v4.1.1...v5.0.0) (2024-11-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * update validate-npm-package-name ([0dac235](https://github.com/eik-lib/common/commit/0dac23582de09bb739a730a8ca9bee7370146bcc))
7
+
8
+
9
+ ### BREAKING CHANGES
10
+
11
+ * Requires Node >=20.5.0
12
+
1
13
  ## [4.1.1](https://github.com/eik-lib/common/compare/v4.1.0...v4.1.1) (2024-08-16)
2
14
 
3
15
 
@@ -1,10 +1,10 @@
1
1
  export default class CustomError extends Error {
2
- /**
3
- * @param {string} message
4
- */
5
- constructor(message) {
6
- super(message);
7
- this.name = this.constructor.name;
8
- Error.captureStackTrace(this, this.constructor);
9
- }
2
+ /**
3
+ * @param {string} message
4
+ */
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = this.constructor.name;
8
+ Error.captureStackTrace(this, this.constructor);
9
+ }
10
10
  }
@@ -1,19 +1,19 @@
1
1
  /**
2
2
  * @type {(value: unknown, message?: string) => asserts value}
3
3
  */
4
- import assert from 'node:assert';
5
- import { extname, join, isAbsolute } from 'node:path';
6
- import NoFilesMatchedError from './no-files-matched-error.js';
7
- import SingleDestMultipleSourcesError from './single-dest-multiple-source-error.js';
8
- import FileMapping from './file-mapping.js';
9
- import RemoteFileLocation from './remote-file-location.js';
10
- import schemas from '../schemas/index.js';
11
- import { removeTrailingSlash, ensurePosix } from '../helpers/path-slashes.js';
12
- import typeSlug from '../helpers/type-slug.js';
13
- import resolveFiles from '../helpers/resolve-files.js';
14
-
15
- const _config = Symbol('config');
16
- const _tokens = Symbol('tokens');
4
+ import assert from "node:assert";
5
+ import { extname, join, isAbsolute } from "node:path";
6
+ import NoFilesMatchedError from "./no-files-matched-error.js";
7
+ import SingleDestMultipleSourcesError from "./single-dest-multiple-source-error.js";
8
+ import FileMapping from "./file-mapping.js";
9
+ import RemoteFileLocation from "./remote-file-location.js";
10
+ import schemas from "../schemas/index.js";
11
+ import { removeTrailingSlash, ensurePosix } from "../helpers/path-slashes.js";
12
+ import typeSlug from "../helpers/type-slug.js";
13
+ import resolveFiles from "../helpers/resolve-files.js";
14
+
15
+ const _config = Symbol("config");
16
+ const _tokens = Symbol("tokens");
17
17
 
18
18
  /**
19
19
  * Normalizes Eik JSON "files" definition to object form if in string form
@@ -23,147 +23,145 @@ const _tokens = Symbol('tokens');
23
23
  * @returns {{[k: string]: string;}}
24
24
  */
25
25
  const normalizeFilesDefinition = (files) =>
26
- typeof files === 'string' ? { '/': files } : files;
26
+ typeof files === "string" ? { "/": files } : files;
27
27
 
28
28
  /**
29
29
  * @typedef {import ("../../eikjson.js").EikjsonSchema} EikjsonSchema
30
30
  */
31
31
 
32
32
  export default class EikConfig {
33
- /**
34
- * @param {EikjsonSchema?} configHash
35
- * @param {[string, string][]?} tokens
36
- * @param {string?} configRootDir
37
- */
38
- constructor(configHash, tokens = null, configRootDir = process.cwd()) {
39
- /** @type EikjsonSchema */
40
- this[_config] = JSON.parse(JSON.stringify(configHash)) || {};
41
- this[_tokens] = new Map(tokens);
42
-
43
- assert(
44
- // @ts-ignore
45
- isAbsolute(configRootDir),
46
- `"configRootDir" must be an absolute path: "${configRootDir}" given`,
47
- );
48
- // @ts-ignore
49
- this.cwd = removeTrailingSlash(configRootDir);
50
- /** @type {string[]} */
51
- // @ts-ignore
52
- this.map = [].concat(this[_config]['import-map'] || []);
53
- }
54
-
55
- /** @type {EikjsonSchema["name"]} */
56
- get name() {
57
- return this[_config].name;
58
- }
59
-
60
- /** @type {EikjsonSchema["version"]} */
61
- get version() {
62
- return this[_config].version;
63
- }
64
-
65
- set version(newVersion) {
66
- schemas.assert.version(newVersion);
67
- this[_config].version = newVersion;
68
- }
69
-
70
- /** @type {EikjsonSchema["type"]} */
71
- get type() {
72
- // @ts-ignore
73
- return this[_config].type || schemas.schema.properties.type.default;
74
- }
75
-
76
- /** @type {string} */
77
- get server() {
78
- const configuredServer = this[_config].server;
79
- if (configuredServer) {
80
- return configuredServer;
81
- }
82
- return this[_tokens].keys().next().value;
83
- }
84
-
85
- /** @type {[string, string][]} */
86
- get token() {
87
- // @ts-ignore
88
- return this[_tokens].get(this.server);
89
- }
90
-
91
- /** @type {EikjsonSchema["files"]} */
92
- get files() {
93
- return this[_config].files;
94
- }
95
-
96
- /**
97
- * Normalized relative directory path with any leading ./ or
98
- * trailing / characters stripped. Defaults to .eik
99
- *
100
- * @returns {string} out path string
101
- */
102
- get out() {
103
- const defaulted = this[_config].out || '.eik';
104
- const out = defaulted.startsWith('./')
105
- ? defaulted.substr(2)
106
- : defaulted;
107
- return removeTrailingSlash(out);
108
- }
109
-
110
- /**
111
- * Serializes internal values to an object
112
- *
113
- * @returns {EikjsonSchema} object consistent with EikjsonSchema
114
- */
115
- toJSON() {
116
- return { ...this[_config] };
117
- }
118
-
119
- /**
120
- * Validates config values against the eik JSON schema
121
- *
122
- * @return {void}
123
- */
124
- validate() {
125
- schemas.assert.eikJSON(this[_config]);
126
- }
127
-
128
- /**
129
- * Resolves file locations on disk based on values defined in files property
130
- * of config object.
131
- *
132
- * @returns {Promise<FileMapping[]>}
133
- */
134
- async mappings() {
135
- const normalizedFiles = normalizeFilesDefinition(this.files);
136
- const resolvedFiles = await resolveFiles(normalizedFiles, this.cwd);
137
-
138
- return resolvedFiles.flatMap((files) => {
139
- // @ts-ignore
140
- const { destination, source } = files;
141
- // @ts-ignore
142
- const filesArray = Array.from(files);
143
- if (filesArray.length === 0) {
144
- throw new NoFilesMatchedError(source);
145
- }
146
-
147
- if (extname(destination) !== '' && filesArray.length > 1) {
148
- throw new SingleDestMultipleSourcesError(destination);
149
- }
150
-
151
- return filesArray.map((localFile) => {
152
- const shouldMapFilename = extname(destination);
153
- const relativePathname = shouldMapFilename
154
- ? destination
155
- : ensurePosix(join(destination, localFile.relative));
156
- const packagePathname = ensurePosix(
157
- join(typeSlug(this.type), this.name, this.version),
158
- );
159
-
160
- const remoteDestination = new RemoteFileLocation(
161
- relativePathname,
162
- packagePathname,
163
- this.server,
164
- );
165
- return new FileMapping(localFile, remoteDestination);
166
- });
167
- });
168
- }
33
+ /**
34
+ * @param {EikjsonSchema?} configHash
35
+ * @param {[string, string][]?} tokens
36
+ * @param {string?} configRootDir
37
+ */
38
+ constructor(configHash, tokens = null, configRootDir = process.cwd()) {
39
+ /** @type EikjsonSchema */
40
+ this[_config] = JSON.parse(JSON.stringify(configHash)) || {};
41
+ this[_tokens] = new Map(tokens);
42
+
43
+ assert(
44
+ // @ts-ignore
45
+ isAbsolute(configRootDir),
46
+ `"configRootDir" must be an absolute path: "${configRootDir}" given`,
47
+ );
48
+ // @ts-ignore
49
+ this.cwd = removeTrailingSlash(configRootDir);
50
+ /** @type {string[]} */
51
+ // @ts-ignore
52
+ this.map = [].concat(this[_config]["import-map"] || []);
53
+ }
54
+
55
+ /** @type {EikjsonSchema["name"]} */
56
+ get name() {
57
+ return this[_config].name;
58
+ }
59
+
60
+ /** @type {EikjsonSchema["version"]} */
61
+ get version() {
62
+ return this[_config].version;
63
+ }
64
+
65
+ set version(newVersion) {
66
+ schemas.assert.version(newVersion);
67
+ this[_config].version = newVersion;
68
+ }
69
+
70
+ /** @type {EikjsonSchema["type"]} */
71
+ get type() {
72
+ // @ts-ignore
73
+ return this[_config].type || schemas.schema.properties.type.default;
74
+ }
75
+
76
+ /** @type {string} */
77
+ get server() {
78
+ const configuredServer = this[_config].server;
79
+ if (configuredServer) {
80
+ return configuredServer;
81
+ }
82
+ return this[_tokens].keys().next().value;
83
+ }
84
+
85
+ /** @type {[string, string][]} */
86
+ get token() {
87
+ // @ts-ignore
88
+ return this[_tokens].get(this.server);
89
+ }
90
+
91
+ /** @type {EikjsonSchema["files"]} */
92
+ get files() {
93
+ return this[_config].files;
94
+ }
95
+
96
+ /**
97
+ * Normalized relative directory path with any leading ./ or
98
+ * trailing / characters stripped. Defaults to .eik
99
+ *
100
+ * @returns {string} out path string
101
+ */
102
+ get out() {
103
+ const defaulted = this[_config].out || ".eik";
104
+ const out = defaulted.startsWith("./") ? defaulted.substr(2) : defaulted;
105
+ return removeTrailingSlash(out);
106
+ }
107
+
108
+ /**
109
+ * Serializes internal values to an object
110
+ *
111
+ * @returns {EikjsonSchema} object consistent with EikjsonSchema
112
+ */
113
+ toJSON() {
114
+ return { ...this[_config] };
115
+ }
116
+
117
+ /**
118
+ * Validates config values against the eik JSON schema
119
+ *
120
+ * @return {void}
121
+ */
122
+ validate() {
123
+ schemas.assert.eikJSON(this[_config]);
124
+ }
125
+
126
+ /**
127
+ * Resolves file locations on disk based on values defined in files property
128
+ * of config object.
129
+ *
130
+ * @returns {Promise<FileMapping[]>}
131
+ */
132
+ async mappings() {
133
+ const normalizedFiles = normalizeFilesDefinition(this.files);
134
+ const resolvedFiles = await resolveFiles(normalizedFiles, this.cwd);
135
+
136
+ return resolvedFiles.flatMap((files) => {
137
+ // @ts-ignore
138
+ const { destination, source } = files;
139
+ // @ts-ignore
140
+ const filesArray = Array.from(files);
141
+ if (filesArray.length === 0) {
142
+ throw new NoFilesMatchedError(source);
143
+ }
144
+
145
+ if (extname(destination) !== "" && filesArray.length > 1) {
146
+ throw new SingleDestMultipleSourcesError(destination);
147
+ }
148
+
149
+ return filesArray.map((localFile) => {
150
+ const shouldMapFilename = extname(destination);
151
+ const relativePathname = shouldMapFilename
152
+ ? destination
153
+ : ensurePosix(join(destination, localFile.relative));
154
+ const packagePathname = ensurePosix(
155
+ join(typeSlug(this.type), this.name, this.version),
156
+ );
157
+
158
+ const remoteDestination = new RemoteFileLocation(
159
+ relativePathname,
160
+ packagePathname,
161
+ this.server,
162
+ );
163
+ return new FileMapping(localFile, remoteDestination);
164
+ });
165
+ });
166
+ }
169
167
  }
@@ -1,38 +1,38 @@
1
1
  /**
2
2
  * @type {(value: unknown, message?: string) => asserts value}
3
3
  */
4
- import assert from 'node:assert';
5
- import LocalFileLocation from './local-file-location.js';
6
- import RemoteFileLocation from './remote-file-location.js';
4
+ import assert from "node:assert";
5
+ import LocalFileLocation from "./local-file-location.js";
6
+ import RemoteFileLocation from "./remote-file-location.js";
7
7
 
8
8
  /**
9
9
  * Class containing a local file system source location and remote server destination location for a file.
10
10
  */
11
11
  class FileMapping {
12
- /**
13
- * @param {LocalFileLocation} source
14
- * @param {RemoteFileLocation} destination
15
- */
16
- constructor(source, destination) {
17
- assert(
18
- source instanceof LocalFileLocation,
19
- '"source" must be an instance of LocalFileLocation',
20
- );
21
- assert(
22
- destination instanceof RemoteFileLocation,
23
- '"destination" must be an instance of RemoteFileLocation',
24
- );
12
+ /**
13
+ * @param {LocalFileLocation} source
14
+ * @param {RemoteFileLocation} destination
15
+ */
16
+ constructor(source, destination) {
17
+ assert(
18
+ source instanceof LocalFileLocation,
19
+ '"source" must be an instance of LocalFileLocation',
20
+ );
21
+ assert(
22
+ destination instanceof RemoteFileLocation,
23
+ '"destination" must be an instance of RemoteFileLocation',
24
+ );
25
25
 
26
- /**
27
- * @type {LocalFileLocation} source
28
- */
29
- this.source = source;
26
+ /**
27
+ * @type {LocalFileLocation} source
28
+ */
29
+ this.source = source;
30
30
 
31
- /**
32
- * @type {RemoteFileLocation} destination
33
- */
34
- this.destination = destination;
35
- }
31
+ /**
32
+ * @type {RemoteFileLocation} destination
33
+ */
34
+ this.destination = destination;
35
+ }
36
36
  }
37
37
 
38
38
  export default FileMapping;
@@ -1,10 +1,10 @@
1
- import CustomError from './custom-error.js';
1
+ import CustomError from "./custom-error.js";
2
2
 
3
3
  export default class InvalidConfigError extends CustomError {
4
- /**
5
- * @param {string} msg
6
- */
7
- constructor(msg) {
8
- super(`Eik config object was invalid: '${msg}'`);
9
- }
4
+ /**
5
+ * @param {string} msg
6
+ */
7
+ constructor(msg) {
8
+ super(`Eik config object was invalid: '${msg}'`);
9
+ }
10
10
  }
@@ -1,64 +1,57 @@
1
1
  /**
2
2
  * @type {(value: unknown, message?: string) => asserts value}
3
3
  */
4
- import assert from 'node:assert';
5
- import { join, extname, isAbsolute } from 'node:path';
4
+ import assert from "node:assert";
5
+ import { join, extname, isAbsolute } from "node:path";
6
6
  // @ts-ignore
7
- import mime from 'mime-types';
8
- import { ensurePosix } from '../helpers/path-slashes.js';
7
+ import mime from "mime-types";
8
+ import { ensurePosix } from "../helpers/path-slashes.js";
9
9
 
10
10
  /**
11
11
  * Class containing information about a local file
12
12
  */
13
13
  class LocalFileLocation {
14
- /**
15
- * @param {string} path path to file on disk relative to basePath
16
- * @param {string} basePath basePath to the file's location on disk
17
- */
18
- constructor(path, basePath) {
19
- assert(typeof path === 'string', '"path" must be of type "string"');
20
- assert(
21
- typeof basePath === 'string',
22
- '"basePath" must be of type "string"',
23
- );
24
- assert(
25
- !isAbsolute(path),
26
- `"path" must be a relative path, got ${path}`,
27
- );
28
-
29
- /**
30
- * @type {string} path to file on disk relative to this.basePath
31
- */
32
- this.relative = path;
33
-
34
- /**
35
- * @type {string} absolute path to root files location on disk
36
- */
37
- this.basePath = basePath;
38
-
39
- /**
40
- * @type {string} absolute path to file on disk,
41
- * this is a concatentation of this.basePath and this.relative
42
- */
43
- this.absolute = ensurePosix(join(basePath, path));
44
-
45
- /**
46
- * @type {string} file extension with "." character included. (eg. ".json")
47
- */
48
- this.extension = extname(path);
49
-
50
- /**
51
- * @type {string} full content-type header value for file
52
- */
53
- this.contentType =
54
- mime.contentType(this.extension) || 'application/octet-stream';
55
-
56
- /**
57
- * @type {string} mime type of file
58
- */
59
- this.mimeType =
60
- mime.lookup(this.extension) || 'application/octet-stream';
61
- }
14
+ /**
15
+ * @param {string} path path to file on disk relative to basePath
16
+ * @param {string} basePath basePath to the file's location on disk
17
+ */
18
+ constructor(path, basePath) {
19
+ assert(typeof path === "string", '"path" must be of type "string"');
20
+ assert(typeof basePath === "string", '"basePath" must be of type "string"');
21
+ assert(!isAbsolute(path), `"path" must be a relative path, got ${path}`);
22
+
23
+ /**
24
+ * @type {string} path to file on disk relative to this.basePath
25
+ */
26
+ this.relative = path;
27
+
28
+ /**
29
+ * @type {string} absolute path to root files location on disk
30
+ */
31
+ this.basePath = basePath;
32
+
33
+ /**
34
+ * @type {string} absolute path to file on disk,
35
+ * this is a concatentation of this.basePath and this.relative
36
+ */
37
+ this.absolute = ensurePosix(join(basePath, path));
38
+
39
+ /**
40
+ * @type {string} file extension with "." character included. (eg. ".json")
41
+ */
42
+ this.extension = extname(path);
43
+
44
+ /**
45
+ * @type {string} full content-type header value for file
46
+ */
47
+ this.contentType =
48
+ mime.contentType(this.extension) || "application/octet-stream";
49
+
50
+ /**
51
+ * @type {string} mime type of file
52
+ */
53
+ this.mimeType = mime.lookup(this.extension) || "application/octet-stream";
54
+ }
62
55
  }
63
56
 
64
57
  export default LocalFileLocation;
@@ -1,10 +1,10 @@
1
- import CustomError from './custom-error.js';
1
+ import CustomError from "./custom-error.js";
2
2
 
3
3
  export default class MissingConfigError extends CustomError {
4
- /**
5
- * @param {string} dir
6
- */
7
- constructor(dir) {
8
- super(`No package.json or eik.json file found in: '${dir}'`);
9
- }
4
+ /**
5
+ * @param {string} dir
6
+ */
7
+ constructor(dir) {
8
+ super(`No package.json or eik.json file found in: '${dir}'`);
9
+ }
10
10
  }
@@ -1,9 +1,9 @@
1
- import CustomError from './custom-error.js';
1
+ import CustomError from "./custom-error.js";
2
2
 
3
3
  export default class MultipleConfigSourcesError extends CustomError {
4
- constructor() {
5
- super(
6
- `Eik configuration was defined in both in package.json and eik.json. You must specify one or the other.`,
7
- );
8
- }
4
+ constructor() {
5
+ super(
6
+ `Eik configuration was defined in both in package.json and eik.json. You must specify one or the other.`,
7
+ );
8
+ }
9
9
  }
@@ -1,11 +1,11 @@
1
- import CustomError from './custom-error.js';
1
+ import CustomError from "./custom-error.js";
2
2
 
3
3
  export default class NoFilesMatchedError extends CustomError {
4
- /**
5
- * @param {string} file
6
- */
7
- constructor(file) {
8
- const message = `No files found for path: '${file}'`;
9
- super(message);
10
- }
4
+ /**
5
+ * @param {string} file
6
+ */
7
+ constructor(file) {
8
+ const message = `No files found for path: '${file}'`;
9
+ super(message);
10
+ }
11
11
  }