@xleddyl/nuxt-cms 0.1.29 → 0.1.30

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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xleddyl/nuxt-cms",
3
3
  "configKey": "cms",
4
- "version": "0.1.29",
4
+ "version": "0.1.30",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -11,6 +11,30 @@ import { minifyIntrospection, outputIntrospectionFile } from 'gql.tada/internal'
11
11
  import { createJiti } from 'jiti';
12
12
  import { typeName, blockTypeName, blockUnionName, renderGraphqlSdl } from '../dist/runtime/shared/graphql-sdl.js';
13
13
  import { isMultiSelect, isTranslatableField, isTranslatableMediaField, DEFAULT_MEDIA_MAX_FILE_SIZE } from '../dist/runtime/shared/index.js';
14
+ import { scanMediaDirectory, readMediaFileMeta } from '../dist/runtime/server/utils/media-sync.js';
15
+
16
+ async function collectMediaManifest(root) {
17
+ const files = await scanMediaDirectory(root);
18
+ return Promise.all(files.map((file) => readMediaFileMeta(root, file)));
19
+ }
20
+ function renderMediaManifestFile(files) {
21
+ return [
22
+ `export const generated = ${files !== null}`,
23
+ ``,
24
+ `export const files = ${JSON.stringify(files ?? [], null, 3)}`,
25
+ ``
26
+ ].join("\n");
27
+ }
28
+ function renderMediaManifestTypes(typesPath) {
29
+ return [
30
+ `import type { MediaFileMeta } from '${typesPath}'`,
31
+ ``,
32
+ `export declare const generated: boolean`,
33
+ ``,
34
+ `export declare const files: MediaFileMeta[]`,
35
+ ``
36
+ ].join("\n");
37
+ }
14
38
 
15
39
  const IDENTIFIER = /^[a-z_]\w*$/i;
16
40
  const RESERVED_ENTRY_KEYS = ["admin", "auth", "login", "media", "graphql", "cms_media"];
@@ -697,6 +721,30 @@ const module$1 = defineNuxtModule({
697
721
  ``
698
722
  ].join("\n")
699
723
  });
724
+ const publicDir = resolve(nuxt.options.rootDir, nuxt.options.dir?.public ?? "public");
725
+ const mediaLocalRoot = resolved.media.storage === "local" && resolved.media.publicBaseUrl.startsWith("/") ? join(publicDir, ...resolved.media.publicBaseUrl.split("/").filter(Boolean)) : "";
726
+ addTemplate({
727
+ filename: "cms/media-manifest.d.ts",
728
+ write: true,
729
+ getContents: () => renderMediaManifestTypes(
730
+ toPosix(resolver.resolve("./runtime/server/utils/media-sync"))
731
+ )
732
+ });
733
+ const mediaManifestTemplate = addTemplate({
734
+ filename: "cms/media-manifest.js",
735
+ write: true,
736
+ getContents: async () => {
737
+ if (!mediaLocalRoot || nuxt.options.dev) return renderMediaManifestFile(null);
738
+ if (!existsSync(mediaLocalRoot)) {
739
+ logger.warn(
740
+ `[nuxt-cms] Local media folder not found at build time: ${mediaLocalRoot}. The media library will not be synced at runtime.`
741
+ );
742
+ return renderMediaManifestFile(null);
743
+ }
744
+ return renderMediaManifestFile(await collectMediaManifest(mediaLocalRoot));
745
+ }
746
+ });
747
+ nuxt.options.alias["#cms-media-manifest"] = mediaManifestTemplate.dst;
700
748
  addServerPlugin(
701
749
  resolver.resolve(
702
750
  driver === "postgres" ? "./runtime/server/plugins/migrate-postgres" : driver === "libsql" ? "./runtime/server/plugins/migrate-libsql" : "./runtime/server/plugins/migrate-sqlite"
@@ -726,8 +774,6 @@ const module$1 = defineNuxtModule({
726
774
  logger.error(`[nuxt-cms] drizzle-kit generate failed (exit code ${code})`);
727
775
  });
728
776
  }
729
- const publicDir = resolve(nuxt.options.rootDir, nuxt.options.dir?.public ?? "public");
730
- const mediaLocalRoot = resolved.media.storage === "local" && resolved.media.publicBaseUrl.startsWith("/") ? join(publicDir, ...resolved.media.publicBaseUrl.split("/").filter(Boolean)) : "";
731
777
  const existingConfig = nuxt.options.runtimeConfig.cms ?? {};
732
778
  nuxt.options.runtimeConfig.cms = {
733
779
  adminEmail: resolved.admin.email,
@@ -1,39 +1,56 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { eq, inArray } from "drizzle-orm";
3
3
  import { useDb } from "#cms-db";
4
+ import { files as manifestFiles, generated as manifestGenerated } from "#cms-media-manifest";
4
5
  import { cms_media } from "#cms-tables";
5
6
  import { useRuntimeConfig } from "#imports";
6
7
  import { chunked, planMediaSync, readMediaFileMeta, scanMediaDirectory } from "../utils/media-sync.js";
7
8
  const CHUNK_SIZE = 100;
9
+ async function resolveMediaSource(root) {
10
+ if (existsSync(root)) {
11
+ return {
12
+ origin: root,
13
+ files: await scanMediaDirectory(root),
14
+ meta: (file) => readMediaFileMeta(root, file)
15
+ };
16
+ }
17
+ if (!manifestGenerated) return null;
18
+ const byKey = new Map(manifestFiles.map((file) => [file.key, file]));
19
+ return {
20
+ origin: `build manifest of ${root}`,
21
+ files: manifestFiles.map(({ key, size }) => ({ key, size })),
22
+ meta: async (file) => byKey.get(file.key)
23
+ };
24
+ }
8
25
  export default async () => {
9
26
  try {
10
27
  const { media } = useRuntimeConfig().cms;
11
28
  if (media?.storage !== "local") return;
12
29
  const root = media.localRoot;
13
30
  if (!root) return;
14
- if (!existsSync(root)) {
31
+ const source = await resolveMediaSource(root);
32
+ if (!source) {
15
33
  console.info(
16
- `[nuxt-cms] Local media folder not found: ${root}. Skipping media library sync.`
34
+ `[nuxt-cms] Local media folder not found: ${root}, and no build manifest was generated. Skipping media library sync.`
17
35
  );
18
36
  return;
19
37
  }
20
- const files = await scanMediaDirectory(root);
21
38
  const db = useDb();
22
39
  const rows = await db.select({ key: cms_media.key, size: cms_media.size }).from(cms_media);
23
- const { insert, update, remove } = planMediaSync(files, rows);
40
+ const { insert, update, remove } = planMediaSync(source.files, rows);
24
41
  for (const chunk of chunked(insert, CHUNK_SIZE)) {
25
- const values = await Promise.all(chunk.map((file) => readMediaFileMeta(root, file)));
42
+ const values = await Promise.all(chunk.map((file) => source.meta(file)));
26
43
  await db.insert(cms_media).values(values.map((value) => ({ ...value, alt: null }))).onConflictDoNothing();
27
44
  }
28
45
  for (const file of update) {
29
- const { mime, size, width, height } = await readMediaFileMeta(root, file);
46
+ const { mime, size, width, height } = await source.meta(file);
30
47
  await db.update(cms_media).set({ mime, size, width, height }).where(eq(cms_media.key, file.key));
31
48
  }
32
49
  for (const chunk of chunked(remove, CHUNK_SIZE)) {
33
50
  await db.delete(cms_media).where(inArray(cms_media.key, chunk));
34
51
  }
35
52
  console.info(
36
- `[nuxt-cms] Local media sync: ${insert.length} added, ${remove.length} removed, ${update.length} updated (${files.length} file${files.length === 1 ? "" : "s"} in ${root})`
53
+ `[nuxt-cms] Local media sync: ${insert.length} added, ${remove.length} removed, ${update.length} updated (${source.files.length} file${source.files.length === 1 ? "" : "s"} in ${source.origin})`
37
54
  );
38
55
  } catch (error) {
39
56
  console.warn("[nuxt-cms] Local media sync failed:", error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xleddyl/nuxt-cms",
3
- "version": "0.1.29",
3
+ "version": "0.1.30",
4
4
  "description": "Lightweight CMS that ships with your Nuxt app: runs on the Nitro server, content types defined in code, /cms admin panel, GraphQL API, SQLite or Postgres. No external CMS needed!",
5
5
  "license": "MIT",
6
6
  "author": "Edoardo Alberti (https://github.com/xleddyl)",
@@ -105,6 +105,6 @@
105
105
  "test": "vitest run",
106
106
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
107
107
  "format": "prettier --write \"**/*.{ts,tsx,js,jsx,md,html,json,sql,vue}\" --log-level error",
108
- "release": "changelogen --release && git push origin main && git push origin v$(node -p \"require('./package.json').version\")"
108
+ "release": "changelogen --release --no-github && git push origin main && git push origin v$(node -p \"require('./package.json').version\")"
109
109
  }
110
110
  }