@eik/node-client 2.0.0-next.4 → 2.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.
- package/CHANGELOG.md +243 -26
- package/README.md +194 -104
- package/dist/index.cjs +377 -0
- package/package.json +36 -22
- package/src/asset.js +49 -7
- package/src/index.js +319 -102
- package/types/asset.d.ts +47 -0
- package/types/index.d.ts +218 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('@eik/common');
|
|
4
|
+
var undici = require('undici');
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {object} AssetOptions
|
|
9
|
+
* @property {string} [value=""]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Holds attributes for use when linking to assets hosted on Eik.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```
|
|
17
|
+
* // JS and <script>
|
|
18
|
+
* const script = eik.file("/app.js");
|
|
19
|
+
* const html = `<script
|
|
20
|
+
* src="${script.value}"
|
|
21
|
+
* ${script.integrity ? `integrity="${script.integrity}"` : ""}
|
|
22
|
+
* type="module"></script>`;
|
|
23
|
+
* ```
|
|
24
|
+
* @example
|
|
25
|
+
* ```
|
|
26
|
+
* // CSS and <link>
|
|
27
|
+
* const styles = eik.file("/styles.css");
|
|
28
|
+
* const html = `<link
|
|
29
|
+
* href="${styles.value}"
|
|
30
|
+
* ${styles.integrity ? `integrity="${styles.integrity}"` : ""}
|
|
31
|
+
* rel="stylesheet" />`;
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
class Asset {
|
|
35
|
+
/**
|
|
36
|
+
* Value for use in [subresource integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#examples).
|
|
37
|
+
* Not calculated if `development` is `true`.
|
|
38
|
+
*
|
|
39
|
+
* @type {string | undefined}
|
|
40
|
+
*/
|
|
41
|
+
integrity = undefined;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* URL to the file for use in `<script>` or `<link>`.
|
|
45
|
+
* @type {string}
|
|
46
|
+
*/
|
|
47
|
+
value;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {AssetOptions} options
|
|
51
|
+
*/
|
|
52
|
+
constructor({ value = "" } = {}) {
|
|
53
|
+
this.integrity = undefined;
|
|
54
|
+
this.value = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const trimSlash = (value = "") => {
|
|
59
|
+
if (value.endsWith("/")) return value.substring(0, value.length - 1);
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const fetchImportMaps = async (urls = []) => {
|
|
64
|
+
try {
|
|
65
|
+
const maps = urls.map(async (map) => {
|
|
66
|
+
const { statusCode, body } = await undici.request(map, {
|
|
67
|
+
maxRedirections: 2,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (statusCode === 404) {
|
|
71
|
+
throw new Error("Import map could not be found on server");
|
|
72
|
+
} else if (statusCode >= 400 && statusCode < 500) {
|
|
73
|
+
throw new Error("Server rejected client request");
|
|
74
|
+
} else if (statusCode >= 500) {
|
|
75
|
+
throw new Error("Server error");
|
|
76
|
+
}
|
|
77
|
+
return body.json();
|
|
78
|
+
});
|
|
79
|
+
return await Promise.all(maps);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Unable to load import map file from server: ${err.message}`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @typedef {object} Options
|
|
89
|
+
* @property {string} [base=null]
|
|
90
|
+
* @property {boolean} [development=false]
|
|
91
|
+
* @property {boolean} [loadMaps=false]
|
|
92
|
+
* @property {string} [path=process.cwd()]
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @typedef {object} ImportMap
|
|
97
|
+
* @property {Record<string, string>} imports
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* An Eik utility for servers running on Node. With it you can:
|
|
102
|
+
* - generate different URLs to assets on an Eik server depending on environment (development vs production).
|
|
103
|
+
* - get the import maps you have configured in `eik.json` from the Eik server, should you want to use them in the HTML response.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```js
|
|
107
|
+
* // Create an instance, then load information from `eik.json` and the Eik server
|
|
108
|
+
* import Eik from "@eik/node-client";
|
|
109
|
+
*
|
|
110
|
+
* const eik = new Eik();
|
|
111
|
+
* await eik.load();
|
|
112
|
+
* ```
|
|
113
|
+
* @example
|
|
114
|
+
* ```js
|
|
115
|
+
* // Serve a local version of a file from `./public`
|
|
116
|
+
* // in development and from Eik in production
|
|
117
|
+
* import path from "node:path";
|
|
118
|
+
* import Eik from "@eik/node-client";
|
|
119
|
+
* import fastifyStatic from "@fastify/static";
|
|
120
|
+
* import fastify from "fastify";
|
|
121
|
+
*
|
|
122
|
+
* const app = fastify();
|
|
123
|
+
* app.register(fastifyStatic, {
|
|
124
|
+
* root: path.join(process.cwd(), "public"),
|
|
125
|
+
* prefix: "/public/",
|
|
126
|
+
* });
|
|
127
|
+
*
|
|
128
|
+
* const eik = new Eik({
|
|
129
|
+
* development: process.env.NODE_ENV === "development",
|
|
130
|
+
* base: "/public",
|
|
131
|
+
* });
|
|
132
|
+
*
|
|
133
|
+
* // load information from `eik.json` and the Eik server
|
|
134
|
+
* await eik.load();
|
|
135
|
+
*
|
|
136
|
+
* // when development is true script.value will be /public/script.js.
|
|
137
|
+
* // when development is false script.value will be
|
|
138
|
+
* // https://{server}/pkg/{name}/{version}/script.js
|
|
139
|
+
* // where {server}, {name} and {version} are read from eik.json
|
|
140
|
+
* const script = eik.file("/script.js");
|
|
141
|
+
*
|
|
142
|
+
* app.get("/", (req, reply) => {
|
|
143
|
+
* reply.type("text/html; charset=utf-8");
|
|
144
|
+
* reply.send(`<html><body>
|
|
145
|
+
* <script
|
|
146
|
+
* src="${script.value}"
|
|
147
|
+
* ${script.integrity ? `integrity="${script.integrity}"` : ""}
|
|
148
|
+
* type="module"></script>
|
|
149
|
+
* </body></html>`);
|
|
150
|
+
* });
|
|
151
|
+
*
|
|
152
|
+
* app.listen({
|
|
153
|
+
* port: 3000,
|
|
154
|
+
* });
|
|
155
|
+
*
|
|
156
|
+
* console.log("Listening on http://localhost:3000");
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
class Eik {
|
|
160
|
+
#development;
|
|
161
|
+
#loadMaps;
|
|
162
|
+
#config;
|
|
163
|
+
#path;
|
|
164
|
+
#base;
|
|
165
|
+
#maps;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {Options} options
|
|
169
|
+
*/
|
|
170
|
+
constructor({
|
|
171
|
+
development = false,
|
|
172
|
+
loadMaps = false,
|
|
173
|
+
base = "",
|
|
174
|
+
path = process.cwd(),
|
|
175
|
+
} = {}) {
|
|
176
|
+
this.#development = development;
|
|
177
|
+
this.#loadMaps = loadMaps;
|
|
178
|
+
this.#config = {};
|
|
179
|
+
this.#path = path;
|
|
180
|
+
this.#base = trimSlash(base);
|
|
181
|
+
this.#maps = [];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Reads the Eik config from disk into the object instance, used for building {@link file} links in production.
|
|
186
|
+
*
|
|
187
|
+
* If {@link Options.loadMaps} is `true` the import maps
|
|
188
|
+
* defined in the Eik config will be fetched from the Eik server for
|
|
189
|
+
* use in {@link maps}.
|
|
190
|
+
*/
|
|
191
|
+
async load() {
|
|
192
|
+
this.#config = await common.helpers.getDefaults(this.#path);
|
|
193
|
+
if (this.#loadMaps) {
|
|
194
|
+
this.#maps = await fetchImportMaps(this.#config.map);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The `"name"` field from the Eik config
|
|
200
|
+
* @throws if read before calling {@link load}
|
|
201
|
+
*/
|
|
202
|
+
get name() {
|
|
203
|
+
if (this.#config.name) return this.#config.name;
|
|
204
|
+
throw new Error("Eik config was not loaded before calling .name");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The `"version"` field from the Eik config
|
|
209
|
+
* @throws if read before calling {@link load}
|
|
210
|
+
*/
|
|
211
|
+
get version() {
|
|
212
|
+
if (this.#config.version) return this.#config.version;
|
|
213
|
+
throw new Error("Eik config was not loaded before calling .version");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* The `"type"` field from the Eik config mapped to its URL equivalent (eg. "package" is "pkg").
|
|
218
|
+
* @throws if read before calling {@link load}
|
|
219
|
+
*/
|
|
220
|
+
get type() {
|
|
221
|
+
if (this.#config.type && this.#config.type === "package") return "pkg";
|
|
222
|
+
if (this.#config.type) return this.#config.type;
|
|
223
|
+
throw new Error("Eik config was not loaded before calling .type");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The `"server"` field from the Eik config
|
|
228
|
+
* @throws if read before calling {@link load}
|
|
229
|
+
*/
|
|
230
|
+
get server() {
|
|
231
|
+
if (this.#config.server) return this.#config.server;
|
|
232
|
+
throw new Error("Eik config was not loaded before calling .server");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The pathname to the base on Eik (ex. /pkg/my-app/1.0.0/)
|
|
237
|
+
* @throws if read before calling {@link load}
|
|
238
|
+
*/
|
|
239
|
+
get pathname() {
|
|
240
|
+
if (this.#config.type && this.#config.name && this.#config.version)
|
|
241
|
+
return path.join(
|
|
242
|
+
"/",
|
|
243
|
+
common.helpers.typeSlug(this.type),
|
|
244
|
+
this.name,
|
|
245
|
+
this.version,
|
|
246
|
+
).replace(/\\/g, "/");
|
|
247
|
+
throw new Error("Eik config was not loaded before calling .pathname");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Similar to {@link file}, this method returns a path to the base on Eik
|
|
252
|
+
* (ex. https://eik.store.com/pkg/my-app/1.0.0), or {@link Options.base}
|
|
253
|
+
* if {@link Options.development} is true.
|
|
254
|
+
*
|
|
255
|
+
* You can use this instead of `file` if you have a directory full of files
|
|
256
|
+
* and you don't need {@link Asset.integrity}.
|
|
257
|
+
*
|
|
258
|
+
* @returns {string} The base path for assets published on Eik
|
|
259
|
+
* @throws when {@link Options.development} is false if called before calling {@link load}
|
|
260
|
+
*/
|
|
261
|
+
base() {
|
|
262
|
+
if (this.#development) return this.#base;
|
|
263
|
+
return `${this.server}${this.pathname}`;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Get a link to a file that is published on Eik when running in production.
|
|
268
|
+
* When {@link Options.development} is `true` the pathname is prefixed
|
|
269
|
+
* with the {@link Options.base} option instead of pointing to Eik.
|
|
270
|
+
*
|
|
271
|
+
* @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)
|
|
272
|
+
* @returns {import('./asset.js').Asset}
|
|
273
|
+
* @throws when {@link Options.development} is false if called before calling {@link load}
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```js
|
|
277
|
+
* // in production
|
|
278
|
+
* const eik = new Eik({
|
|
279
|
+
* development: false,
|
|
280
|
+
* });
|
|
281
|
+
* await eik.load();
|
|
282
|
+
*
|
|
283
|
+
* const file = eik.file("/path/to/script.js");
|
|
284
|
+
* // {
|
|
285
|
+
* // value: https://eik.store.com/pkg/my-app/1.0.0/path/to/script.js
|
|
286
|
+
* // integrity: sha512-zHQjnD-etc.
|
|
287
|
+
* // }
|
|
288
|
+
* // where the server URL, app name and version are read from eik.json
|
|
289
|
+
* // {
|
|
290
|
+
* // "name": "my-app",
|
|
291
|
+
* // "version": "1.0.0",
|
|
292
|
+
* // "server": "https://eik.store.com",
|
|
293
|
+
* // }
|
|
294
|
+
* ```
|
|
295
|
+
* @example
|
|
296
|
+
* ```js
|
|
297
|
+
* // in development
|
|
298
|
+
* const eik = new Eik({
|
|
299
|
+
* development: true,
|
|
300
|
+
* base: "/public",
|
|
301
|
+
* });
|
|
302
|
+
* await eik.load();
|
|
303
|
+
*
|
|
304
|
+
* const file = eik.file("/path/to/script.js");
|
|
305
|
+
* // {
|
|
306
|
+
* // value: /public/path/to/script.js
|
|
307
|
+
* // integrity: undefined
|
|
308
|
+
* // }
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
file(pathname = "") {
|
|
312
|
+
const base = this.base();
|
|
313
|
+
return new Asset({
|
|
314
|
+
value: `${base}${pathname}`,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* When {@link Options.loadMaps} is `true` and you call {@link load}, the client
|
|
320
|
+
* fetches the configured import maps from the Eik server.
|
|
321
|
+
*
|
|
322
|
+
* This method returns the import maps that were fetched during `load`.
|
|
323
|
+
*
|
|
324
|
+
* @returns {ImportMap[]}
|
|
325
|
+
* @throws if {@link Options.loadMaps} is not `true` or called before calling {@link load}
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```js
|
|
329
|
+
* const client = new Eik({
|
|
330
|
+
* loadMaps: true,
|
|
331
|
+
* });
|
|
332
|
+
* await client.load();
|
|
333
|
+
*
|
|
334
|
+
* const maps = client.maps();
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
maps() {
|
|
338
|
+
if (this.#config.version && this.#loadMaps) return this.#maps;
|
|
339
|
+
throw new Error(
|
|
340
|
+
'Eik config was not loaded or "loadMaps" is "false" when calling .maps()',
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Function that generates and returns an import map script tag for use in an document head.
|
|
346
|
+
*
|
|
347
|
+
* Only a single import map is allowed per HTML document.
|
|
348
|
+
* A key (ex. `react`) can only be defined once.
|
|
349
|
+
* If multiple import maps defined in `eik.json` use the same key, the last key wins.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```
|
|
353
|
+
* const importMap = eik.toHTML();
|
|
354
|
+
*
|
|
355
|
+
* <head>
|
|
356
|
+
* ...
|
|
357
|
+
* ${importMap}
|
|
358
|
+
* ...
|
|
359
|
+
* </head>
|
|
360
|
+
* ```
|
|
361
|
+
*
|
|
362
|
+
* @returns {string}
|
|
363
|
+
*/
|
|
364
|
+
toHTML() {
|
|
365
|
+
const allImportMapKeyValuePairs = this.maps().flatMap((map) =>
|
|
366
|
+
Object.entries(map.imports),
|
|
367
|
+
);
|
|
368
|
+
const mergedAndDedupedImportMapObject = Object.fromEntries(
|
|
369
|
+
new Map(allImportMapKeyValuePairs).entries(),
|
|
370
|
+
);
|
|
371
|
+
return `<script type="importmap">${JSON.stringify({
|
|
372
|
+
imports: mergedAndDedupedImportMapObject,
|
|
373
|
+
})}</script>`;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
module.exports = Eik;
|
package/package.json
CHANGED
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eik/node-client",
|
|
3
|
-
"version": "2.0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Utilities for working with assets and import maps on an Eik server",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"types": "./types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"types": "./types/index.d.ts",
|
|
10
|
+
"import": "./src/index.js",
|
|
11
|
+
"require": "./dist/index.cjs"
|
|
12
|
+
},
|
|
7
13
|
"files": [
|
|
8
14
|
"CHANGELOG.md",
|
|
9
15
|
"package.json",
|
|
10
16
|
"LICENSE",
|
|
11
|
-
"
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"types"
|
|
12
20
|
],
|
|
13
21
|
"scripts": {
|
|
14
|
-
"
|
|
22
|
+
"build": "rollup -c",
|
|
23
|
+
"clean": "rimraf .tap dist node_modules types",
|
|
24
|
+
"lint": "eslint .",
|
|
15
25
|
"lint:fix": "eslint --fix .",
|
|
16
|
-
"
|
|
26
|
+
"test": "tap --disable-coverage --allow-empty-coverage",
|
|
27
|
+
"types": "run-s types:module types:test",
|
|
28
|
+
"types:module": "tsc",
|
|
29
|
+
"types:test": "tsc --project tsconfig.test.json",
|
|
30
|
+
"prepare": "npm run -s build"
|
|
17
31
|
},
|
|
18
32
|
"repository": {
|
|
19
33
|
"type": "git",
|
|
20
34
|
"url": "git@github.com:eik-lib/node-client.git"
|
|
21
35
|
},
|
|
22
36
|
"keywords": [
|
|
23
|
-
"eik"
|
|
24
|
-
"esm"
|
|
37
|
+
"eik"
|
|
25
38
|
],
|
|
26
39
|
"author": "Finn.no",
|
|
27
40
|
"license": "MIT",
|
|
@@ -30,21 +43,22 @@
|
|
|
30
43
|
},
|
|
31
44
|
"homepage": "https://github.com/eik-lib/node-client#readme",
|
|
32
45
|
"dependencies": {
|
|
33
|
-
"@eik/common
|
|
34
|
-
"abslog": "2.4.
|
|
35
|
-
"undici": "
|
|
46
|
+
"@eik/common": "5.0.0",
|
|
47
|
+
"abslog": "2.4.4",
|
|
48
|
+
"undici": "6.21.0"
|
|
36
49
|
},
|
|
37
50
|
"devDependencies": {
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"eslint
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
51
|
+
"@eik/eslint-config": "1.0.5",
|
|
52
|
+
"@eik/prettier-config": "1.0.1",
|
|
53
|
+
"@eik/semantic-release-config": "1.0.0",
|
|
54
|
+
"@eik/typescript-config": "1.0.0",
|
|
55
|
+
"eslint": "9.14.0",
|
|
56
|
+
"npm-run-all2": "7.0.1",
|
|
57
|
+
"prettier": "3.3.3",
|
|
58
|
+
"rimraf": "6.0.1",
|
|
59
|
+
"rollup": "4.27.0",
|
|
60
|
+
"semantic-release": "24.2.0",
|
|
61
|
+
"tap": "21.0.1",
|
|
62
|
+
"typescript": "5.6.3"
|
|
49
63
|
}
|
|
50
64
|
}
|
package/src/asset.js
CHANGED
|
@@ -1,8 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} AssetOptions
|
|
3
|
+
* @property {string} [value=""]
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Holds attributes for use when linking to assets hosted on Eik.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```
|
|
11
|
+
* // JS and <script>
|
|
12
|
+
* const script = eik.file("/app.js");
|
|
13
|
+
* const html = `<script
|
|
14
|
+
* src="${script.value}"
|
|
15
|
+
* ${script.integrity ? `integrity="${script.integrity}"` : ""}
|
|
16
|
+
* type="module"></script>`;
|
|
17
|
+
* ```
|
|
18
|
+
* @example
|
|
19
|
+
* ```
|
|
20
|
+
* // CSS and <link>
|
|
21
|
+
* const styles = eik.file("/styles.css");
|
|
22
|
+
* const html = `<link
|
|
23
|
+
* href="${styles.value}"
|
|
24
|
+
* ${styles.integrity ? `integrity="${styles.integrity}"` : ""}
|
|
25
|
+
* rel="stylesheet" />`;
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class Asset {
|
|
29
|
+
/**
|
|
30
|
+
* Value for use in [subresource integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#examples).
|
|
31
|
+
* Not calculated if `development` is `true`.
|
|
32
|
+
*
|
|
33
|
+
* @type {string | undefined}
|
|
34
|
+
*/
|
|
35
|
+
integrity = undefined;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* URL to the file for use in `<script>` or `<link>`.
|
|
39
|
+
* @type {string}
|
|
40
|
+
*/
|
|
41
|
+
value;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {AssetOptions} options
|
|
45
|
+
*/
|
|
46
|
+
constructor({ value = "" } = {}) {
|
|
47
|
+
this.integrity = undefined;
|
|
48
|
+
this.value = value;
|
|
49
|
+
}
|
|
8
50
|
}
|