lightnet 3.4.0 → 3.4.2

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # lightnet
2
2
 
3
+ ## 3.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#256](https://github.com/LightNetDev/LightNet/pull/256) [`3c005c1`](https://github.com/LightNetDev/LightNet/commit/3c005c10ed55061f00f7d9c74e03be879bd5bb85) Thanks [@smn-cds](https://github.com/smn-cds)! - Improve error messages.
8
+
9
+ ## 3.4.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#254](https://github.com/LightNetDev/LightNet/pull/254) [`46c0f7c`](https://github.com/LightNetDev/LightNet/commit/46c0f7c693a46a7a2e06e72c4a333368aa8f7485) Thanks [@smn-cds](https://github.com/smn-cds)! - Improve responsive image variants:
14
+
15
+ - Improve image quality on search result items
16
+ - Limit the size of the media list image
17
+ - Streamline details page cover image variants
18
+ - Streamline gallery image variants
19
+
3
20
  ## 3.4.0
4
21
 
5
22
  ### Minor Changes
@@ -6,9 +6,9 @@ case `uname` in
6
6
  esac
7
7
 
8
8
  if [ -z "$NODE_PATH" ]; then
9
- export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.1_@types+node@22.14.0_jiti@2.4.2_lightningcss@1.29.1_rollup@4.39.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.1_@types+node@22.14.0_jiti@2.4.2_lightningcss@1.29.1_rollup@4.39.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules"
9
+ export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.2_@types+node@22.14.1_jiti@2.4.2_lightningcss@1.29.1_rollup@4.40.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.2_@types+node@22.14.1_jiti@2.4.2_lightningcss@1.29.1_rollup@4.40.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules"
10
10
  else
11
- export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.1_@types+node@22.14.0_jiti@2.4.2_lightningcss@1.29.1_rollup@4.39.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.1_@types+node@22.14.0_jiti@2.4.2_lightningcss@1.29.1_rollup@4.39.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules:$NODE_PATH"
11
+ export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.2_@types+node@22.14.1_jiti@2.4.2_lightningcss@1.29.1_rollup@4.40.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.6.2_@types+node@22.14.1_jiti@2.4.2_lightningcss@1.29.1_rollup@4.40.0_terser@5.39.0_typescript@5.8.3_yaml@2.7.1/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules:$NODE_PATH"
12
12
  fi
13
13
  if [ -x "$basedir/node" ]; then
14
14
  exec "$basedir/node" "$basedir/../astro/astro.js" "$@"
@@ -4,11 +4,11 @@
4
4
  "version": "0.0.1",
5
5
  "private": "true",
6
6
  "dependencies": {
7
- "@astrojs/react": "^4.2.3",
7
+ "@astrojs/react": "^4.2.4",
8
8
  "@astrojs/tailwind": "^6.0.2",
9
9
  "@lightnet/decap-admin": "^3.1.0",
10
- "astro": "^5.6.1",
11
- "lightnet": "^3.4.0",
10
+ "astro": "^5.6.2",
11
+ "lightnet": "^3.4.1",
12
12
  "react": "^19.1.0",
13
13
  "react-dom": "^19.1.0",
14
14
  "sharp": "^0.33.5",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "lightnet",
3
3
  "type": "module",
4
4
  "license": "MIT",
5
- "version": "3.4.0",
5
+ "version": "3.4.2",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/LightNetDev/lightnet",
@@ -45,17 +45,16 @@
45
45
  "@iconify-json/mdi": "^1.2.3",
46
46
  "@iconify/tailwind": "^1.2.0",
47
47
  "@tailwindcss/typography": "^0.5.16",
48
- "@types/react": "^19.1.0",
48
+ "@types/react": "^19.1.2",
49
49
  "daisyui": "^4.12.24",
50
50
  "fuse.js": "^7.1.0",
51
- "i18next": "^24.2.3",
52
- "marked": "^15.0.7",
53
- "yaml": "^2.7.1",
54
- "zod-validation-error": "^3.4.0"
51
+ "i18next": "^25.0.0",
52
+ "marked": "^15.0.8",
53
+ "yaml": "^2.7.1"
55
54
  },
56
55
  "devDependencies": {
57
56
  "@playwright/test": "^1.51.1",
58
- "@types/node": "^22.14.0",
57
+ "@types/node": "^22.14.1",
59
58
  "vitest": "^3.1.1"
60
59
  },
61
60
  "scripts": {
@@ -23,7 +23,8 @@ export function lightnet(lightnetConfig: LightnetConfig): AstroIntegration {
23
23
  const config = verifySchema(
24
24
  configSchema,
25
25
  lightnetConfig,
26
- "Invalid config passed to LightNet integration.",
26
+ "Invalid LightNet configuration",
27
+ "Fix these errors on the LightNet configuration inside astro.config.mjs:",
27
28
  )
28
29
 
29
30
  injectRoute({
@@ -52,7 +52,7 @@ const items = itemsInput.filter((item) => !!item)
52
52
  class="h-full w-full object-contain"
53
53
  src={item.data.image}
54
54
  alt=""
55
- widths={[120, 160, 240, 320, 640]}
55
+ widths={[256, 512, 768, 1024]}
56
56
  sizes={
57
57
  "(max-width: 640px) calc(calc(100vw - 3.5rem ) / 2), " +
58
58
  "(max-width: 768px) calc(calc(100vw - 5rem ) / 3), " +
@@ -62,6 +62,7 @@ const mediaTypes = Object.fromEntries(
62
62
  <Image
63
63
  class="max-h-32 w-auto max-w-32 rounded-sm object-contain shadow-md"
64
64
  src={item.data.image}
65
+ width={256}
65
66
  alt=""
66
67
  />
67
68
  </div>
@@ -23,5 +23,6 @@ const prepareItem = async (item: unknown) => {
23
23
  mediaItemEntrySchema,
24
24
  item,
25
25
  (id) => `Invalid media item: ${id}`,
26
+ (id) => `Fix these issues inside "src/content/media/${id}.json":`,
26
27
  )
27
28
  }
@@ -7,7 +7,8 @@ export const getMediaType = async (id: string) => {
7
7
  return verifySchema(
8
8
  mediaTypeEntrySchema,
9
9
  await getEntry("media-types", id),
10
- `Received invalid media type ${id}.`,
10
+ (id) => `Invalid media type: "${id}"`,
11
+ (id) => `Fix these issues inside "src/content/media-types/${id}.json":`,
11
12
  )
12
13
  }
13
14
 
@@ -17,7 +18,8 @@ export const getMediaTypes = async () => {
17
18
  verifySchema(
18
19
  mediaTypeEntrySchema,
19
20
  type,
20
- (id) => `Received invalid media type '${id}'.`,
21
+ (id) => `Invalid media type: "${id}"`,
22
+ (id) => `Fix these issues inside "src/content/media-types/${id}.json":`,
21
23
  ),
22
24
  )
23
25
  }
@@ -12,8 +12,8 @@ export const resolveCategoryLabel = (
12
12
  const category = categories.find((c) => c.id === categoryId)
13
13
  if (!category) {
14
14
  throw new AstroError(
15
- `Unknown category: ${categoryId}`,
16
- "Make sure you add the category to the categories content collection.",
15
+ `Missing category "${categoryId}"`,
16
+ `To fix the issue, add a category at "src/content/categories/${categoryId}.json".`,
17
17
  )
18
18
  }
19
19
  return translate(category.data.label)
@@ -11,8 +11,8 @@ export const resolveDefaultLocale = ({
11
11
  const defaultLanguage = languages.find((l) => l.isDefaultSiteLanguage)
12
12
  if (!defaultLanguage) {
13
13
  throw new AstroError(
14
- "No default site language has been set",
15
- "Make sure you have set one language to be the default language by setting the isDefaultSiteLanguage to `true`.",
14
+ "No default site language set",
15
+ "To fix the issue, set isDefaultSiteLanguage for one language in the LightNet configuration in your astro.config.mjs file.",
16
16
  )
17
17
  }
18
18
  return defaultLanguage.code
@@ -12,7 +12,10 @@ export const resolveLanguage = (bcp47: string) => {
12
12
  const language = languages[bcp47]
13
13
 
14
14
  if (!language) {
15
- throw new AstroError(`There is no language definition for: ${bcp47}`)
15
+ throw new AstroError(
16
+ `Missing language code "${bcp47}"`,
17
+ `To fix the issue, add a language with the code "${bcp47}" to the LightNet configuration in your astro.config.mjs file.`,
18
+ )
16
19
  }
17
20
  return {
18
21
  ...language,
@@ -47,7 +47,7 @@ export function useTranslate(bcp47: string | undefined): TranslateFn {
47
47
  if (value.match(/^(?:ln|x)\../i)) {
48
48
  throw new AstroError(
49
49
  `Missing translation: '${key}' is undefined for language '${resolvedLocale}'.`,
50
- `Add a translation for '${key}' to src/translations/${resolvedLocale}.yml`,
50
+ `To fix the issue, add a translation for '${key}' to src/translations/${resolvedLocale}.yml`,
51
51
  )
52
52
  }
53
53
  return value
@@ -17,8 +17,8 @@ const favicons = config.favicon?.map((favicon) => {
17
17
  const type = faviconTypes[extname(favicon.href)]
18
18
  if (!type) {
19
19
  throw new AstroError(
20
- `Unsupported favicon ${favicon.href}`,
21
- "favicon must be a .ico, .gif, .jpg, .png, or .svg file",
20
+ `Unsupported favicon type "${extname(favicon.href)}"`,
21
+ "To fix the issue, set the favicon href to a path ending with .ico, .gif, .jpg, .png, or .svg.",
22
22
  )
23
23
  }
24
24
  return { ...favicon, type }
@@ -32,7 +32,7 @@ async function createSearchItem(mediaItem: MediaItemEntry) {
32
32
  } = await getImage({
33
33
  src: image,
34
34
  format: "webp",
35
- width: 144,
35
+ width: 256,
36
36
  })
37
37
  return {
38
38
  title,
@@ -33,8 +33,8 @@ if (detailsPage?.layout === "custom") {
33
33
  ] as () => Promise<any>
34
34
  if (!customDetailsImport) {
35
35
  throw new AstroError(
36
- `Unknown details page ${detailsPage.customComponent}`,
37
- "Make sure to add your details component within /src/details-pages/",
36
+ `Missing custom details page "${detailsPage.customComponent}"`,
37
+ `To fix the issue, add your details page on "/src/details-pages/${detailsPage.customComponent}".`,
38
38
  )
39
39
  }
40
40
  CustomDetails = (await customDetailsImport()).default
@@ -14,7 +14,10 @@ const { collectionId, disableItem } = Astro.props
14
14
 
15
15
  const collection = await getEntry("media-collections", collectionId)
16
16
  if (!collection) {
17
- throw new AstroError(`Unknown media collection id ${collection}.`)
17
+ throw new AstroError(
18
+ `Missing media-collection "${collectionId}".`,
19
+ `To fix the issue, add a media-collection at "src/content/media-collections/${collectionId}.json".`,
20
+ )
18
21
  }
19
22
  const items = (
20
23
  await queryMediaItems(getMediaItems(), {
@@ -9,7 +9,7 @@ const { src, className } = Astro.props
9
9
  if (!src.endsWith(".mp3")) {
10
10
  throw new AstroError(
11
11
  `Unsupported audio file ${src}`,
12
- "Mp3 is the only supported format.",
12
+ "To fix the issue, reference a mp3 file.",
13
13
  )
14
14
  }
15
15
  ---
@@ -21,7 +21,7 @@ const isPortraitImage = image.height > image.width
21
21
  <Image
22
22
  class:list={isPortraitImage ? "h-52 w-auto sm:h-72" : "h-auto w-52 sm:w-72"}
23
23
  alt=""
24
- widths={[208, 288, 576, 864]}
24
+ widths={[256, 512, 768, 1024]}
25
25
  sizes="(max-width: 640px) 13rem, 18rem"
26
26
  src={image}
27
27
  quality="high"
@@ -20,7 +20,9 @@ export function useSearch() {
20
20
  try {
21
21
  const response = await fetch("/api/search.json")
22
22
  if (!response.ok) {
23
- throw new Error("Network response was not ok")
23
+ throw new Error(
24
+ "Was not able to load search results from /api/search.json.",
25
+ )
24
26
  }
25
27
  const { items }: SearchResponse = await response.json()
26
28
  fuse.current = new Fuse(items, {
@@ -1,15 +1,15 @@
1
1
  import { AstroError } from "astro/errors"
2
2
  import { z } from "astro/zod"
3
- import { fromZodError } from "zod-validation-error"
4
3
 
5
4
  export async function verifySchemaAsync<T extends z.Schema>(
6
5
  schema: T,
7
6
  toVerify: unknown,
8
7
  errorMessage: string | ((id: string | undefined) => string),
8
+ hint: string | ((id: string | undefined) => string),
9
9
  ): Promise<z.output<T>> {
10
10
  const parsed = await schema.safeParseAsync(toVerify)
11
11
  if (!parsed.success) {
12
- throwParseError(toVerify, errorMessage, parsed)
12
+ throwParseError(toVerify, errorMessage, hint, parsed)
13
13
  }
14
14
  return parsed.data
15
15
  }
@@ -18,10 +18,11 @@ export function verifySchema<T extends z.Schema>(
18
18
  schema: T,
19
19
  toVerify: unknown,
20
20
  errorMessage: string | ((id: string | undefined) => string),
21
+ hint: string | ((id: string | undefined) => string),
21
22
  ): z.output<T> {
22
23
  const parsed = schema.safeParse(toVerify, {})
23
24
  if (!parsed.success) {
24
- throwParseError(toVerify, errorMessage, parsed)
25
+ throwParseError(toVerify, errorMessage, hint, parsed)
25
26
  }
26
27
  return parsed.data
27
28
  }
@@ -29,10 +30,15 @@ export function verifySchema<T extends z.Schema>(
29
30
  function throwParseError(
30
31
  toVerify: unknown,
31
32
  errorMessage: string | ((id: string | undefined) => string),
33
+ hint: string | ((id: string | undefined) => string),
32
34
  parsed: z.SafeParseError<unknown>,
33
35
  ) {
34
36
  const id = z.object({ id: z.string() }).safeParse(toVerify).data?.id
35
37
  const message =
36
38
  typeof errorMessage === "string" ? errorMessage : errorMessage(id)
37
- throw new AstroError(message, fromZodError(parsed.error).toString())
39
+ const hintFinal = typeof hint === "string" ? hint : hint(id)
40
+ const issues = parsed.error.errors
41
+ .map((e) => `- ${e.path.join(".")}: ${e.message}`)
42
+ .join("\n")
43
+ throw new AstroError(message, `${hintFinal}\n\n${issues}`)
38
44
  }