kmcom-nuxt-layers 2.7.3 → 2.7.5

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.
@@ -16,3 +16,10 @@
16
16
 
17
17
  @import '#layers/core/app/assets/css/layout.css';
18
18
  @import '#layers/core/app/assets/css/base.css';
19
+
20
+ /* Relative path, not the '#layers/typography' alias — that alias only exists
21
+ when the typography layer is in a consumer's `extends`. This file is a CSS
22
+ import (needed so Tailwind treats it as part of this one build root, see
23
+ typography.css's header comment), and must resolve even for consumers that
24
+ only extend core, since it lives in the same single published package. */
25
+ @import '../../../../typography/app/assets/css/typography.css';
@@ -0,0 +1,12 @@
1
+ import { _api } from '@iconify/vue'
2
+
3
+ // @nuxt/icon@2.5.0 wires `_api.setFetch(useRequestFetch().native)`, but this
4
+ // Nuxt/ofetch version doesn't expose `.native` on the request-scoped fetch,
5
+ // so every icon lookup gets `undefined` as its fetch fn and fails instantly.
6
+ // Re-point it at the global fetch after @nuxt/icon's own plugin has run.
7
+ export default defineNuxtPlugin({
8
+ name: 'icon-fetch-fix',
9
+ setup() {
10
+ _api.setFetch(fetch)
11
+ },
12
+ })
@@ -19,6 +19,9 @@
19
19
  "nuxtupdate": "npx nuxi@latest upgrade --dedupe --force",
20
20
  "nuxiupgrade": "npx nuxi upgrade"
21
21
  },
22
+ "dependencies": {
23
+ "@iconify/vue": "catalog:"
24
+ },
22
25
  "devDependencies": {
23
26
  "@vite-pwa/nuxt": "catalog:"
24
27
  }
@@ -2,13 +2,23 @@ import type { MetadataCreator, MetadataRecord } from '#layers/metadata/shared/ty
2
2
 
3
3
  import type { ComicVineIssue, ComicVineVolume } from './types'
4
4
 
5
- // fallow-ignore-next-line complexity
6
- export function normaliseComicVineIssue(issue: ComicVineIssue): MetadataRecord {
7
- const creators: MetadataCreator[] = (issue.person_credits ?? []).map((p) => ({
5
+ function mapComicVineCreators(
6
+ people: Array<{ id: number; name: string; role: string }> | null
7
+ ): MetadataCreator[] {
8
+ return (people ?? []).map((p) => ({
8
9
  name: p.name,
9
10
  role: p.role,
10
11
  providerId: String(p.id),
11
12
  }))
13
+ }
14
+
15
+ function buildComicVineIssueTitle(issue: ComicVineIssue): string {
16
+ if (issue.volume?.name) return `${issue.volume.name} #${issue.issue_number}`
17
+ return issue.name ?? `Issue #${issue.issue_number}`
18
+ }
19
+
20
+ export function normaliseComicVineIssue(issue: ComicVineIssue): MetadataRecord {
21
+ const creators = mapComicVineCreators(issue.person_credits)
12
22
 
13
23
  const description = issue.deck ?? issue.description
14
24
  const publishedAt = issue.cover_date ?? issue.store_date
@@ -19,9 +29,7 @@ export function normaliseComicVineIssue(issue: ComicVineIssue): MetadataRecord {
19
29
  provider: 'comicvine',
20
30
  providerId: String(issue.id),
21
31
  mediaType: 'comic',
22
- title: issue.volume?.name
23
- ? `${issue.volume.name} #${issue.issue_number}`
24
- : (issue.name ?? `Issue #${issue.issue_number}`),
32
+ title: buildComicVineIssueTitle(issue),
25
33
  ...(issue.name && { subtitle: issue.name }),
26
34
  ...(description && { description }),
27
35
  ...(creators.length && { creators }),
@@ -35,22 +43,17 @@ export function normaliseComicVineIssue(issue: ComicVineIssue): MetadataRecord {
35
43
  }
36
44
  }
37
45
 
38
- // fallow-ignore-next-line complexity
46
+ function buildComicVineVolumeSubtitle(volume: ComicVineVolume): string {
47
+ const issueCount = volume.count_of_issues
48
+ ? `${volume.count_of_issues} issue${volume.count_of_issues === 1 ? '' : 's'}`
49
+ : null
50
+ return [volume.publisher?.name, issueCount].filter(Boolean).join(' · ')
51
+ }
52
+
39
53
  export function normaliseComicVineVolume(volume: ComicVineVolume): MetadataRecord {
40
- const creators: MetadataCreator[] = (volume.people ?? []).map((p) => ({
41
- name: p.name,
42
- role: p.role,
43
- providerId: String(p.id),
44
- }))
54
+ const creators = mapComicVineCreators(volume.people)
45
55
 
46
- const subtitle = [
47
- volume.publisher?.name,
48
- volume.count_of_issues
49
- ? `${volume.count_of_issues} issue${volume.count_of_issues === 1 ? '' : 's'}`
50
- : null,
51
- ]
52
- .filter(Boolean)
53
- .join(' · ')
56
+ const subtitle = buildComicVineVolumeSubtitle(volume)
54
57
  const description = volume.deck ?? volume.description
55
58
  const coverUrl = volume.image?.medium_url ?? volume.image?.original_url
56
59
 
@@ -1,27 +1,34 @@
1
1
  import type { MetadataCreator, MetadataRecord } from '#layers/metadata/shared/types'
2
2
 
3
- import type { GoogleBooksVolume } from './types'
4
-
5
- // fallow-ignore-next-line complexity
6
- export function normaliseGoogleBooksVolume(volume: GoogleBooksVolume): MetadataRecord {
7
- const { volumeInfo } = volume
8
-
9
- const creators: MetadataCreator[] = (volumeInfo.authors ?? []).map((name) => ({
10
- name,
11
- role: 'author',
12
- }))
3
+ import type { GoogleBooksVolume, GoogleBooksVolumeInfo } from './types'
13
4
 
5
+ function resolveGoogleBooksIsbns(volumeInfo: GoogleBooksVolumeInfo) {
14
6
  const isbn10 = volumeInfo.industryIdentifiers?.find((i) => i.type === 'ISBN_10')?.identifier
15
7
  const isbn13 = volumeInfo.industryIdentifiers?.find((i) => i.type === 'ISBN_13')?.identifier
8
+ return { isbn10, isbn13 }
9
+ }
16
10
 
17
- const rawCover =
11
+ function resolveGoogleBooksRawCover(volumeInfo: GoogleBooksVolumeInfo) {
12
+ return (
18
13
  volumeInfo.imageLinks?.extraLarge ??
19
14
  volumeInfo.imageLinks?.large ??
20
15
  volumeInfo.imageLinks?.medium ??
21
16
  volumeInfo.imageLinks?.small ??
22
17
  volumeInfo.imageLinks?.thumbnail ??
23
18
  volumeInfo.imageLinks?.smallThumbnail
19
+ )
20
+ }
21
+
22
+ export function normaliseGoogleBooksVolume(volume: GoogleBooksVolume): MetadataRecord {
23
+ const { volumeInfo } = volume
24
+
25
+ const creators: MetadataCreator[] = (volumeInfo.authors ?? []).map((name) => ({
26
+ name,
27
+ role: 'author',
28
+ }))
24
29
 
30
+ const { isbn10, isbn13 } = resolveGoogleBooksIsbns(volumeInfo)
31
+ const rawCover = resolveGoogleBooksRawCover(volumeInfo)
25
32
  const sourceUrl = volumeInfo.canonicalVolumeLink ?? volumeInfo.infoLink
26
33
 
27
34
  return {
@@ -1,16 +1,10 @@
1
1
  /*
2
- * Loaded as its own global stylesheet (see layers/typography/nuxt.config.ts
3
- * `css:` array), not @import-chained through core.css's Tailwind root — so
4
- * @utility below is invisible to Tailwind unless this file is its own build
5
- * root. theme+utilities only (no preflight) to avoid double-emitting the
6
- * reset core.css already provides.
2
+ * @import-chained through core.css's single Tailwind build root (see
3
+ * layers/core/app/assets/css/core.css) — must NOT open its own
4
+ * 'tailwindcss/theme'/'tailwindcss/utilities' root, that creates a second
5
+ * parallel Tailwind build and breaks content-scan coverage for @nuxt/ui
6
+ * utilities elsewhere in the app (see kmcom-nuxt-layers-typography-css-bug.md).
7
7
  */
8
- @import 'tailwindcss/theme' layer(theme);
9
- @import 'tailwindcss/utilities' layer(utilities);
10
-
11
- @source '../../../../*/app/**/*.{vue,ts}';
12
- @source '../../../../../apps/*/app/**/*.{vue,ts}';
13
-
14
8
  :root {
15
9
  /* Fluid type scale — rounding interval. rem, never px (see §5 a11y). */
16
10
  --fluid-step: 0.25rem;
@@ -8,8 +8,6 @@ export default defineNuxtConfig({
8
8
  '#layers/typography/types': `${import.meta.dirname}/app/types`,
9
9
  },
10
10
 
11
- css: ['#layers/typography/app/assets/css/typography.css'],
12
-
13
11
  compatibilityDate: '2026-06-06',
14
12
 
15
13
  typescript: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kmcom-nuxt-layers",
3
3
  "private": false,
4
- "version": "2.7.3",
4
+ "version": "2.7.5",
5
5
  "description": "Composable Nuxt 4 layers for building scalable Vue applications",
6
6
  "exports": {
7
7
  "./layers/core": "./layers/core/nuxt.config.ts",