@brightsideoy/kama 0.1.0-alpha.142 → 0.1.0-alpha.145
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/.wrangler/state/v3/cache/default/blobs/4de32ec3e619aa3f9acad3fb1a2528209381347d1cbb86e939e08724f5b35bc4000001a0b2b5b216 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/5f895e5810a26a6319bbadde9d751e5b10faae6e141db1c454c5f53b3e725591000001a0b2b624a4 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/74744186327d8aaf1c6078e50bc561135fd90690c96bd4b733035d0cb3fedb94000001a0b2b5be6b +0 -0
- package/.wrangler/state/v3/cache/default/blobs/79c1c81c1ddcd49f49eb27b9197ae0160c3a7981f308aee2ae972653de1b3668000001a0b2b60e76 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/7cd29a3bd95a88e7e896a4ae253758cd9e4bde78fc371077f3fef974cd11c64d000001a0b098ff88 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/7ecc4caad58c7ee119c02adb84132eaa691b9a171f932ab1c17e0f95c3fed2a8000001a0b2b5bf5e +0 -0
- package/.wrangler/state/v3/cache/default/blobs/81928c274111d2c3cbd3d7174136a2fdce83e267da8f8d0caf60d650396197f5000001a0b098de9d +0 -0
- package/.wrangler/state/v3/cache/default/blobs/8c3aa6f6625d7c0d682cb498e6715355aec1905909b04ead5e85adbca3989b19000001a0b098e4ac +0 -0
- package/.wrangler/state/v3/cache/default/blobs/97205d84c3e4399f6f51295e8381b21f2a8810cdaecc0ab13f2cadf712fae5f4000001a0b339609d +0 -0
- package/.wrangler/state/v3/cache/default/blobs/b48d02100b8f1a9520a209628a0778a0f9e0f4ce0643f8d59b3888bbd0f85fc2000001a0b2b63647 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/cf30c018e70dad1c6859277e4361da657b79adf34e60cb05885eb32951fbbafc000001a0b09b168f +0 -0
- package/.wrangler/state/v3/cache/default/blobs/d0d796d0fe4efd55f61e0c3b8d30170a89703669a52854687186a66304adbf8a000001a0b2b6244d +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/9f458c07675338a7426a7b81ac4fb1baf92d034efbcaaf4336379640ed744ded.sqlite +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/7cfce387cae19c0dfbb9cc4f2a9c353f60ca0a80fabd0b2e2837d152b58feaaa.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-shm +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-wal +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/1c7705701fba41f9a2683025d40393711daffc55d32172088a62d8999017e9c6000001a0b339607a +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/1ee266c53f586a4a57a1d21be291e34bb2e2236c15e43ae30497f6054290f01d000001a0b2b6248c +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/6db1f8204b6d125f0911b3e42022258cc7e1c37a95c2ce7f5c7f14da31d408ec000001a0b2b60e1f +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/97b86f251c5d30df5e1eab8662cab83f5f7c4583ad14fd2d5ea99f16fdcfd6ef000001a0b2b62482 +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/9ffe30cff37d40b366f64100a8f041c0a1e5aee78708ba90b9ef4ca6a6b2d883.sqlite +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-wal +0 -0
- package/README.md +16 -37
- package/bin/cli.js +190 -147
- package/definitions/_page.yaml +52 -0
- package/dist/assets/index-BSBvGvQz.css +1 -0
- package/dist/assets/index-RzfH6iq3.js +162 -0
- package/dist/dist-CZEgSuN0.js +8674 -0
- package/dist/index.html +2 -2
- package/dist/index.js +6856 -11229
- package/dist/schema-compiler.js +38 -0
- package/npm-test.sh +75 -0
- package/package.json +14 -10
- package/schema.sql +3 -2
- package/templates/astro-starter/src/components/blocks/ImageBlock.astro +20 -56
- package/templates/astro-starter/src/components/global/Header.astro +19 -12
- package/templates/astro-starter/src/components/ui/KamaImage.astro +49 -73
- package/templates/astro-starter/src/pages/[...slug].astro +16 -43
- package/templates/astro-starter/src/pages/media/[...path].ts +8 -1
- package/wrangler.json +22 -0
- package/dist/assets/index-Bv7fPRX7.css +0 -1
- package/dist/assets/index-SWBz-Fr1.js +0 -162
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fileURLToPath as e, pathToFileURL as t } from "node:url";
|
|
2
|
+
import { existsSync as n, mkdirSync as r, readFileSync as i, writeFileSync as a } from "node:fs";
|
|
3
|
+
import { dirname as o, join as s } from "node:path";
|
|
4
|
+
//#region scripts/schema-compiler.ts
|
|
5
|
+
var c = e(import.meta.url), l = o(c);
|
|
6
|
+
async function u() {
|
|
7
|
+
let e = process.cwd(), o = !1;
|
|
8
|
+
try {
|
|
9
|
+
JSON.parse(i(s(e, "package.json"), "utf-8")).name === "@brightsideoy/kama" && (o = !0);
|
|
10
|
+
} catch {}
|
|
11
|
+
let c;
|
|
12
|
+
if (o) {
|
|
13
|
+
let t = s(e, "server", "db");
|
|
14
|
+
n(t) || r(t, { recursive: !0 }), c = s(t, "bundled-definitions.js");
|
|
15
|
+
} else {
|
|
16
|
+
let t = s(e, "kama-worker");
|
|
17
|
+
n(t) || r(t, { recursive: !0 }), c = s(t, "bundled-definitions.js");
|
|
18
|
+
}
|
|
19
|
+
let u, d = s(l, "../server/schema/engine.ts"), f = s(l, "../dist/index.js");
|
|
20
|
+
if (n(d)) u = (await import(t(d).href)).compileDefinitions;
|
|
21
|
+
else if (n(f)) u = (await import(t(f).href)).compileDefinitions;
|
|
22
|
+
else try {
|
|
23
|
+
u = (await import("./dist-CZEgSuN0.js")).compileDefinitions;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
console.error("❌ Could not resolve Kama Schema Engine:", e), process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
u || (console.error("❌ compileDefinitions function missing from resolved module"), process.exit(1));
|
|
28
|
+
let p = u(), m = Object.keys(p?.nodes || {}).length, h = Object.keys(p?.blocks || {}).length, g = `// AUTO-GENERATED BUNDLE - DO NOT EDIT
|
|
29
|
+
const defs = ${JSON.stringify(p, null, 2)};
|
|
30
|
+
export const BUNDLED_DEFINITIONS = defs;
|
|
31
|
+
export default defs;
|
|
32
|
+
`;
|
|
33
|
+
a(c, g, "utf-8"), console.log(`✅ Schema securely compiled using engine.ts to ${c} (${m} nodes, ${h} blocks)`);
|
|
34
|
+
}
|
|
35
|
+
u().catch((e) => {
|
|
36
|
+
console.error("❌ Schema Compiler Runtime Error:", e), process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
//#endregion
|
package/npm-test.sh
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Exit immediately if any command fails
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
# Define absolute test directory path
|
|
7
|
+
TEST_DIR="$(cd .. && pwd)/npm-test"
|
|
8
|
+
|
|
9
|
+
echo "🧹 1. Nuking old test environment & caches..."
|
|
10
|
+
rm -rf "$TEST_DIR"
|
|
11
|
+
mkdir -p "$TEST_DIR"
|
|
12
|
+
rm -rf ~/.npm/_npx/
|
|
13
|
+
|
|
14
|
+
# 🎯 FIX 1: Nuke the global npm cache so npx doesn't silently use an old cached version of the tarball!
|
|
15
|
+
npm cache clean --force
|
|
16
|
+
|
|
17
|
+
# Ensure CLI binary permissions are intact
|
|
18
|
+
chmod +x bin/cli.js
|
|
19
|
+
|
|
20
|
+
echo "🔥 2. Building & packing KAMA package locally..."
|
|
21
|
+
npm run build --loglevel error
|
|
22
|
+
npm pack --loglevel error
|
|
23
|
+
|
|
24
|
+
# Find the newly created tarball
|
|
25
|
+
TARBALL=$(ls -1t *.tgz | head -n 1)
|
|
26
|
+
|
|
27
|
+
if [ -z "$TARBALL" ]; then
|
|
28
|
+
echo "❌ Error: Failed to find the packed .tgz file."
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
mv "$TARBALL" "$TEST_DIR/"
|
|
33
|
+
cd "$TEST_DIR"
|
|
34
|
+
|
|
35
|
+
echo "🚀 3. Initializing test workspace..."
|
|
36
|
+
echo "------------------------------------------------------"
|
|
37
|
+
npx --yes --package "$TEST_DIR/$TARBALL" kama init
|
|
38
|
+
echo "------------------------------------------------------"
|
|
39
|
+
|
|
40
|
+
# Detect workspace root
|
|
41
|
+
WORKSPACE_DIR="."
|
|
42
|
+
if [ ! -f "package.json" ]; then
|
|
43
|
+
WORKSPACE_DIR=$(find . -mindepth 2 -maxdepth 2 -name "package.json" | head -n 1 | xargs dirname)
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ ! -f "$WORKSPACE_DIR/package.json" ]; then
|
|
47
|
+
echo "❌ Could not find package.json. Aborting test."
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
cd "$WORKSPACE_DIR"
|
|
52
|
+
|
|
53
|
+
echo "📦 4. Installing workspace dependencies quietly..."
|
|
54
|
+
npm install --loglevel error
|
|
55
|
+
npm install "$TEST_DIR/$TARBALL" --save --loglevel error
|
|
56
|
+
|
|
57
|
+
if [ -d "kama-worker" ]; then
|
|
58
|
+
npm install "$TEST_DIR/$TARBALL" -w kama-worker --save --loglevel error
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# 🎯 FIX 2: You MUST inject the local tarball into the site too!
|
|
62
|
+
# Otherwise, Astro will download an old Kama package from the internet.
|
|
63
|
+
if [ -d "sites/kama-starter" ]; then
|
|
64
|
+
npm install "$TEST_DIR/$TARBALL" -w sites/kama-starter --save --loglevel error
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo ""
|
|
68
|
+
echo "======================================================"
|
|
69
|
+
echo "✨ KAMA ENVIRONMENT BOOTSTRAPPED SUCCESSFULLY!"
|
|
70
|
+
echo " - Backend Worker: http://localhost:8787"
|
|
71
|
+
echo " - Astro Site: http://localhost:4321"
|
|
72
|
+
echo "======================================================"
|
|
73
|
+
echo ""
|
|
74
|
+
|
|
75
|
+
npm run dev --loglevel error
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightsideoy/kama",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.145",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,15 +15,19 @@
|
|
|
15
15
|
"create-kama": "bin/cli.js"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"
|
|
18
|
+
"predev": "npm run bundle:definitions && npm run build:schema",
|
|
19
|
+
"dev": "npm run dev:local",
|
|
20
|
+
"dev:local": "concurrently \"vite\" \"KAMA_RUNTIME=node tsx server/dev.ts\"",
|
|
21
|
+
"dev:cf": "concurrently \"vite\" \"wrangler dev server/index.ts\"",
|
|
22
|
+
"bundle:definitions": "node bin/cli.js bundle",
|
|
23
|
+
"build:schema": "tsx scripts/build-schema.ts",
|
|
24
|
+
"build:seed": "tsx scripts/build-seed.ts",
|
|
19
25
|
"build:server": "vite build",
|
|
20
26
|
"build:ui": "vite build --config vite.config.ui.ts",
|
|
21
|
-
"build": "npm run build:schema && npm run build:server && npm run build:ui",
|
|
27
|
+
"build": "npm run bundle:definitions && npm run build:schema && npm run build:server && npm run build:ui",
|
|
22
28
|
"build:cms": "npm run build",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"prepack": "npm run build && chmod +x bin/cli.js",
|
|
26
|
-
"serve": "tsx server/dev.ts"
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"serve": "wrangler dev server/index.ts"
|
|
27
31
|
},
|
|
28
32
|
"publishConfig": {
|
|
29
33
|
"access": "public"
|
|
@@ -41,7 +45,6 @@
|
|
|
41
45
|
"@tiptap/pm": "^3.30.0",
|
|
42
46
|
"@tiptap/starter-kit": "^3.30.0",
|
|
43
47
|
"@tiptap/vue-3": "^3.30.0",
|
|
44
|
-
"better-sqlite3": "^13.0.3",
|
|
45
48
|
"drizzle-orm": "^0.45.2",
|
|
46
49
|
"hono": "^4.13.2",
|
|
47
50
|
"locale-codes": "^1.3.1",
|
|
@@ -56,7 +59,7 @@
|
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@iconify-json/heroicons": "^1.2.3",
|
|
58
61
|
"@iconify-json/lucide": "^1.2.123",
|
|
59
|
-
"@
|
|
62
|
+
"@libsql/client": "^0.14.0",
|
|
60
63
|
"@types/node": "^26.2.0",
|
|
61
64
|
"@types/sharp": "^0.31.1",
|
|
62
65
|
"@types/yaml": "^1.9.6",
|
|
@@ -67,6 +70,7 @@
|
|
|
67
70
|
"typescript": "~5.7.2",
|
|
68
71
|
"unplugin-icons": "^23.0.1",
|
|
69
72
|
"vite": "^8.2.1",
|
|
70
|
-
"vue-tsc": "^2.2.0"
|
|
73
|
+
"vue-tsc": "^2.2.0",
|
|
74
|
+
"wrangler": "^4.134.0"
|
|
71
75
|
}
|
|
72
76
|
}
|
package/schema.sql
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
-- Kama Core System Schema
|
|
1
|
+
-- Kama Core System Schema
|
|
2
|
+
-- Auto-generated from server/db/schema.ts
|
|
2
3
|
|
|
3
4
|
CREATE TABLE IF NOT EXISTS "content_schemas" (
|
|
4
5
|
id TEXT PRIMARY KEY,
|
|
@@ -197,7 +198,7 @@ CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId,
|
|
|
197
198
|
CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);
|
|
198
199
|
CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);
|
|
199
200
|
CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);
|
|
200
|
-
CREATE INDEX IF NOT EXISTS
|
|
201
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);
|
|
201
202
|
CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);
|
|
202
203
|
CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);
|
|
203
204
|
CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);
|
|
@@ -32,18 +32,15 @@ interface Props {
|
|
|
32
32
|
[key: string]: CropVariant | undefined;
|
|
33
33
|
};
|
|
34
34
|
};
|
|
35
|
-
|
|
36
35
|
image_meta?: {
|
|
37
36
|
cropCoordinates?: {
|
|
38
37
|
width?: number;
|
|
39
38
|
height?: number;
|
|
40
39
|
};
|
|
41
40
|
};
|
|
42
|
-
|
|
43
41
|
width?: number | string;
|
|
44
42
|
height?: number | string;
|
|
45
43
|
};
|
|
46
|
-
|
|
47
44
|
region?: string;
|
|
48
45
|
isFirst?: boolean;
|
|
49
46
|
}
|
|
@@ -51,44 +48,22 @@ interface Props {
|
|
|
51
48
|
const { data, region = "main", isFirst = false } = Astro.props;
|
|
52
49
|
|
|
53
50
|
const img = data?.image;
|
|
51
|
+
const isValid = Boolean(img && (img.url || img.path || img.variants));
|
|
54
52
|
|
|
55
|
-
if (!img || (!img.url && !img.path && !img.variants)) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Determine whether this is likely to be LCP.
|
|
61
|
-
*/
|
|
62
53
|
const isLcp = region === "header" || (region === "main" && isFirst);
|
|
63
54
|
|
|
64
|
-
/**
|
|
65
|
-
* Determine grid column count from the region name.
|
|
66
|
-
*/
|
|
67
55
|
let columnCount = 1;
|
|
68
|
-
|
|
69
56
|
if (region.includes("_")) {
|
|
70
57
|
columnCount = 2;
|
|
71
|
-
|
|
72
|
-
if (region.includes("
|
|
73
|
-
columnCount = 3;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (region.includes("_col4")) {
|
|
77
|
-
columnCount = 4;
|
|
78
|
-
}
|
|
58
|
+
if (region.includes("_middle") || region.includes("_col3")) columnCount = 3;
|
|
59
|
+
if (region.includes("_col4")) columnCount = 4;
|
|
79
60
|
}
|
|
80
61
|
|
|
81
|
-
/**
|
|
82
|
-
* Default single-column layout.
|
|
83
|
-
*/
|
|
84
62
|
let maxWidth = "1352";
|
|
85
63
|
let targetColumnWidth = 1352;
|
|
86
64
|
let optimizedWidths = [768, 1352];
|
|
87
65
|
let sizes = "(max-width: 1399px) calc(100vw - 48px), 1352px";
|
|
88
66
|
|
|
89
|
-
/**
|
|
90
|
-
* Two-column layout.
|
|
91
|
-
*/
|
|
92
67
|
if (columnCount === 2) {
|
|
93
68
|
maxWidth = "660";
|
|
94
69
|
targetColumnWidth = 660;
|
|
@@ -97,12 +72,7 @@ if (columnCount === 2) {
|
|
|
97
72
|
"(max-width: 767px) calc(100vw - 48px), " +
|
|
98
73
|
"(max-width: 1399px) calc((100vw - 80px) / 2), " +
|
|
99
74
|
"660px";
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Three-column layout.
|
|
104
|
-
*/
|
|
105
|
-
else if (columnCount === 3) {
|
|
75
|
+
} else if (columnCount === 3) {
|
|
106
76
|
maxWidth = "429";
|
|
107
77
|
targetColumnWidth = 429;
|
|
108
78
|
optimizedWidths = [300, 429];
|
|
@@ -110,12 +80,7 @@ else if (columnCount === 3) {
|
|
|
110
80
|
"(max-width: 767px) calc(100vw - 48px), " +
|
|
111
81
|
"(max-width: 1399px) calc((100vw - 112px) / 3), " +
|
|
112
82
|
"429px";
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Four-column layout.
|
|
117
|
-
*/
|
|
118
|
-
else if (columnCount === 4) {
|
|
83
|
+
} else if (columnCount === 4) {
|
|
119
84
|
maxWidth = "314";
|
|
120
85
|
targetColumnWidth = 314;
|
|
121
86
|
optimizedWidths = [264, 314];
|
|
@@ -126,22 +91,21 @@ else if (columnCount === 4) {
|
|
|
126
91
|
}
|
|
127
92
|
---
|
|
128
93
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
image={
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</div>
|
|
94
|
+
{
|
|
95
|
+
isValid && (
|
|
96
|
+
<div class="cms-block cms-block-image" style={`--max-w: ${maxWidth}px;`}>
|
|
97
|
+
<KamaImage
|
|
98
|
+
image={img}
|
|
99
|
+
sizes={sizes}
|
|
100
|
+
desktopWidths={optimizedWidths}
|
|
101
|
+
idealWidth={targetColumnWidth}
|
|
102
|
+
class="free-crop-image"
|
|
103
|
+
loading={isLcp ? "eager" : "lazy"}
|
|
104
|
+
fetchpriority={isLcp ? "high" : "auto"}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
145
109
|
|
|
146
110
|
<style>
|
|
147
111
|
.cms-block-image {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
// src/components/global/Header.astro
|
|
2
|
+
// templates/astro-starter/src/components/global/Header.astro
|
|
3
3
|
import NavigationMenu from "@/components/global/NavigationMenu.astro";
|
|
4
4
|
import { getTree, getTreeId, getChannelId } from "@/lib/cms";
|
|
5
5
|
import type { TreeNode } from "@/lib/cms";
|
|
@@ -9,12 +9,12 @@ interface Props {
|
|
|
9
9
|
tree?: TreeNode[];
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
let rawTree = tree || [];
|
|
12
|
+
const props = Astro.props as Props;
|
|
13
|
+
const currentPropsNode = props.node || {};
|
|
14
|
+
let rawTree: TreeNode[] = props.tree || [];
|
|
15
15
|
|
|
16
16
|
// Fallback: If the layout didn't pass the tree, fetch it directly
|
|
17
|
-
if (rawTree.length === 0) {
|
|
17
|
+
if (!rawTree || rawTree.length === 0) {
|
|
18
18
|
const locals = Astro.locals as Record<string, any>;
|
|
19
19
|
const runtimeEnv = locals?.runtime?.env || {};
|
|
20
20
|
const cmsWorker = runtimeEnv.CMS_WORKER;
|
|
@@ -27,17 +27,24 @@ if (rawTree.length === 0) {
|
|
|
27
27
|
return fetch(input, init);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
try {
|
|
31
|
+
rawTree = await getTree(getTreeId(), getChannelId(), customFetch);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
rawTree = [];
|
|
34
|
+
}
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
const homeSlug = import.meta.env.PUBLIC_HOME_SLUG || "home";
|
|
34
|
-
const homeNodeInTree =
|
|
38
|
+
const homeNodeInTree =
|
|
39
|
+
rawTree.find(n => n.slug === homeSlug) || rawTree[0] || {};
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
homeNodeInTree
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
let siteName = currentPropsNode.logoText;
|
|
42
|
+
if (!siteName && homeNodeInTree && "logoText" in homeNodeInTree) {
|
|
43
|
+
siteName = homeNodeInTree.logoText as string;
|
|
44
|
+
}
|
|
45
|
+
if (!siteName) {
|
|
46
|
+
siteName = import.meta.env.PUBLIC_SITE_NAME || "KAMA";
|
|
47
|
+
}
|
|
41
48
|
---
|
|
42
49
|
|
|
43
50
|
<header class="site-header">
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
// src/components/ui/KamaImage.astro
|
|
3
|
-
|
|
4
3
|
import { getMediaUrl } from "@/lib/cms";
|
|
5
|
-
// 🎯 FIX: Updated import path to match our new folder structure
|
|
6
4
|
import { buildAgnosticImageUrl } from "@/lib/media/media-url";
|
|
7
5
|
|
|
8
6
|
interface Props {
|
|
@@ -25,25 +23,18 @@ const {
|
|
|
25
23
|
fetchpriority = "auto",
|
|
26
24
|
} = Astro.props;
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const isValidImage = Boolean(
|
|
27
|
+
image && (image.url || image.path || image.variants),
|
|
28
|
+
);
|
|
31
29
|
|
|
32
|
-
const variants = image
|
|
30
|
+
const variants = image?.variants || {};
|
|
33
31
|
|
|
34
|
-
/**
|
|
35
|
-
* Resolve CMS media URLs.
|
|
36
|
-
*/
|
|
37
32
|
const rawMobileUrl = getMediaUrl(variants.mobile?.url);
|
|
38
33
|
const rawTabletUrl = getMediaUrl(variants.tablet?.url);
|
|
39
34
|
const rawDesktopUrl = getMediaUrl(
|
|
40
|
-
variants.standard?.url || image
|
|
35
|
+
variants.standard?.url || image?.url || image?.path,
|
|
41
36
|
);
|
|
42
37
|
|
|
43
|
-
/**
|
|
44
|
-
* Resolve dimensions.
|
|
45
|
-
* Crop dimensions take precedence over original image dimensions.
|
|
46
|
-
*/
|
|
47
38
|
const mobileW = Number(variants.mobile?.cropCoordinates?.width || 768);
|
|
48
39
|
const mobileH = Number(variants.mobile?.cropCoordinates?.height || 576);
|
|
49
40
|
|
|
@@ -51,32 +42,25 @@ const tabletW = Number(variants.tablet?.cropCoordinates?.width || 1024);
|
|
|
51
42
|
const tabletH = Number(variants.tablet?.cropCoordinates?.height || 512);
|
|
52
43
|
|
|
53
44
|
const baseWidth = Number(
|
|
54
|
-
variants.standard?.cropCoordinates?.width || image
|
|
45
|
+
variants.standard?.cropCoordinates?.width || image?.width || idealWidth,
|
|
55
46
|
);
|
|
56
47
|
const baseHeight = Number(
|
|
57
48
|
variants.standard?.cropCoordinates?.height ||
|
|
58
|
-
image
|
|
49
|
+
image?.height ||
|
|
59
50
|
Math.round(idealWidth * 0.5),
|
|
60
51
|
);
|
|
61
52
|
|
|
62
|
-
/**
|
|
63
|
-
* Build responsive srcset using query-based media proxy URLs (/media/foo.jpg?w=768&q=75&f=auto)
|
|
64
|
-
*/
|
|
65
53
|
function buildAgnosticSrcset(
|
|
66
54
|
url: string,
|
|
67
55
|
targetWidths: number[],
|
|
68
56
|
quality = 75,
|
|
69
57
|
): string {
|
|
70
58
|
if (!url) return "";
|
|
71
|
-
|
|
72
59
|
return targetWidths
|
|
73
60
|
.map(width => `${buildAgnosticImageUrl(url, width, quality)} ${width}w`)
|
|
74
61
|
.join(", ");
|
|
75
62
|
}
|
|
76
63
|
|
|
77
|
-
/**
|
|
78
|
-
* Build srcsets.
|
|
79
|
-
*/
|
|
80
64
|
const mobileSrcset = rawMobileUrl
|
|
81
65
|
? buildAgnosticSrcset(rawMobileUrl, [400, 768])
|
|
82
66
|
: null;
|
|
@@ -89,61 +73,53 @@ const desktopSrcset = rawDesktopUrl
|
|
|
89
73
|
? buildAgnosticSrcset(rawDesktopUrl, desktopWidths)
|
|
90
74
|
: null;
|
|
91
75
|
|
|
92
|
-
/**
|
|
93
|
-
* Fallback image URL: /media/foo.jpg?w=1352&q=75&f=auto
|
|
94
|
-
*/
|
|
95
76
|
const absoluteFallback = rawDesktopUrl
|
|
96
77
|
? buildAgnosticImageUrl(rawDesktopUrl, idealWidth, 75)
|
|
97
78
|
: "";
|
|
98
79
|
---
|
|
99
80
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
81
|
+
{
|
|
82
|
+
isValidImage && (
|
|
83
|
+
<picture>
|
|
84
|
+
{Boolean(mobileSrcset) && (
|
|
85
|
+
<source
|
|
86
|
+
media="(max-width: 767px)"
|
|
87
|
+
srcset={mobileSrcset as string}
|
|
88
|
+
sizes="(max-width: 767px) calc(100vw - 48px), 768px"
|
|
89
|
+
width={mobileW}
|
|
90
|
+
height={mobileH}
|
|
91
|
+
/>
|
|
92
|
+
)}
|
|
93
|
+
|
|
94
|
+
{Boolean(tabletSrcset) && (
|
|
95
|
+
<source
|
|
96
|
+
media="(min-width: 768px) and (max-width: 1024px)"
|
|
97
|
+
srcset={tabletSrcset as string}
|
|
98
|
+
sizes="(max-width: 1024px) calc(100vw - 48px), 1024px"
|
|
99
|
+
width={tabletW}
|
|
100
|
+
height={tabletH}
|
|
101
|
+
/>
|
|
102
|
+
)}
|
|
103
|
+
|
|
104
|
+
{Boolean(desktopSrcset) && (
|
|
105
|
+
<source
|
|
106
|
+
srcset={desktopSrcset as string}
|
|
107
|
+
sizes={sizes}
|
|
108
|
+
width={baseWidth}
|
|
109
|
+
height={baseHeight}
|
|
110
|
+
/>
|
|
111
|
+
)}
|
|
112
|
+
|
|
113
|
+
<img
|
|
114
|
+
src={absoluteFallback}
|
|
115
|
+
alt={image.alt || image.filename || ""}
|
|
133
116
|
width={baseWidth}
|
|
134
117
|
height={baseHeight}
|
|
118
|
+
loading={loading}
|
|
119
|
+
fetchpriority={fetchpriority}
|
|
120
|
+
decoding={loading === "eager" ? "sync" : "async"}
|
|
121
|
+
class={className}
|
|
135
122
|
/>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
<img
|
|
140
|
-
src={absoluteFallback}
|
|
141
|
-
alt={image.alt || image.filename || ""}
|
|
142
|
-
width={baseWidth}
|
|
143
|
-
height={baseHeight}
|
|
144
|
-
loading={loading}
|
|
145
|
-
fetchpriority={fetchpriority}
|
|
146
|
-
decoding={loading === "eager" ? "sync" : "async"}
|
|
147
|
-
class={className}
|
|
148
|
-
/>
|
|
149
|
-
</picture>
|
|
123
|
+
</picture>
|
|
124
|
+
)
|
|
125
|
+
}
|