@lightspeed/crane 3.2.1 → 3.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 +25 -0
- package/UPGRADE.md +25 -0
- package/dist/cli.mjs +57 -34
- package/package.json +11 -13
- package/template/collections/example-collection/configuration.ts +6 -5
- package/template/eslint.config.js +1 -0
- package/template/footers/example-footer/component/MadeWith.vue +24 -8
- package/template/layouts/catalog/example-catalog/client.ts +6 -0
- package/template/layouts/category/example-category/client.ts +6 -0
- package/template/layouts/category/example-category/settings/translations.ts +1 -0
- package/template/layouts/product/example-product/client.ts +6 -0
- package/template/layouts/product/example-product/settings/translations.ts +1 -0
- package/template/package.json +1 -1
- package/template/preview/shared/api-routes.ts +27 -4
- package/template/preview/shared/mock.ts +9 -0
- package/template/preview/shared/preview.ts +3 -0
- package/template/preview/vite.config.js +4 -0
- package/template/reference/sections/tag-lines/TagLines.vue +6 -6
- package/template/eslint.config.cjs +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightspeed/crane",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": "bin/crane.js",
|
|
6
6
|
"main": "./dist/app.mjs",
|
|
@@ -58,41 +58,39 @@
|
|
|
58
58
|
"mock-fs": "^5.5.0",
|
|
59
59
|
"ts-jest": "^29.4.0",
|
|
60
60
|
"ts-node": "^10.9.2",
|
|
61
|
-
"typescript": "5.9.
|
|
61
|
+
"typescript": "5.9.3",
|
|
62
62
|
"unbuild": "^3.5.0",
|
|
63
63
|
"vite-plugin-dts": "^4.5.4",
|
|
64
64
|
"vite-plugin-static-copy": "^3.1.0"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@jridgewell/sourcemap-codec": "^1.5.4",
|
|
68
|
-
"@lightspeed/crane-api": "2.
|
|
68
|
+
"@lightspeed/crane-api": "2.3.0",
|
|
69
69
|
"@lightspeed/eslint-config-crane": "1.1.3",
|
|
70
70
|
"@types/micromatch": "^4.0.8",
|
|
71
71
|
"@types/prompts": "^2.4.2",
|
|
72
72
|
"@types/ws": "^8.5.3",
|
|
73
73
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
74
74
|
"adm-zip": "^0.5.16",
|
|
75
|
-
"
|
|
76
|
-
"ajv-formats": "^3.0.1",
|
|
77
|
-
"axios": "^1.11.0",
|
|
75
|
+
"axios": "^1.14.0",
|
|
78
76
|
"axios-concurrency": "^1.0.4",
|
|
79
77
|
"cac": "^6.7.14",
|
|
80
78
|
"cli-progress": "^3.12.0",
|
|
81
79
|
"eslint": "^9.33.0",
|
|
82
80
|
"fs-extra": "^11.3.1",
|
|
83
|
-
"glob": "^
|
|
84
|
-
"jsonpath-plus": "^10.
|
|
81
|
+
"glob": "^13.0.6",
|
|
82
|
+
"jsonpath-plus": "^10.4.0",
|
|
85
83
|
"kolorist": "^1.8.0",
|
|
86
84
|
"prompts": "^2.4.2",
|
|
87
85
|
"semver": "^7.7.2",
|
|
88
86
|
"terser": "^5.44.0",
|
|
89
87
|
"tinycolor2": "^1.6.0",
|
|
90
|
-
"typescript": "5.9.
|
|
88
|
+
"typescript": "5.9.3",
|
|
91
89
|
"vite": "^7.1.4",
|
|
92
|
-
"vite-plugin-checker": "^0.
|
|
90
|
+
"vite-plugin-checker": "^0.12.0",
|
|
93
91
|
"vite-plugin-compression": "^0.5.1",
|
|
94
92
|
"vite-plugin-externals": "^0.6.2",
|
|
95
|
-
"vite-tsconfig-paths": "^
|
|
93
|
+
"vite-tsconfig-paths": "^6.1.1",
|
|
96
94
|
"vue": "^3.5.21",
|
|
97
95
|
"vue-tsc": "^3.0.6",
|
|
98
96
|
"ws": "^8.19.0"
|
|
@@ -102,10 +100,10 @@
|
|
|
102
100
|
},
|
|
103
101
|
"overrides": {
|
|
104
102
|
"axios-concurrency": {
|
|
105
|
-
"axios": "1.
|
|
103
|
+
"axios": "1.14.0"
|
|
106
104
|
},
|
|
107
105
|
"magic-string": "0.30.10",
|
|
108
|
-
"glob": "^
|
|
106
|
+
"glob": "^13.0.6",
|
|
109
107
|
"stylus": "^0.64.0"
|
|
110
108
|
}
|
|
111
109
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { collection, section } from '@lightspeed/crane-api';
|
|
2
|
+
|
|
3
|
+
export default collection.configuration({
|
|
2
4
|
metadata: {
|
|
3
5
|
name: 'Example Collection',
|
|
4
6
|
description: 'Example Collection with custom sections, headers, and footers',
|
|
@@ -11,11 +13,10 @@ export default {
|
|
|
11
13
|
},
|
|
12
14
|
},
|
|
13
15
|
sections: [
|
|
14
|
-
{
|
|
15
|
-
type: 'custom',
|
|
16
|
+
section.custom({
|
|
16
17
|
id: 'example-section',
|
|
17
18
|
showcase_id: '1',
|
|
18
19
|
category: 'COLLECTIONS',
|
|
19
|
-
},
|
|
20
|
+
}),
|
|
20
21
|
],
|
|
21
|
-
};
|
|
22
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@lightspeed/eslint-config-crane';
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<a :href="madeWith
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<div v-if="madeWith">
|
|
3
|
+
<a :href="madeWith.url" :target="madeWith.target">
|
|
4
|
+
<template v-if="isV2">
|
|
5
|
+
<span>{{ madeWith.poweredBy }}</span>
|
|
6
|
+
<span
|
|
7
|
+
v-if="madeWith.iconSvg"
|
|
8
|
+
v-html="madeWith.iconSvg"
|
|
9
|
+
/>
|
|
10
|
+
<img
|
|
11
|
+
v-else-if="madeWith.icon"
|
|
12
|
+
:src="madeWith.icon"
|
|
13
|
+
:alt="madeWith.poweredBy"
|
|
14
|
+
/>
|
|
15
|
+
<span v-if="madeWith.company">{{ madeWith.company }}</span>
|
|
16
|
+
</template>
|
|
17
|
+
<template v-else>
|
|
18
|
+
<span>{{ madeWith.poweredBy }} </span>
|
|
19
|
+
<span>
|
|
20
|
+
<img :src="madeWith.icon" alt="cart" />
|
|
21
|
+
</span>
|
|
22
|
+
<span>{{ madeWith.company }}</span>
|
|
23
|
+
</template>
|
|
9
24
|
</a>
|
|
10
25
|
</div>
|
|
11
26
|
</template>
|
|
@@ -16,7 +31,8 @@ import { Design } from '../type.ts';
|
|
|
16
31
|
|
|
17
32
|
const baseProps = useVueBaseProps<unknown, Design>();
|
|
18
33
|
const siteContent: SiteContent = baseProps.site?.value satisfies SiteContent;
|
|
19
|
-
const
|
|
34
|
+
const isV2 = !!siteContent.madeWithV2;
|
|
35
|
+
const madeWith = siteContent.madeWithV2 ?? siteContent.madeWith;
|
|
20
36
|
</script>
|
|
21
37
|
|
|
22
38
|
<style scoped>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {} as const;
|
package/template/package.json
CHANGED
|
@@ -16,6 +16,9 @@ import { debugLog } from './logger';
|
|
|
16
16
|
import { getShowcaseData, BlockType, BLOCK_TYPES } from './preview';
|
|
17
17
|
import { fetchTiles, updateTilesSection, updateCustomContent, getBlockType } from './utils';
|
|
18
18
|
|
|
19
|
+
/** Maximum allowed nesting depth for DECK settings */
|
|
20
|
+
const MAX_DECK_DEPTH = 2;
|
|
21
|
+
|
|
19
22
|
/**
|
|
20
23
|
* AppBlock type definition for block-config response
|
|
21
24
|
*/
|
|
@@ -206,9 +209,14 @@ function processEditorExceptDeck(setting: ContentEditor, fieldName: string) {
|
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
/**
|
|
209
|
-
* Process a DECK editor: transform cards.defaultCardContent.settings into editors array
|
|
212
|
+
* Process a DECK editor: transform cards.defaultCardContent.settings into editors array.
|
|
213
|
+
* Supports nested DECK up to MAX_DECK_DEPTH levels.
|
|
210
214
|
*/
|
|
211
|
-
function processDeckEditor(
|
|
215
|
+
function processDeckEditor(
|
|
216
|
+
editor: DeckContentEditor,
|
|
217
|
+
fieldName: string,
|
|
218
|
+
depth: number = 1,
|
|
219
|
+
): Record<string, unknown> {
|
|
212
220
|
const result: Record<string, unknown> = {
|
|
213
221
|
field: fieldName,
|
|
214
222
|
type: 'DECK_EDITOR',
|
|
@@ -228,8 +236,23 @@ function processDeckEditor(editor: DeckContentEditor, fieldName: string): Record
|
|
|
228
236
|
// Create editors array from settings and add to defaultCard
|
|
229
237
|
if (settings) {
|
|
230
238
|
const editors: Record<string, unknown>[] = [];
|
|
231
|
-
for (const [settingFieldName, settingEditor] of Object.entries(settings)) {
|
|
232
|
-
|
|
239
|
+
for (const [settingFieldName, settingEditor] of Object.entries(settings) as [string, ContentEditor][]) {
|
|
240
|
+
let processedEditor: Record<string, unknown>;
|
|
241
|
+
// Recursively process nested DECK editors, enforcing MAX_DECK_DEPTH
|
|
242
|
+
if (settingEditor.type === 'DECK') {
|
|
243
|
+
if (depth >= MAX_DECK_DEPTH) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Maximum DECK nesting depth of ${MAX_DECK_DEPTH} exceeded at field "${settingFieldName}".`,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
processedEditor = processDeckEditor(
|
|
249
|
+
settingEditor as DeckContentEditor,
|
|
250
|
+
settingFieldName,
|
|
251
|
+
depth + 1,
|
|
252
|
+
);
|
|
253
|
+
} else {
|
|
254
|
+
processedEditor = processEditorExceptDeck(settingEditor, settingFieldName);
|
|
255
|
+
}
|
|
233
256
|
editors.push(processedEditor);
|
|
234
257
|
}
|
|
235
258
|
defaultCard.editors = editors;
|
|
@@ -55,9 +55,18 @@ export const externalContentMock: ExternalContentMock = {
|
|
|
55
55
|
url: 'https://www.lightspeedhq.com',
|
|
56
56
|
target: '_blank',
|
|
57
57
|
icon: '/assets/lightspeed-icon.png',
|
|
58
|
+
iconSvg: undefined,
|
|
58
59
|
poweredBy: 'Powered by',
|
|
59
60
|
company: 'Lightspeed',
|
|
60
61
|
},
|
|
62
|
+
madeWithV2: {
|
|
63
|
+
url: 'https://www.lightspeedhq.com',
|
|
64
|
+
target: '_blank',
|
|
65
|
+
icon: undefined,
|
|
66
|
+
iconSvg: undefined,
|
|
67
|
+
poweredBy: 'Powered by Lightspeed',
|
|
68
|
+
company: undefined,
|
|
69
|
+
},
|
|
61
70
|
},
|
|
62
71
|
|
|
63
72
|
category: {
|
|
@@ -244,6 +244,9 @@ function parseAccordionDesign(comp: any): Record<string, any> {
|
|
|
244
244
|
Object.entries(comp.items || {}).forEach(([itemName, item]: [string, any]) => {
|
|
245
245
|
const editors: Record<string, any> = {};
|
|
246
246
|
Object.entries(item.editors || {}).forEach(([editorName, editor]: [string, any]) => {
|
|
247
|
+
if (editor?.type === 'DIVIDER' || editor?.type === 'INFO') {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
247
250
|
editors[editorName] = editor.defaults || {};
|
|
248
251
|
});
|
|
249
252
|
items[itemName] = { label: item.label, editors };
|
|
@@ -40,6 +40,10 @@ export default defineConfig({
|
|
|
40
40
|
fs.writeFileSync(analyticsFile, JSON.stringify({}, null, 2), 'utf-8');
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// Exclude analytics file from Vite's file watcher to prevent
|
|
44
|
+
// HMR triggers when bumpSectionCount writes to it.
|
|
45
|
+
server.watcher.unwatch(analyticsFile);
|
|
46
|
+
|
|
43
47
|
// helper to bump and persist counter for a given section
|
|
44
48
|
function bumpSectionCount(section) {
|
|
45
49
|
const raw = fs.readFileSync(analyticsFile, 'utf-8');
|
|
@@ -128,11 +128,11 @@ const {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
.tag-lines-section
|
|
131
|
+
.tag-lines-section :deep(.tag-lines-section__highlighted-texts:has(.tag-lines-section__highlighted-text:hover)) .tag-lines-section__highlighted-text {
|
|
132
132
|
opacity: 0.2;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
.tag-lines-section
|
|
135
|
+
.tag-lines-section :deep(.tag-lines-section__highlighted-texts:has(.tag-lines-section__highlighted-text:hover)) .tag-lines-section__highlighted-text:hover {
|
|
136
136
|
opacity: 1;
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -140,13 +140,13 @@ const {
|
|
|
140
140
|
transition: opacity ease-in-out 0.3s;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
.tag-lines-section:has(.tag-lines-section__highlighted-text:hover)
|
|
143
|
+
.tag-lines-section:has(.tag-lines-section__highlighted-text:hover) :deep(.section-image__element) {
|
|
144
144
|
opacity: 0;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
.tag-lines-section:has(.tag-lines-section__highlighted-text--1:hover)
|
|
148
|
-
.tag-lines-section:has(.tag-lines-section__highlighted-text--2:hover)
|
|
149
|
-
.tag-lines-section:has(.tag-lines-section__highlighted-text--3:hover)
|
|
147
|
+
.tag-lines-section:has(.tag-lines-section__highlighted-text--1:hover) :deep(.section-image__element--1),
|
|
148
|
+
.tag-lines-section:has(.tag-lines-section__highlighted-text--2:hover) :deep(.section-image__element--2),
|
|
149
|
+
.tag-lines-section:has(.tag-lines-section__highlighted-text--3:hover) :deep(.section-image__element--3) {
|
|
150
150
|
opacity: 1;
|
|
151
151
|
}
|
|
152
152
|
</style>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('@lightspeed/eslint-config-crane');
|