nuxt-content-assets 1.4.2 → 1.4.4

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/README.md CHANGED
@@ -155,11 +155,16 @@ If you delete an asset, it will be greyed out in the browser until you replace t
155
155
 
156
156
  If you edit an image, video, embed or iframe source, the content will update immediately, which is useful if you're looking to get that design just right!
157
157
 
158
+ > [!NOTE]
159
+ > Live reload does not currently work with Nuxt Image (see Issue [#77](https://github.com/davestewart/nuxt-content-assets/issues/77)).
160
+ >
161
+ > If you need to iterate on image design, consider disabling Nuxt Image in development.
162
+
158
163
  ### Image sizing
159
164
 
160
165
  #### HTML
161
166
 
162
- The module is [preconfigured](#image-size) to pass image size hints (by default `style`) to generated `<img>` tags:
167
+ The module can pass image size hints to generated `<img>` tags:
163
168
 
164
169
  ```html
165
170
  <!-- imageSize: 'style' -->
@@ -169,7 +174,10 @@ The module is [preconfigured](#image-size) to pass image size hints (by default
169
174
  <img src="/image.jpg" width="640" height="480">
170
175
  ```
171
176
 
172
- Keeping this on prevents content jumps as your page loads.
177
+ Turning this on prevents content jumps as your page loads.
178
+
179
+ > [!CAUTION]
180
+ > Don't use `imageSize: 'src'` in conjunction with Nuxt Image as it prevents the IPX module from correctly serving images, which causes static site generation to fail
173
181
 
174
182
  #### Prose components
175
183
 
@@ -207,27 +215,17 @@ See playground component [here](playground/components/content/ContentImage.vue).
207
215
 
208
216
  ### Nuxt Image
209
217
 
210
- Nuxt Content Assets works with [Nuxt Image](https://image.nuxtjs.org/) with just a little configuration:
218
+ [Nuxt Image](https://image.nuxtjs.org/) is supported by adding Nuxt Content Asset's cache folder as a Nuxt Layer:
211
219
 
212
220
  ```ts
213
221
  // nuxt.config.ts
214
222
  export default defineNuxtConfig({
215
- modules: [
216
- // Nuxt Image should be placed before Nuxt Content Assets
217
- '@nuxt/image',
218
- 'nuxt-content-assets',
219
- '@nuxt/content',
220
- ],
221
-
222
223
  extends: [
223
- // add Nuxt Content Assets build folder as a Nuxt Layer (since v1.4.0)
224
- '.nuxt/content-assets',
224
+ 'node_modules/nuxt-content-assets/cache',
225
225
  ],
226
226
  }
227
227
  ```
228
228
 
229
- > Note that the new Layers setup enables Nuxt Image to load images from both the project's `public` folder and from `content`.
230
-
231
229
  To serve all images as Nuxt Image images, create a `ProseImg` component like so:
232
230
 
233
231
  ```vue
@@ -239,7 +237,6 @@ To serve all images as Nuxt Image images, create a `ProseImg` component like so:
239
237
 
240
238
  See the playground folder for both the [global](playground/components/temp/ProseImg.vue) and a [per image](playground/components/content/NuxtImg.ts) solution.
241
239
 
242
-
243
240
  ## Configuration
244
241
 
245
242
  The module has the following options:
@@ -248,11 +245,11 @@ The module has the following options:
248
245
  // nuxt.config.ts
249
246
  export default defineNuxtConfig({
250
247
  contentAssets: {
251
- // inject image sizes into the rendered html
248
+ // inject image size hints into the rendered html
252
249
  imageSize: 'style',
253
250
 
254
251
  // treat these extensions as content
255
- contentExtensions: 'md csv ya?ml json',
252
+ contentExtensions: 'mdx? csv ya?ml json',
256
253
 
257
254
  // output debug messages
258
255
  debug: false,
@@ -262,7 +259,11 @@ export default defineNuxtConfig({
262
259
 
263
260
  ### Image size
264
261
 
265
- You can add one or more image size hints to the generated images:
262
+ > [!Note]
263
+ >
264
+ > Since `v1.4.1` image size hints are now opt-in. This was done to maximise compatibiility with Nuxt Image.
265
+
266
+ You can add one _or more_ image size hints to the generated images:
266
267
 
267
268
  ```ts
268
269
  {
@@ -277,7 +278,6 @@ Pick from the following switches:
277
278
  | `'style'` | Adds `style="aspect-ratio:..."` to any `<img>` tag |
278
279
  | `'attrs'` | Adds `width` and `height` attributes to any `<img>` tag |
279
280
  | `'src'` | Adds `?width=...&height=...` to `src` attribute (frontmatter only) |
280
- | `false` | Disable image size hints |
281
281
 
282
282
  Note: if you add *only* `attrs`, include the following CSS in your app:
283
283
 
@@ -290,15 +290,20 @@ img {
290
290
 
291
291
  ### Content extensions
292
292
 
293
+ > [!NOTE]
293
294
  > Generally, you shouldn't need to touch this setting
294
295
 
295
- This setting tells Nuxt Content to ignore anything that is **not** one of these file extensions:
296
+ This setting tells Nuxt Content to ignore anything that is **not** one of the supported content types:
296
297
 
297
298
  ```
298
- md csv ya?ml json
299
+ mdx? csv ya?ml json
299
300
  ```
300
301
 
301
- This way, you can use any **other** file type as an asset, without needing to explicitly configure extensions.
302
+ This way, you can use any **other** file type as an asset, without needing to explicitly configure Nuxt Content's [ignores](https://content.nuxt.com/get-started/configuration#ignores) list.
303
+
304
+ Without this, Nuxt Content would warn about unsupported file types:
305
+
306
+ > [WARN] .jpg files are not supported, "content:path:to:some-asset.jpg" falling back to raw content
302
307
 
303
308
  ### Debug
304
309
 
@@ -312,65 +317,85 @@ If you want to see what the module does as it runs, set `debug` to true:
312
317
 
313
318
  ## How it works
314
319
 
315
- When Nuxt builds, the module scans all content sources for assets, copies them to an accessible public assets folder, and indexes path and image metadata.
320
+ When Nuxt builds, the module scans all content sources for assets, copies them to a temporary layer folder (`nuxt_modules/nuxt-content-assets/cache`), and indexes path and image metadata.
316
321
 
317
- After Nuxt Content has run, the parsed content is traversed, and both element attributes and frontmatter properties are checked to see if they resolve to the indexed asset paths.
322
+ After Nuxt Content has run, the parsed content (`.nuxt/content-cache`) is traversed, and both element attributes and frontmatter properties are checked to see if they resolve to the previously-indexed asset paths.
318
323
 
319
- If they do, then the attribute or property is rewritten with the absolute path. If the asset is an image, then the element or metadata is optionally updated with size attributes or a query string.
324
+ If they do, then the attribute or property in Nuxt Content's cache is rewritten with the absolute path. If the asset is an image, then the element or metadata is optionally updated with size attributes or a query string.
320
325
 
321
326
  Finally, Nitro serves the site, and any requests made to the transformed asset paths should be picked up and the *copied* asset served by the browser.
322
327
 
323
- In development, file watching propagates asset changes to the public folder, updates related cached content, and notifies the browser via web sockets to refresh any loaded images.
328
+ In development, a watch process propagates asset changes to the cache, updates the asset index, and notifies the browser via web sockets to refresh any loaded images.
329
+
330
+ If Nuxt Image is used, the `_ipx/` endpoint serves images directly from the cache's public folder.
324
331
 
325
332
  ## Development
326
333
 
327
- Should you wish to develop the project, the scripts are:
334
+ Should you wish to develop the project, you'll work with the following entities:
335
+
336
+ - [src](./src)<br>The module code itself
337
+ - [playground](./playground)<br>A standalone Nuxt app that reads the live module code
338
+ - [scripts](package.json)<br>A set of scripts to develop and publish the module
328
339
 
329
- Develop the module (running the playground which uses the live module code):
340
+ ### Setup
341
+
342
+ To set up the project, run each of these scripts once:
330
343
 
331
344
  ```bash
332
345
  # install dependencies
333
346
  npm install
334
347
 
335
- # generate playground type stubs (for the first time)
336
- npm run dev:prepare
337
-
338
- # develop (runs the playground app)
339
- npm run dev
340
-
341
- # run eslint
342
- npm run lint
348
+ # copy the cache folder to the playground's node_modules (workaround required in development)
349
+ npm run dev:setup
343
350
 
344
- # run vitest
345
- npm run test
346
- npm run test:watch
351
+ # generate types for the module and playground (re-run if you install new packages)
352
+ npm run dev:prepare
347
353
  ```
348
354
 
349
- Build and check the playground (simulating users' final build choices):
355
+ ### Development
356
+
357
+ To develop the module, utilise the supplied playground app:
350
358
 
351
359
  ```bash
360
+ # compile the module, run and serve the playground
361
+ npm run dev
362
+
352
363
  # generate the playground
353
364
  npm run dev:generate
354
365
 
355
366
  # build the playground
356
367
  npm run dev:build
357
368
 
358
- # serve the generated / built playground
369
+ # serve the generated/built playground
359
370
  npm run dev:preview
360
371
  ```
361
372
 
362
- Make a new release (so users can install the module):
373
+ Check your code quality using these tools:
374
+
375
+ ```bash
376
+ # lint your code with eslint
377
+ npm run lint
378
+
379
+ # runs tests with vitest
380
+ npm run test
381
+ npm run test:watch
382
+ ```
383
+
384
+ ### Publishing
385
+
386
+ > [!IMPORTANT]
387
+ > Before publishing, be sure to update the [version](package.json) and [changelog](CHANGELOG.md)!
388
+
389
+ To build and publish, run following scripts as required:
363
390
 
364
391
  ```bash
365
- # dry run the release
392
+ # lint, test, build, and dry-run publish
366
393
  npm run release:dry
367
394
 
368
- # release new version
395
+ # lint, test, build and publish
369
396
  npm run release
370
397
  ```
371
398
 
372
- Make sure to edit changelog and update `package.json` version before releasing!
373
-
374
399
  ## Maintenance
375
400
 
376
401
  This module was created using the Nuxt [Module Builder](https://github.com/nuxt/module-builder) command:
@@ -385,6 +410,8 @@ This created the module code from the starter template found here:
385
410
 
386
411
  Both [Nuxi](https://github.com/nuxt/cli) and the module's dependencies and scripts are updated fairly regularly, so from time to time this module may need to be updated to keep in sync. So far, this has meant just updating the dependencies and scripts, which are found in the starter template code mentioned above.
387
412
 
413
+ Note that the build/release scripts are slightly modified from the originals; build is now separated, and release now doesn't use [changelogen](https://github.com/unjs/changelogen), or automatically add tags and push to GitHub.
414
+
388
415
  <!-- Badges -->
389
416
  [npm-version-src]: https://img.shields.io/npm/v/nuxt-content-assets/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
390
417
  [npm-version-href]: https://npmjs.com/package/nuxt-content-assets
@@ -0,0 +1 @@
1
+ export default {}
@@ -0,0 +1,2 @@
1
+ *
2
+ !.gitignore
package/dist/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "1.4.2"
7
+ "version": "1.4.4"
8
8
  }
package/dist/module.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import Fs from 'fs';
1
+ import * as Fs from 'fs';
2
+ import Fs__default from 'fs';
2
3
  import Path from 'crosspath';
3
4
  import { useNuxt, createResolver, defineNuxtModule, addPlugin } from '@nuxt/kit';
4
5
  import { visit, SKIP, CONTINUE } from 'unist-util-visit';
@@ -36,6 +37,8 @@ function deKey(path) {
36
37
  const extensions = {
37
38
  // used to get image size
38
39
  image: matchTokens("png jpg jpeg gif svg webp ico"),
40
+ // used to recognise content
41
+ content: matchTokens("md mdx json yml yaml csv"),
39
42
  // unused for now
40
43
  media: matchTokens("mp3 m4a wav mp4 mov webm ogg avi flv avchd")
41
44
  };
@@ -47,15 +50,17 @@ function makeIgnores(extensions2) {
47
50
  function removeQuery(path) {
48
51
  return path.replace(/\?.*$/, "");
49
52
  }
53
+ function getExt(path) {
54
+ return Path.extname(removeQuery(path)).substring(1);
55
+ }
50
56
  function isExcluded(path) {
51
57
  return path.split("/").some((segment) => segment.startsWith(".") || segment.startsWith("_"));
52
58
  }
53
59
  function isImage(path) {
54
- const ext = Path.extname(path).substring(1);
55
- return extensions.image.includes(ext);
60
+ return extensions.image.includes(getExt(path));
56
61
  }
57
62
  function isArticle(path) {
58
- return removeQuery(path).endsWith(".md");
63
+ return extensions.content.includes(getExt(path));
59
64
  }
60
65
  function isAsset(path) {
61
66
  return !isArticle(path);
@@ -153,35 +158,47 @@ function buildQuery(...expr) {
153
158
  }
154
159
 
155
160
  function readFile(path, asJson = false) {
156
- const text = Fs.readFileSync(path, { encoding: "utf8" });
161
+ const text = Fs__default.readFileSync(path, { encoding: "utf8" });
157
162
  return asJson ? JSON.parse(text) : text;
158
163
  }
159
164
  function writeFile(path, data) {
160
165
  const text = typeof data === "object" ? JSON.stringify(data, null, " ") : String(data);
161
166
  createFolder(Path.dirname(path));
162
- Fs.writeFileSync(path, text, { encoding: "utf8" });
167
+ Fs__default.writeFileSync(path, text, { encoding: "utf8" });
163
168
  }
164
169
  async function writeBlob(path, data) {
165
170
  const buffer = Buffer.from(await data.arrayBuffer());
166
171
  createFolder(Path.dirname(path));
167
- Fs.writeFileSync(path, buffer);
172
+ Fs__default.writeFileSync(path, buffer);
168
173
  }
169
174
  function copyFile(src, trg) {
170
175
  createFolder(Path.dirname(trg));
171
- Fs.copyFileSync(src, trg);
176
+ Fs__default.copyFileSync(src, trg);
172
177
  }
173
178
  function removeFile(src) {
174
- Fs.rmSync(src);
179
+ Fs__default.rmSync(src);
175
180
  }
176
181
  function createFolder(path) {
177
- Fs.mkdirSync(path, { recursive: true });
182
+ Fs__default.mkdirSync(path, { recursive: true });
178
183
  }
179
184
  function removeFolder(path) {
180
185
  const isDownstream = path.startsWith(Path.resolve());
181
186
  if (isDownstream) {
182
- Fs.rmSync(path, { recursive: true, force: true });
187
+ Fs__default.rmSync(path, { recursive: true, force: true });
183
188
  }
184
189
  }
190
+ function removeEntry(path) {
191
+ if (Fs__default.existsSync(path)) {
192
+ if (isFile(path)) {
193
+ removeFile(path);
194
+ } else {
195
+ removeFolder(path);
196
+ }
197
+ }
198
+ }
199
+ function isFile(path) {
200
+ return Fs__default.lstatSync(path).isFile();
201
+ }
185
202
 
186
203
  function createWebSocket() {
187
204
  const wss = new WebSocketServer({ noServer: true });
@@ -390,22 +407,23 @@ function makeSourceManager(key, source, publicPath, callback) {
390
407
  }
391
408
 
392
409
  function makeAssetsManager(publicPath, shouldWatch = true) {
393
- const indexKey = "assets.json";
394
- const storage = makeSourceStorage(Path.join(publicPath, ".."));
410
+ const assetsKey = "assets.json";
411
+ const assetsPath = Path.join(publicPath, "..");
412
+ const storage = makeSourceStorage(assetsPath);
395
413
  if (shouldWatch) {
396
414
  void storage.watch(async (event, key) => {
397
- if (event === "update" && key === indexKey) {
415
+ if (event === "update" && key === assetsKey) {
398
416
  await load();
399
417
  }
400
418
  });
401
419
  }
402
420
  const assets = {};
403
421
  async function load() {
404
- const data = await storage.getItem(indexKey);
422
+ const data = await storage.getItem(assetsKey);
405
423
  Object.assign(assets, data || {});
406
424
  }
407
425
  const save = debounce(function() {
408
- void storage.setItem(indexKey, assets);
426
+ void storage.setItem(assetsKey, assets);
409
427
  }, 50);
410
428
  function resolveAsset(content, relAsset, registerContent = false) {
411
429
  const srcDir = Path.dirname(content._file);
@@ -447,8 +465,19 @@ function makeAssetsManager(publicPath, shouldWatch = true) {
447
465
  }
448
466
  return asset;
449
467
  }
468
+ const init = () => {
469
+ if (Fs.existsSync(publicPath)) {
470
+ const names = Fs.readdirSync(publicPath);
471
+ for (const name of names) {
472
+ if (!/^\.git(ignore|keep)$/.test(name)) {
473
+ removeEntry(Path.join(publicPath, name));
474
+ }
475
+ }
476
+ }
477
+ };
450
478
  void load();
451
479
  return {
480
+ init,
452
481
  setAsset,
453
482
  getAsset,
454
483
  removeAsset,
@@ -521,24 +550,29 @@ const meta = {
521
550
  const module = defineNuxtModule({
522
551
  meta,
523
552
  defaults: {
524
- imageSize: "style",
525
- contentExtensions: "md csv ya?ml json",
553
+ imageSize: "",
554
+ contentExtensions: "mdx? csv ya?ml json",
526
555
  debug: false
527
556
  },
528
557
  async setup(options, nuxt) {
529
558
  const buildPath = nuxt.options.buildDir;
530
- const assetsPath = Path.join(buildPath, "content-assets");
531
- const publicPath = Path.join(assetsPath, "public");
532
- const contentPath = Path.join(buildPath, "content-cache/parsed");
559
+ const modulesPath = nuxt.options.modulesDir.find((path) => Fs.existsSync(`${path}/nuxt-content-assets/cache`)) || "";
560
+ if (!modulesPath) {
561
+ warn("Unable to find cache folder!");
562
+ if (nuxt.options.srcDir.endsWith("/playground")) {
563
+ warn('Run "npm run dev:setup" to generate a new cache folder');
564
+ }
565
+ }
566
+ const cachePath = modulesPath ? Path.resolve(modulesPath, "nuxt-content-assets/cache") : Path.resolve(buildPath, "content-assets");
567
+ const publicPath = Path.join(cachePath, "public");
568
+ const contentPath = Path.join(buildPath, "content-cache");
533
569
  const isDev = !!nuxt.options.dev;
534
570
  const isDebug = !!options.debug;
535
571
  if (isDebug) {
536
- log("Removing cache folders...");
572
+ log("Cleaning content-cache");
573
+ log(`Cache path: "${Path.relative(".", cachePath)}"`);
537
574
  }
538
- removeFolder(Path.join(buildPath, "content-cache"));
539
- removeFolder(assetsPath);
540
- createFolder(`${assetsPath}/public`);
541
- writeFile(`${assetsPath}/nuxt.config.ts`, "export default {}");
575
+ removeEntry(contentPath);
542
576
  const { contentExtensions } = options;
543
577
  if (contentExtensions) {
544
578
  nuxt.options.content ||= {};
@@ -550,7 +584,7 @@ const module = defineNuxtModule({
550
584
  }
551
585
  const imageSizes = matchTokens(options.imageSize);
552
586
  const sources = Array.from(nuxt.options._layers).map((layer) => layer.config?.content?.sources).reduce((output, sources2) => {
553
- if (sources2) {
587
+ if (sources2 && !Array.isArray(sources2)) {
554
588
  Object.assign(output, sources2);
555
589
  }
556
590
  return output;
@@ -565,6 +599,7 @@ const module = defineNuxtModule({
565
599
  }
566
600
  }
567
601
  const assets = makeAssetsManager(publicPath, isDev);
602
+ assets.init();
568
603
  function onAssetChange(event, absTrg) {
569
604
  let src = "";
570
605
  let width;
@@ -577,7 +612,7 @@ const module = defineNuxtModule({
577
612
  if (oldAsset) {
578
613
  if (oldAsset.width !== newAsset.width || oldAsset.height !== newAsset.height) {
579
614
  newAsset.content.forEach(async (id) => {
580
- const path = Path.join(contentPath, toPath(id));
615
+ const path = Path.join(contentPath, "parsed", toPath(id));
581
616
  rewriteContent(path, newAsset);
582
617
  });
583
618
  }
@@ -3,10 +3,11 @@ import type { ParsedContent, AssetConfig } from '../../types';
3
3
  * Manages the public assets
4
4
  */
5
5
  export declare function makeAssetsManager(publicPath: string, shouldWatch?: boolean): {
6
+ init: () => void;
6
7
  setAsset: (path: string) => AssetConfig;
7
8
  getAsset: (path: string) => AssetConfig | undefined;
8
9
  removeAsset: (path: string) => AssetConfig | undefined;
9
- resolveAsset: (content: ParsedContent, relAsset: string, registerContent?: boolean) => AssetConfig;
10
+ resolveAsset: (content: ParsedContent, relAsset: string, registerContent?: boolean) => Partial<AssetConfig>;
10
11
  dispose: () => Promise<void>;
11
12
  };
12
13
  /**
@@ -1,26 +1,28 @@
1
+ import * as Fs from "fs";
1
2
  import Path from "crosspath";
2
3
  import getImageSize from "image-size";
3
4
  import debounce from "debounce";
4
5
  import { hash } from "ohash";
5
6
  import { makeSourceStorage } from "./source.mjs";
6
- import { isImage, warn, log } from "../utils/index.mjs";
7
+ import { isImage, warn, log, removeEntry } from "../utils/index.mjs";
7
8
  export function makeAssetsManager(publicPath, shouldWatch = true) {
8
- const indexKey = "assets.json";
9
- const storage = makeSourceStorage(Path.join(publicPath, ".."));
9
+ const assetsKey = "assets.json";
10
+ const assetsPath = Path.join(publicPath, "..");
11
+ const storage = makeSourceStorage(assetsPath);
10
12
  if (shouldWatch) {
11
13
  void storage.watch(async (event, key) => {
12
- if (event === "update" && key === indexKey) {
14
+ if (event === "update" && key === assetsKey) {
13
15
  await load();
14
16
  }
15
17
  });
16
18
  }
17
19
  const assets = {};
18
20
  async function load() {
19
- const data = await storage.getItem(indexKey);
21
+ const data = await storage.getItem(assetsKey);
20
22
  Object.assign(assets, data || {});
21
23
  }
22
24
  const save = debounce(function() {
23
- void storage.setItem(indexKey, assets);
25
+ void storage.setItem(assetsKey, assets);
24
26
  }, 50);
25
27
  function resolveAsset(content, relAsset, registerContent = false) {
26
28
  const srcDir = Path.dirname(content._file);
@@ -62,8 +64,19 @@ export function makeAssetsManager(publicPath, shouldWatch = true) {
62
64
  }
63
65
  return asset;
64
66
  }
67
+ const init = () => {
68
+ if (Fs.existsSync(publicPath)) {
69
+ const names = Fs.readdirSync(publicPath);
70
+ for (const name of names) {
71
+ if (!/^\.git(ignore|keep)$/.test(name)) {
72
+ removeEntry(Path.join(publicPath, name));
73
+ }
74
+ }
75
+ }
76
+ };
65
77
  void load();
66
78
  return {
79
+ init,
67
80
  setAsset,
68
81
  getAsset,
69
82
  removeAsset,
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export declare const extensions: {
5
5
  image: string[];
6
+ content: string[];
6
7
  media: string[];
7
8
  };
8
9
  /**
@@ -2,6 +2,8 @@ import { matchTokens } from "./string.mjs";
2
2
  export const extensions = {
3
3
  // used to get image size
4
4
  image: matchTokens("png jpg jpeg gif svg webp ico"),
5
+ // used to recognise content
6
+ content: matchTokens("md mdx json yml yaml csv"),
5
7
  // unused for now
6
8
  media: matchTokens("mp3 m4a wav mp4 mov webm ogg avi flv avchd")
7
9
  };
@@ -5,3 +5,5 @@ export declare function copyFile(src: string, trg: string): void;
5
5
  export declare function removeFile(src: string): void;
6
6
  export declare function createFolder(path: string): void;
7
7
  export declare function removeFolder(path: string): void;
8
+ export declare function removeEntry(path: string): void;
9
+ export declare function isFile(path: string): any;
@@ -30,3 +30,15 @@ export function removeFolder(path) {
30
30
  Fs.rmSync(path, { recursive: true, force: true });
31
31
  }
32
32
  }
33
+ export function removeEntry(path) {
34
+ if (Fs.existsSync(path)) {
35
+ if (isFile(path)) {
36
+ removeFile(path);
37
+ } else {
38
+ removeFolder(path);
39
+ }
40
+ }
41
+ }
42
+ export function isFile(path) {
43
+ return Fs.lstatSync(path).isFile();
44
+ }
@@ -6,6 +6,11 @@ export declare function parseQuery(path: string): string;
6
6
  * Removes the query string from a path
7
7
  */
8
8
  export declare function removeQuery(path: string): string;
9
+ /**
10
+ * Gets the extension of a path
11
+ * @param path
12
+ */
13
+ export declare function getExt(path: string): string;
9
14
  /**
10
15
  * Test path to be relative
11
16
  */
@@ -20,7 +25,7 @@ export declare function isExcluded(path: string): boolean;
20
25
  */
21
26
  export declare function isImage(path: string): boolean;
22
27
  /**
23
- * Test path is markdown
28
+ * Test path is markdown or data
24
29
  */
25
30
  export declare function isArticle(path: string): boolean;
26
31
  /**
@@ -7,6 +7,9 @@ export function parseQuery(path) {
7
7
  export function removeQuery(path) {
8
8
  return path.replace(/\?.*$/, "");
9
9
  }
10
+ export function getExt(path) {
11
+ return Path.extname(removeQuery(path)).substring(1);
12
+ }
10
13
  export function isRelative(path) {
11
14
  return !(path.startsWith("http") || Path.isAbsolute(path));
12
15
  }
@@ -14,11 +17,10 @@ export function isExcluded(path) {
14
17
  return path.split("/").some((segment) => segment.startsWith(".") || segment.startsWith("_"));
15
18
  }
16
19
  export function isImage(path) {
17
- const ext = Path.extname(path).substring(1);
18
- return extensions.image.includes(ext);
20
+ return extensions.image.includes(getExt(path));
19
21
  }
20
22
  export function isArticle(path) {
21
- return removeQuery(path).endsWith(".md");
23
+ return extensions.content.includes(getExt(path));
22
24
  }
23
25
  export function isAsset(path) {
24
26
  return !isArticle(path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-content-assets",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "Enable locally-located assets in Nuxt Content",
5
5
  "repository": "davestewart/nuxt-content-assets",
6
6
  "license": "MIT",
@@ -15,16 +15,23 @@
15
15
  "main": "./dist/module.cjs",
16
16
  "types": "./dist/types.d.ts",
17
17
  "files": [
18
+ "cache",
18
19
  "dist"
19
20
  ],
20
21
  "scripts": {
22
+ "dev:setup": "cpy cache playground/node_modules/nuxt-content-assets && cpy \"cache/**\" playground/.nuxt/content-assets",
23
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare",
24
+
21
25
  "dev": "nuxi dev playground",
22
- "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
23
26
  "dev:generate": "nuxi generate playground",
24
27
  "dev:build": "nuxi build playground",
25
28
  "dev:preview": "nuxi preview playground",
26
- "release": "npm run lint && npm run test && nuxt-module-build build && npm publish",
27
- "release:dry": "npm run lint && npm run test && nuxt-module-build build && npm publish --dry-run",
29
+
30
+ "build": "nuxt-module-build build",
31
+ "release:setup": "npm run lint && npm run test && npm run build",
32
+ "release:dry": "npm run release:setup && npm publish --dry-run",
33
+ "release": "npm run release:setup && npm publish",
34
+
28
35
  "lint": "eslint .",
29
36
  "test": "vitest run",
30
37
  "test:watch": "vitest watch"
@@ -44,18 +51,19 @@
44
51
  "@nuxt/content": "^2.0.0"
45
52
  },
46
53
  "devDependencies": {
47
- "@types/node": "^20.12.4",
48
54
  "@nuxt/devtools": "latest",
49
55
  "@nuxt/eslint-config": "^0.2.0",
50
56
  "@nuxt/module-builder": "^0.5.5",
51
57
  "@nuxt/schema": "^3.11.2",
52
58
  "@nuxt/test-utils": "^3.12.0",
59
+ "@types/debounce": "^1.2.1",
60
+ "@types/node": "^20.12.4",
61
+ "@types/ws": "^8.5.10",
53
62
  "changelogen": "^0.5.5",
63
+ "cpy-cli": "^5.0.0",
54
64
  "eslint": "^8.57.0",
55
65
  "nuxt": "^3.11.2",
56
- "vitest": "^1.4.0",
57
- "@types/debounce": "^1.2.1",
58
- "@types/ws": "^8.5.10"
66
+ "vitest": "^1.4.0"
59
67
  },
60
68
  "engines": {
61
69
  "node": ">=16.0.0"