@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.
- package/{components → app/components}/edgeScrollRevealAnim.vue +5 -8
- package/{directives → app/directives}/scrollReveal.ts +1 -1
- package/{pages → app/pages}/contact.vue +1 -1
- package/{pages → app/pages}/stuff.vue +1 -1
- package/nuxt.config.ts +13 -1
- package/package.json +2 -1
- package/scripts/generateImageManifest.mjs +1 -1
- package/server/api/hello.ts +2 -2
- package/server/api/images/[...path].ts +5 -2
- package/server/api/images/index.ts +6 -2
- package/server/api/kv/[key].ts +17 -0
- package/server/routes/sitemap.xml.ts +33 -0
- package/server/utils/getKV.js +65 -0
- package/tailwind.config.js +23 -23
- package/wrangler.toml +3 -0
- /package/{app.vue → app/app.vue} +0 -0
- /package/{assets → app/assets}/css/global.css +0 -0
- /package/{components → app/components}/Input.vue +0 -0
- /package/{components → app/components}/Select.vue +0 -0
- /package/{components → app/components}/Textarea.vue +0 -0
- /package/{components → app/components}/edgeFooter.vue +0 -0
- /package/{components → app/components}/edgeFormFling.vue +0 -0
- /package/{components → app/components}/edgeGallery.vue +0 -0
- /package/{components → app/components}/edgeNavbar.vue +0 -0
- /package/{components → app/components}/edgeSwiper.vue +0 -0
- /package/{components → app/components}/titleSection.vue +0 -0
- /package/{pages → app/pages}/[...404].vue +0 -0
- /package/{pages → app/pages}/index.vue +0 -0
- /package/{plugins → app/plugins}/scrollReveal.ts +0 -0
- /package/{plugins → app/plugins}/vee-validate-rules.js +0 -0
- /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
|
-
|
|
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)
|
|
25
|
+
obs.unobserve(row)
|
|
25
26
|
}
|
|
26
27
|
})
|
|
27
28
|
}, {
|
|
28
|
-
threshold: 0.3,
|
|
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.
|
|
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
|
}
|
package/server/api/hello.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export default defineEventHandler(() => {
|
|
2
|
-
return { message:
|
|
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
|
|
13
|
-
const
|
|
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
|
|
4
|
-
const
|
|
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
|
+
}
|
package/tailwind.config.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
2
|
export default {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
27
|
-
|
|
25
|
+
},
|
|
26
|
+
plugins: [],
|
|
27
|
+
}
|
package/wrangler.toml
ADDED
/package/{app.vue → app/app.vue}
RENAMED
|
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
|
|
File without changes
|