@codecavepro/brand 1.4.0 → 1.5.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.
@@ -28,7 +28,7 @@ const imageUrl = (url: string) => props.resolveImage?.(url) ?? url
28
28
  </script>
29
29
 
30
30
  <template>
31
- <a :href="`${paths.insights}/${article.slug}`" :class="`mx-1 lg:mx-2 w-full h-full self-start sm:self-auto p-6 flex flex-col gap-5 sm:gap-8
31
+ <a :href="`${paths.insights}${article.slug}/`" :class="`mx-1 lg:mx-2 w-full h-full self-start sm:self-auto p-6 flex flex-col gap-5 sm:gap-8
32
32
  rounded-[2.25rem] bg-surface-secondary hover:bg-surface-secondary transition-colors cursor-pointer border-surface-tertiary border
33
33
  ${className ?? ''}`">
34
34
  <div class="flex flex-col sm:flex-row gap-5 sm:gap-8 h-fit">
@@ -47,6 +47,6 @@ export const reviews: Link[] = [
47
47
  ]
48
48
 
49
49
  export const legal: Link[] = [
50
- {name: 'Cookie policy', href: '/cookie-policy'},
51
- {name: 'Privacy policy', href: '/privacy-policy'},
50
+ {name: 'Cookie policy', href: paths.cookiePolicy},
51
+ {name: 'Privacy policy', href: paths.privacyPolicy},
52
52
  ]
@@ -1,21 +1,33 @@
1
+ /* Every value here is a COMPLETE url, trailing slash included, because
2
+ * build.format is Astro's default 'directory' — /workflow is emitted as
3
+ * workflow/index.html and only /workflow/ is the address of that file.
4
+ * Written without the slash, all 716 internal links on the site were a 308
5
+ * to the same page with one added; nothing complained because Astro's
6
+ * trailingSlash default is 'ignore'. astro.config.mjs now sets 'always', so
7
+ * dev 404s a slash-less route instead of quietly serving it.
8
+ *
9
+ * Consequence for callers: a path is a PREFIX you append to, never a
10
+ * segment you join with a slash. Write `${paths.insights}${slug}/`, not
11
+ * `${paths.insights}/${slug}` — the latter now yields //. scripts/check-links.mjs
12
+ * fails the build on either mistake. */
1
13
  const services = '/services'
2
14
 
3
15
  export const paths = {
4
16
  home: '/',
5
17
 
6
- devops: `${services}/devops`,
7
- autodesk: `${services}/autodesk`,
8
- hubspot: `${services}/hubspot`,
9
- ecommerce: `${services}/ecommerce`,
10
- automation: `${services}/automation`,
11
- arVr: `${services}/ar-vr`,
18
+ devops: `${services}/devops/`,
19
+ autodesk: `${services}/autodesk/`,
20
+ hubspot: `${services}/hubspot/`,
21
+ ecommerce: `${services}/ecommerce/`,
22
+ automation: `${services}/automation/`,
23
+ arVr: `${services}/ar-vr/`,
12
24
 
13
- workflow: '/workflow',
14
- projects: '/projects',
15
- insights: '/insights',
25
+ workflow: '/workflow/',
26
+ projects: '/projects/',
27
+ insights: '/insights/',
16
28
  contactUs: '/#contact-us',
17
- cookiePolicy: '/cookie-policy',
18
- privacyPolicy: '/privacy-policy',
29
+ cookiePolicy: '/cookie-policy/',
30
+ privacyPolicy: '/privacy-policy/',
19
31
 
20
32
  testimonials: '/#testimonials',
21
33
  strongPoints: '/workflow/#our-strong-point',
@@ -23,3 +35,30 @@ export const paths = {
23
35
  }
24
36
 
25
37
  export const websiteUrl = 'https://www.codecave.it'
38
+
39
+ /* Give an internal href the trailing slash the route table already carries.
40
+ *
41
+ * Links in CMS prose do not come from the table above — an editor writes
42
+ * them, and the privacy policy links the cookie policy as a bare
43
+ * https://www.codecave.it/cookie-policy, one 308 on a page nobody rebuilds.
44
+ * Normalising at render time is the only fix that survives the next edit.
45
+ *
46
+ * Deliberately narrow: internal only, and only where the last segment has no
47
+ * dot, so a linked .pdf keeps its own address. A #fragment or ?query is put
48
+ * back after the slash, since /workflow#x and /workflow/#x are different
49
+ * requests for the same reason. */
50
+ export const internalHref = (href: string): string => {
51
+ if (!href) return href
52
+
53
+ const rest = href.startsWith(websiteUrl)
54
+ ? href.slice(websiteUrl.length)
55
+ : href.startsWith('/') && !href.startsWith('//')
56
+ ? href
57
+ : null
58
+ if (rest === null) return href
59
+
60
+ const [path, tail = ''] = [rest.split(/[#?]/)[0], rest.slice(rest.split(/[#?]/)[0].length)]
61
+ if (!path || path.endsWith('/') || path.split('/').pop()!.includes('.')) return href
62
+
63
+ return href.slice(0, href.length - rest.length) + path + '/' + tail
64
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codecavepro/brand",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "CODECAVE design system — colour, typography and layout tokens as CSS custom properties and as a typed module.",
5
5
  "license": "Unlicense",
6
6
  "type": "module",