@edgedev/create-edge-site 1.0.12 → 1.0.14

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.
Files changed (31) hide show
  1. package/{components → app/components}/edgeScrollRevealAnim.vue +5 -8
  2. package/{directives → app/directives}/scrollReveal.ts +1 -1
  3. package/{pages → app/pages}/contact.vue +1 -1
  4. package/{pages → app/pages}/stuff.vue +1 -1
  5. package/nuxt.config.ts +13 -1
  6. package/package.json +2 -1
  7. package/scripts/generateImageManifest.mjs +1 -1
  8. package/server/api/hello.ts +2 -2
  9. package/server/api/images/[...path].ts +5 -2
  10. package/server/api/images/index.ts +6 -2
  11. package/server/api/kv/[key].ts +17 -0
  12. package/server/routes/sitemap.xml.ts +33 -0
  13. package/server/utils/getKV.js +65 -0
  14. package/tailwind.config.js +23 -23
  15. package/wrangler.toml +3 -0
  16. /package/{app.vue → app/app.vue} +0 -0
  17. /package/{assets → app/assets}/css/global.css +0 -0
  18. /package/{components → app/components}/Input.vue +0 -0
  19. /package/{components → app/components}/Select.vue +0 -0
  20. /package/{components → app/components}/Textarea.vue +0 -0
  21. /package/{components → app/components}/edgeFooter.vue +0 -0
  22. /package/{components → app/components}/edgeFormFling.vue +0 -0
  23. /package/{components → app/components}/edgeGallery.vue +0 -0
  24. /package/{components → app/components}/edgeNavbar.vue +0 -0
  25. /package/{components → app/components}/edgeSwiper.vue +0 -0
  26. /package/{components → app/components}/titleSection.vue +0 -0
  27. /package/{pages → app/pages}/[...404].vue +0 -0
  28. /package/{pages → app/pages}/index.vue +0 -0
  29. /package/{plugins → app/plugins}/scrollReveal.ts +0 -0
  30. /package/{plugins → app/plugins}/vee-validate-rules.js +0 -0
  31. /package/{plugins → app/plugins}/vue-imask.js +0 -0
@@ -1,8 +1,9 @@
1
1
  <script setup>
2
- import ScrollReveal from 'scrollreveal'
3
2
  import { onMounted } from 'vue'
4
3
 
5
- function initObserver() {
4
+ onMounted(async () => {
5
+ const ScrollReveal = (await import('scrollreveal')).default
6
+
6
7
  const rows = document.querySelectorAll('.sr-row')
7
8
 
8
9
  const observer = new IntersectionObserver((entries, obs) => {
@@ -21,18 +22,14 @@ function initObserver() {
21
22
  reset: false,
22
23
  })
23
24
 
24
- obs.unobserve(row) // only trigger once
25
+ obs.unobserve(row)
25
26
  }
26
27
  })
27
28
  }, {
28
- threshold: 0.3, // only trigger when 30% of the row is visible
29
+ threshold: 0.3,
29
30
  })
30
31
 
31
32
  rows.forEach(row => observer.observe(row))
32
- }
33
-
34
- onMounted(() => {
35
- initObserver()
36
33
  })
37
34
  </script>
38
35
 
@@ -15,7 +15,7 @@ const scrollReveal: ObjectDirective = {
15
15
 
16
16
  const observer = new IntersectionObserver(
17
17
  ([entry]) => {
18
- if (entry.isIntersecting) {
18
+ if (entry && entry.isIntersecting) {
19
19
  setTimeout(() => {
20
20
  el.classList.remove('opacity-0', 'translate-y-8')
21
21
  el.classList.add('opacity-100', 'translate-y-0')
@@ -30,7 +30,7 @@ onMounted(() => {
30
30
  <Head>
31
31
  <Title>Edge Website - An awesome Edge website</Title>
32
32
  <Meta name="description" content="This is an Edge website template" />
33
- <Link rel="canonical" href="https://edgemarketingdesign.com/" />
33
+ <Link rel="canonical" href="https://edgemarketingdesign.com/contact" />
34
34
  </Head>
35
35
 
36
36
  <titleSection
@@ -8,7 +8,7 @@ onMounted(() => {
8
8
  <Head>
9
9
  <Title>Edge Website - An awesome Edge website</Title>
10
10
  <Meta name="description" content="This is an Edge website template" />
11
- <Link rel="canonical" href="https://edgemarketingdesign.com/" />
11
+ <Link rel="canonical" href="https://edgemarketingdesign.com/stuff" />
12
12
  </Head>
13
13
 
14
14
  <titleSection
package/nuxt.config.ts CHANGED
@@ -1,6 +1,10 @@
1
+ import process from 'node:process'
1
2
  import { defineNuxtConfig } from 'nuxt/config'
2
3
 
3
4
  export default defineNuxtConfig({
5
+ future: {
6
+ compatibilityVersion: 4,
7
+ },
4
8
  ssr: true,
5
9
  nitro: {
6
10
  preset: 'cloudflare-pages',
@@ -28,7 +32,7 @@ export default defineNuxtConfig({
28
32
  css: [
29
33
  '~/assets/css/global.css', // ✅ Keep global styles only
30
34
  ],
31
- modules: ['@nuxtjs/tailwindcss', '@vee-validate/nuxt'],
35
+ modules: ['@nuxtjs/tailwindcss', '@vee-validate/nuxt', 'nitro-cloudflare-dev'],
32
36
  vite: {
33
37
  define: {
34
38
  'process.env.DEBUG': false,
@@ -41,4 +45,12 @@ export default defineNuxtConfig({
41
45
  },
42
46
  },
43
47
  devtools: { enabled: false },
48
+ runtimeConfig: {
49
+ // These values are only available on the server
50
+ cfAccountId: process.env.NUXT_CF_ACCOUNT_ID,
51
+ cfKVNamespaceId: process.env.NUXT_CF_KV_NAMESPACE_ID,
52
+ cfApiToken: process.env.NUXT_CF_API_TOKEN,
53
+
54
+ public: {}, // nothing here unless you want it client-exposed
55
+ },
44
56
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/create-edge-site",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Create Edge Starter Site",
5
5
  "bin": {
6
6
  "create-edge-site": "./bin/cli.js"
@@ -31,6 +31,7 @@
31
31
  "devDependencies": {
32
32
  "@antfu/eslint-config": "^4.11.0",
33
33
  "eslint": "^9",
34
+ "nitro-cloudflare-dev": "^0.2.2",
34
35
  "wrangler": "^4.14.4"
35
36
  }
36
37
  }
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs/promises'
2
2
  import path from 'node:path'
3
3
 
4
- const rootFolder = 'public/images'
4
+ const rootFolder = '../public/images'
5
5
  const output = {}
6
6
 
7
7
  async function scanFolder(dirPath) {
@@ -1,3 +1,3 @@
1
1
  export default defineEventHandler(() => {
2
- return { message: "Hello from World" };
3
- });
2
+ return { message: 'Hello from World' }
3
+ })
@@ -1,3 +1,5 @@
1
+ import { readFile } from 'fs/promises'
2
+ import { join } from 'path'
1
3
  export default defineEventHandler(async (event) => {
2
4
  const rawParam = event.context.params?.path;
3
5
  const pathSegments = Array.isArray(rawParam)
@@ -9,8 +11,9 @@ export default defineEventHandler(async (event) => {
9
11
  const requestedPath = pathSegments.join('/');
10
12
 
11
13
  try {
12
- const manifestModule = await import('~/public/images/image-manifest.json');
13
- const manifest = manifestModule.default;
14
+ const manifestPath = join(process.cwd(), 'public/images/image-manifest.json');
15
+ const raw = await readFile(manifestPath, 'utf-8');
16
+ const manifest = JSON.parse(raw);
14
17
 
15
18
  if (!manifest || typeof manifest !== 'object') {
16
19
  return sendError(event, createError({
@@ -1,7 +1,11 @@
1
+ import { readFile } from 'fs/promises'
2
+ import { join } from 'path'
3
+
1
4
  export default defineEventHandler(async (event) => {
2
5
  try {
3
- const manifestModule = await import('~/public/images/image-manifest.json');
4
- const manifest = manifestModule.default;
6
+ const manifestPath = join(process.cwd(), 'public/images/image-manifest.json');
7
+ const raw = await readFile(manifestPath, 'utf-8');
8
+ const manifest = JSON.parse(raw);
5
9
 
6
10
  return { images: manifest };
7
11
  } catch (err) {
@@ -0,0 +1,17 @@
1
+ import { getKVValue } from '../../../server/utils/getKV'
2
+
3
+ export default defineEventHandler(async (event) => {
4
+ const { key } = getRouterParams(event)
5
+
6
+ const context = event.context
7
+ const value = await getKVValue(key, context)
8
+
9
+
10
+ if (!value) {
11
+ return sendError(event, createError({ statusCode: 404, statusMessage: 'Not found'}))
12
+ }
13
+
14
+ const jsonValue = JSON.parse(value)
15
+
16
+ return jsonValue
17
+ })
@@ -0,0 +1,33 @@
1
+ export default defineEventHandler(async (event) => {
2
+ const host =
3
+ event.node?.req?.headers?.host ||
4
+ event.req?.headers?.['host'] ||
5
+ 'localhost'
6
+
7
+ const protocol = host.startsWith('localhost') ? 'http' : 'https'
8
+ const baseURL = `${protocol}://${host.replace(/^www\./, '')}`
9
+
10
+ // Your routes here
11
+ const routes = [
12
+ '', // homepage
13
+ 'stuff',
14
+ 'contact',
15
+ ]
16
+
17
+ const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
18
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
19
+ ${routes
20
+ .map(
21
+ (path) => `
22
+ <url>
23
+ <loc>${baseURL}/${path}</loc>
24
+ <changefreq>monthly</changefreq>
25
+ <priority>0.7</priority>
26
+ </url>`
27
+ )
28
+ .join('')}
29
+ </urlset>`
30
+
31
+ event.node.res.setHeader('Content-Type', 'application/xml')
32
+ return sitemap
33
+ })
@@ -0,0 +1,65 @@
1
+ import { useRuntimeConfig } from '#imports'
2
+
3
+ export async function getKVValue(key, context) {
4
+ const config = useRuntimeConfig()
5
+ const isDev = import.meta.dev
6
+ const MY_KV = context?.cloudflare?.env?.MY_KV
7
+
8
+ const fetchFromAPI = async () => {
9
+ const { cfAccountId, cfKVNamespaceId, cfApiToken } = config
10
+ const url = `https://api.cloudflare.com/client/v4/accounts/${cfAccountId}/storage/kv/namespaces/${cfKVNamespaceId}/values/${key}`
11
+ const res = await fetch(url, {
12
+ headers: {
13
+ Authorization: `Bearer ${cfApiToken}`,
14
+ },
15
+ })
16
+ if (!res.ok) {
17
+ console.warn('❌ Remote fetch failed')
18
+ return null
19
+ }
20
+ return await res.text()
21
+ }
22
+
23
+ // Dev only: sync from API to local KV
24
+ if (isDev && typeof MY_KV !== 'undefined') {
25
+ console.log('🛠 Dev mode – syncing from API to local KV')
26
+ const remoteValue = await fetchFromAPI()
27
+ if (remoteValue !== null) {
28
+ try {
29
+ await MY_KV.put(key, remoteValue)
30
+ console.log('📥 Synced to local KV')
31
+ }
32
+ catch (e) {
33
+ console.warn('⚠️ Failed to write to local KV:', e)
34
+ }
35
+ }
36
+ }
37
+
38
+ // Always try local KV first if available
39
+ if (typeof MY_KV !== 'undefined') {
40
+ const localValue = await MY_KV.get(key)
41
+ if (localValue !== null) {
42
+ console.log('✅ Retrieved from local KV')
43
+ return localValue
44
+ }
45
+
46
+ if (isDev) {
47
+ console.log('🔍 Not found in KV, trying API fallback (dev only)')
48
+ return await fetchFromAPI()
49
+ }
50
+ else {
51
+ console.warn('🚫 Not found in KV and API fallback is disabled in production')
52
+ return null
53
+ }
54
+ }
55
+
56
+ // No KV available
57
+ if (isDev) {
58
+ console.log('🌐 No KV available, trying API fallback (dev only)')
59
+ return await fetchFromAPI()
60
+ }
61
+ else {
62
+ console.warn('🚫 No KV and no API fallback in production')
63
+ return null
64
+ }
65
+ }
@@ -1,27 +1,27 @@
1
1
  /** @type {import('tailwindcss').Config} */
2
2
  export default {
3
- content: [
4
- "./components/**/*.{vue,js,ts}",
5
- "./layouts/**/*.{vue,js,ts}",
6
- "./pages/**/*.{vue,js,ts}",
7
- "./app.vue",
8
- ],
9
- theme: {
10
- extend: {
11
- colors: {
12
- dblue: "#30464C", // Dark Blue
13
- mblue: "#46616F", // Medium Blue
14
- lgray: "#A2A8AE", // Light Gray
15
- lblue: "#87B4B7", // Light Blue
16
- burntorange: "#B65B33", // Burnt Orange
17
- tan: "#BDA86A", // Tan
18
- cream: "#D9D0C4", // Cream
19
- },
20
- fontFamily: {
21
- sans: ["Overpass", "sans-serif"],
22
- serif: ["Rokkitt", "serif"],
23
- },
3
+ content: [
4
+ './app/components/**/*.{vue,js,ts}',
5
+ './app/layouts/**/*.{vue,js,ts}',
6
+ './app/pages/**/*.{vue,js,ts}',
7
+ './app/app.vue',
8
+ ],
9
+ theme: {
10
+ extend: {
11
+ colors: {
12
+ dblue: '#30464C', // Dark Blue
13
+ mblue: '#46616F', // Medium Blue
14
+ lgray: '#A2A8AE', // Light Gray
15
+ lblue: '#87B4B7', // Light Blue
16
+ burntorange: '#B65B33', // Burnt Orange
17
+ tan: '#BDA86A', // Tan
18
+ cream: '#D9D0C4', // Cream
19
+ },
20
+ fontFamily: {
21
+ sans: ['Overpass', 'sans-serif'],
22
+ serif: ['Rokkitt', 'serif'],
24
23
  },
25
24
  },
26
- plugins: [],
27
- };
25
+ },
26
+ plugins: [],
27
+ }
package/wrangler.toml ADDED
@@ -0,0 +1,3 @@
1
+ [[kv_namespaces]]
2
+ binding = "MY_KV"
3
+ id = "ce7ff0d3eb6f43ae84611b5d9e28b6f1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes