@lightspeed/crane 1.2.5 → 1.3.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.
- package/CHANGELOG.md +16 -0
- package/dist/app.d.mts +23 -10
- package/dist/app.d.ts +23 -10
- package/dist/app.mjs +1 -1
- package/dist/cli.mjs +7 -7
- package/package.json +13 -13
- package/template/layouts/catalog/example-catalog/Main.vue +1 -1
- package/template/layouts/catalog/example-catalog/assets/account-icon.svg +11 -0
- package/template/layouts/catalog/example-catalog/components/Icon.vue +52 -0
- package/template/layouts/catalog/example-catalog/settings/content.ts +1 -0
- package/template/layouts/catalog/example-catalog/settings/design.ts +1 -0
- package/template/layouts/catalog/example-catalog/settings/translations.ts +1 -0
- package/template/layouts/catalog/example-catalog/slots/custom-bottom-bar/CustomBottomBar.vue +69 -0
- package/template/layouts/catalog/example-catalog/slots/custom-bottom-bar/client.ts +5 -0
- package/template/layouts/catalog/example-catalog/slots/custom-bottom-bar/server.ts +5 -0
- package/template/layouts/catalog/example-catalog/type.ts +5 -0
- package/template/layouts/category/example-category/settings/content.ts +1 -0
- package/template/layouts/category/example-category/settings/design.ts +1 -0
- package/template/layouts/category/example-category/type.ts +5 -0
- package/template/layouts/product/example-product/settings/content.ts +1 -0
- package/template/layouts/product/example-product/settings/design.ts +1 -0
- package/template/layouts/product/example-product/type.ts +5 -0
- package/template/page-templates/example-template/pages/catalog.ts +5 -4
- package/template/page-templates/example-template/pages/category.ts +5 -4
- package/template/page-templates/example-template/pages/product.ts +5 -4
- package/template/preview/sections/preview.html +52 -4
- package/template/preview/shared/utils.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightspeed/crane",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": "bin/crane.js",
|
|
6
6
|
"main": "./dist/app.mjs",
|
|
@@ -36,29 +36,29 @@
|
|
|
36
36
|
},
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@jest/globals": "^
|
|
40
|
-
"@stylistic/eslint-plugin": "^
|
|
39
|
+
"@jest/globals": "^30.0.4",
|
|
40
|
+
"@stylistic/eslint-plugin": "^5.1.0",
|
|
41
41
|
"@types/adm-zip": "^0.5.7",
|
|
42
42
|
"@types/axios-concurrency": "^1.0.0",
|
|
43
43
|
"@types/cli-progress": "^3.11.6",
|
|
44
44
|
"@types/express-fileupload": "^1.5.0",
|
|
45
45
|
"@types/fs-extra": "^11.0.1",
|
|
46
|
-
"@types/jest": "^
|
|
46
|
+
"@types/jest": "^30.0.0",
|
|
47
47
|
"@types/mock-fs": "^4.13.4",
|
|
48
|
-
"@types/node": "^
|
|
48
|
+
"@types/node": "^24.0.10",
|
|
49
49
|
"@types/semver": "^7.5.8",
|
|
50
50
|
"@types/tinycolor2": "^1.4.6",
|
|
51
51
|
"dir-compare": "^5.0.0",
|
|
52
|
-
"express": "^
|
|
53
|
-
"express-fileupload": "^1.5.
|
|
54
|
-
"jest": "^
|
|
52
|
+
"express": "^5.1.0",
|
|
53
|
+
"express-fileupload": "^1.5.2",
|
|
54
|
+
"jest": "^30.0.4",
|
|
55
55
|
"mock-fs": "^5.5.0",
|
|
56
|
-
"ts-jest": "^29.
|
|
56
|
+
"ts-jest": "^29.4.0",
|
|
57
57
|
"ts-node": "^10.9.2",
|
|
58
58
|
"typescript": "5.4.5",
|
|
59
59
|
"unbuild": "^3.5.0",
|
|
60
|
-
"vite-plugin-dts": "^
|
|
61
|
-
"vite-plugin-static-copy": "^3.
|
|
60
|
+
"vite-plugin-dts": "^4.5.4",
|
|
61
|
+
"vite-plugin-static-copy": "^3.1.0"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"adm-zip": "^0.5.16",
|
|
69
69
|
"ajv": "^8.12.0",
|
|
70
70
|
"ajv-formats": "^2.1.1",
|
|
71
|
-
"axios": "^1.
|
|
71
|
+
"axios": "^1.11.0",
|
|
72
72
|
"axios-concurrency": "^1.0.4",
|
|
73
73
|
"cac": "^6.7.14",
|
|
74
74
|
"cli-progress": "^3.12.0",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"overrides": {
|
|
97
97
|
"axios-concurrency": {
|
|
98
|
-
"axios": "1.
|
|
98
|
+
"axios": "1.11.0"
|
|
99
99
|
},
|
|
100
100
|
"magic-string": "0.30.10",
|
|
101
101
|
"glob": "^9.3.5",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
width="24"
|
|
3
|
+
height="24"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
>
|
|
7
|
+
<path
|
|
8
|
+
d="M23.5 12.0037C23.5012 10.0898 23.0244 8.20585 22.1129 6.52281C21.2014 4.83976 19.884 3.41084 18.2802 2.36565C16.6764 1.32047 14.8369 0.692104 12.9287 0.537549C11.0204 0.382995 9.10378 0.707143 7.35258 1.48059C5.60138 2.25404 4.07105 3.45232 2.9004 4.96672C1.72975 6.48113 0.955821 8.26374 0.64882 10.1529C0.34182 12.042 0.511461 13.9779 1.14235 15.7848C1.77325 17.5918 2.84543 19.2128 4.26165 20.5006C4.28966 20.5338 4.32226 20.5629 4.35848 20.5869C6.46141 22.4631 9.18149 23.5 12.0001 23.5C14.8188 23.5 17.5388 22.463 19.6417 20.5867C19.6778 20.5628 19.7102 20.5338 19.7381 20.5007C20.9235 19.4252 21.8705 18.1135 22.5184 16.6501C23.1663 15.1867 23.5007 13.604 23.5 12.0037ZM1.42 12.0037C1.41878 10.2648 1.84643 8.55248 2.66509 7.01827C3.48375 5.48405 4.66817 4.17528 6.11348 3.20782C7.55879 2.24035 9.22042 1.64404 10.9512 1.47168C12.6821 1.29931 14.4287 1.55621 16.0365 2.21963C17.6444 2.88305 19.0638 3.93252 20.1691 5.27513C21.2744 6.61775 22.0316 8.21209 22.3735 9.91701C22.7155 11.6219 22.6317 13.3848 22.1295 15.0496C21.6274 16.7145 20.7224 18.2298 19.4947 19.4616C18.3528 17.55 16.5208 16.1493 14.3764 15.5482C15.373 15.0182 16.1638 14.1702 16.6228 13.1392C17.0819 12.1081 17.1828 10.9532 16.9096 9.85816C16.6364 8.76314 16.0047 7.79091 15.1151 7.09614C14.2254 6.40136 13.1289 6.02395 12 6.02395C10.8711 6.02395 9.77458 6.40136 8.88494 7.09614C7.9953 7.79091 7.36363 8.76314 7.09042 9.85816C6.8172 10.9532 6.91814 12.1081 7.37717 13.1392C7.8362 14.1702 8.62696 15.0182 9.62364 15.5482C7.4792 16.1493 5.64721 17.55 4.50533 19.4616C3.52633 18.4819 2.74996 17.3191 2.22057 16.0394C1.69119 14.7598 1.41915 13.3884 1.42 12.0037ZM12 15.2226C11.1812 15.2226 10.3808 14.9799 9.69994 14.5252C9.01912 14.0704 8.48848 13.424 8.17514 12.6678C7.86179 11.9115 7.77981 11.0794 7.93955 10.2765C8.09929 9.4737 8.49359 8.73626 9.07258 8.15745C9.65157 7.57864 10.3892 7.18447 11.1923 7.02478C11.9954 6.86509 12.8278 6.94705 13.5843 7.26029C14.3408 7.57354 14.9874 8.10401 15.4423 8.78461C15.8972 9.46522 16.14 10.2654 16.14 11.084C16.1388 12.1812 15.7022 13.2332 14.9261 14.0091C14.1499 14.785 13.0976 15.2214 12 15.2226ZM5.19947 20.0991C5.88217 18.8976 6.87116 17.8985 8.06574 17.2035C9.26032 16.5084 10.6178 16.1422 12 16.1422C13.3822 16.1422 14.7397 16.5084 15.9343 17.2035C17.1288 17.8985 18.1178 18.8976 18.8005 20.0991C16.897 21.7015 14.4885 22.5803 12 22.5803C9.51148 22.5803 7.10295 21.7015 5.19947 20.0991Z"
|
|
9
|
+
fill="currentColor"
|
|
10
|
+
/>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="icon" :class="iconClass">
|
|
3
|
+
<img :src="accountIcon" alt="account icon" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { computed } from 'vue';
|
|
9
|
+
import accountIcon from '../assets/account-icon.svg';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
size?: 'small' | 'medium' | 'large';
|
|
13
|
+
color?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
17
|
+
size: 'medium',
|
|
18
|
+
color: 'currentColor',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const iconClass = computed(() => ({
|
|
22
|
+
[`icon--${props.size}`]: true,
|
|
23
|
+
}));
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<style lang="scss" scoped>
|
|
27
|
+
.icon {
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
|
|
32
|
+
svg {
|
|
33
|
+
fill: v-bind(color);
|
|
34
|
+
transition: all 0.3s ease;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&--small svg {
|
|
38
|
+
width: 16px;
|
|
39
|
+
height: 16px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&--medium svg {
|
|
43
|
+
width: 24px;
|
|
44
|
+
height: 24px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&--large svg {
|
|
48
|
+
width: 32px;
|
|
49
|
+
height: 32px;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="custom-bottom-bar">
|
|
3
|
+
<button class="account-button" @click="goToAccount">
|
|
4
|
+
<Icon size="small" color="white" />
|
|
5
|
+
<span class="account-text">Go to Account</span>
|
|
6
|
+
</button>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import Icon from '../../components/Icon.vue';
|
|
12
|
+
|
|
13
|
+
const goToAccount = () => {
|
|
14
|
+
// eslint-disable-next-line
|
|
15
|
+
const storefrontApi = (window as any)?.Ecwid;
|
|
16
|
+
|
|
17
|
+
storefrontApi?.OnAPILoaded.add(() => {
|
|
18
|
+
storefrontApi?.openPage('account');
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<style lang="scss" scoped>
|
|
24
|
+
.custom-bottom-bar {
|
|
25
|
+
position: fixed;
|
|
26
|
+
bottom: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
right: 0;
|
|
29
|
+
padding: 16px;
|
|
30
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.1), transparent);
|
|
31
|
+
pointer-events: none;
|
|
32
|
+
z-index: 1000;
|
|
33
|
+
|
|
34
|
+
.account-button {
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: 8px;
|
|
38
|
+
background: #333;
|
|
39
|
+
color: white;
|
|
40
|
+
border: none;
|
|
41
|
+
padding: 12px 20px;
|
|
42
|
+
border-radius: 8px;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
font-weight: 500;
|
|
46
|
+
transition: all 0.3s ease;
|
|
47
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
48
|
+
margin: 0 auto;
|
|
49
|
+
pointer-events: auto;
|
|
50
|
+
min-width: 160px;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
|
|
53
|
+
&:hover {
|
|
54
|
+
background: #555;
|
|
55
|
+
transform: translateY(-2px);
|
|
56
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&:active {
|
|
60
|
+
transform: translateY(0);
|
|
61
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.account-text {
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { StorePageConfiguration } from '@lightspeed/crane';
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
sections: [
|
|
3
5
|
{
|
|
4
|
-
type: '
|
|
5
|
-
id: 'catalog',
|
|
6
|
-
layout_id: 'example-catalog',
|
|
6
|
+
type: 'store',
|
|
7
|
+
id: 'example-catalog',
|
|
7
8
|
},
|
|
8
9
|
],
|
|
9
|
-
};
|
|
10
|
+
} satisfies StorePageConfiguration;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { StorePageConfiguration } from '@lightspeed/crane';
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
sections: [
|
|
3
5
|
{
|
|
4
|
-
type: '
|
|
5
|
-
id: 'category',
|
|
6
|
-
layout_id: 'example-category',
|
|
6
|
+
type: 'store',
|
|
7
|
+
id: 'example-category',
|
|
7
8
|
},
|
|
8
9
|
],
|
|
9
|
-
};
|
|
10
|
+
} satisfies StorePageConfiguration;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { StorePageConfiguration } from '@lightspeed/crane';
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
sections: [
|
|
3
5
|
{
|
|
4
|
-
type: '
|
|
5
|
-
id: 'product',
|
|
6
|
-
layout_id: 'example-product',
|
|
6
|
+
type: 'store',
|
|
7
|
+
id: 'example-product',
|
|
7
8
|
},
|
|
8
9
|
],
|
|
9
|
-
};
|
|
10
|
+
} satisfies StorePageConfiguration;
|
|
@@ -74,14 +74,62 @@
|
|
|
74
74
|
select.appendChild(option);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// SessionStorage functions for activeShowcase
|
|
78
|
+
function saveActiveShowcase(showcaseValue) {
|
|
79
|
+
try {
|
|
80
|
+
sessionStorage.setItem('activeShowcaseId', showcaseValue);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.warn('Could not save showcase to sessionStorage:', e);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function loadActiveShowcase() {
|
|
87
|
+
try {
|
|
88
|
+
return sessionStorage.getItem('activeShowcaseId');
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.warn('Could not load showcase from sessionStorage:', e);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function clearActiveShowcase() {
|
|
96
|
+
try {
|
|
97
|
+
sessionStorage.removeItem('activeShowcaseId');
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.warn('Could not clear showcase from sessionStorage:', e);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
77
103
|
select.addEventListener('change', async (e) => {
|
|
78
|
-
const
|
|
104
|
+
const showcaseValue = e.target.value;
|
|
105
|
+
const [sectionName, showcaseId] = showcaseValue.split(':');
|
|
106
|
+
|
|
107
|
+
// Save the active showcase to sessionStorage
|
|
108
|
+
saveActiveShowcase(showcaseValue);
|
|
109
|
+
|
|
110
|
+
// Render the showcase
|
|
79
111
|
renderShowcase(sectionName, showcaseId);
|
|
80
112
|
});
|
|
81
113
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
114
|
+
// Restore saved showcase or render first available
|
|
115
|
+
const savedShowcase = loadActiveShowcase();
|
|
116
|
+
let initialShowcase = null;
|
|
117
|
+
|
|
118
|
+
if (savedShowcase && showCaseOptions.some(option => option.value === savedShowcase)) {
|
|
119
|
+
// Restore saved showcase if it still exists
|
|
120
|
+
initialShowcase = savedShowcase;
|
|
121
|
+
select.value = savedShowcase;
|
|
122
|
+
} else if (select.options.length > 0) {
|
|
123
|
+
// Fall back to first option if no saved state or saved showcase no longer exists
|
|
124
|
+
initialShowcase = select.options[0].value;
|
|
125
|
+
select.value = initialShowcase;
|
|
126
|
+
// Save the initial showcase
|
|
127
|
+
saveActiveShowcase(initialShowcase);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Render the initial showcase
|
|
131
|
+
if (initialShowcase) {
|
|
132
|
+
const [sectionName, showcaseId] = initialShowcase.split(':');
|
|
85
133
|
renderShowcase(sectionName, showcaseId);
|
|
86
134
|
}
|
|
87
135
|
</script>
|