@crombolo/cli 0.0.0-stage → 0.9.1

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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +69 -0
  3. package/bin/crombolo.ts +2108 -0
  4. package/package.json +42 -4
  5. package/src/index.ts +7 -0
  6. package/src/operations/commands.ts +775 -0
  7. package/src/operations/sections.ts +423 -0
  8. package/src/templates.ts +309 -0
  9. package/templates/basic/bundle/bundle.json +45 -0
  10. package/templates/basic/bundle/nodes/36955f6e-d110-469e-b280-72096eccd148.json +38 -0
  11. package/templates/basic/files/components/homePage.tsx +22 -0
  12. package/templates/basic/files/schema/content-types/home-page.toml +28 -0
  13. package/templates/basic/files/schema/schema.toml +2 -0
  14. package/templates/basic/template.json +4 -0
  15. package/templates/demo/harbourstone/CREDITS.md +42 -0
  16. package/templates/demo/harbourstone/bundle/blobs/180cc8ef/distillery-from-the-cliff-path.jpg +0 -0
  17. package/templates/demo/harbourstone/bundle/blobs/68c9cfdf/bottle-brine-and-kiln.jpg +0 -0
  18. package/templates/demo/harbourstone/bundle/blobs/6be45535/bottle-oloroso-pier.jpg +0 -0
  19. package/templates/demo/harbourstone/bundle/blobs/6d8d6398/bottle-the-cove.jpg +0 -0
  20. package/templates/demo/harbourstone/bundle/blobs/7b4713f8/copper-pot-stills.jpg +0 -0
  21. package/templates/demo/harbourstone/bundle/blobs/c114b7d8/bottle-neap-tide.jpg +0 -0
  22. package/templates/demo/harbourstone/bundle/blobs/fd337567/casks-in-the-sea-facing-warehouse.jpg +0 -0
  23. package/templates/demo/harbourstone/bundle/bundle.json +197 -0
  24. package/templates/demo/harbourstone/bundle/nodes/069cc3c5-c9f5-4792-90c9-e2bfcc4855b6.json +35 -0
  25. package/templates/demo/harbourstone/bundle/nodes/13788fe7-1a45-4b48-8ae4-f4227e154e1e.json +35 -0
  26. package/templates/demo/harbourstone/bundle/nodes/180cc8ef-caf1-4316-b6a7-e3b5aee41ffd.json +60 -0
  27. package/templates/demo/harbourstone/bundle/nodes/22144db2-e214-4006-a0bb-53b5bd121fd6.json +35 -0
  28. package/templates/demo/harbourstone/bundle/nodes/26e87610-e2d6-4b47-bf92-3967f7186907.json +35 -0
  29. package/templates/demo/harbourstone/bundle/nodes/2caa099b-3884-472d-9cea-797a0f0c376f.json +35 -0
  30. package/templates/demo/harbourstone/bundle/nodes/2efbdb5b-7888-4a49-bca5-c0f85b76e472.json +42 -0
  31. package/templates/demo/harbourstone/bundle/nodes/2fe03891-1294-4344-8e24-47e8b212e5b0.json +35 -0
  32. package/templates/demo/harbourstone/bundle/nodes/38b009f7-03c0-4fda-b5c7-843ad6044e9c.json +35 -0
  33. package/templates/demo/harbourstone/bundle/nodes/3d312cc8-2937-40e1-ba14-fd781c9a862d.json +95 -0
  34. package/templates/demo/harbourstone/bundle/nodes/3dc30fc1-973a-4217-b26f-24902210be17.json +35 -0
  35. package/templates/demo/harbourstone/bundle/nodes/40107d59-f3e9-4592-aee8-5b03d4586cbd.json +101 -0
  36. package/templates/demo/harbourstone/bundle/nodes/483a0d3b-a10c-4c9d-8c81-d9607d37e968.json +35 -0
  37. package/templates/demo/harbourstone/bundle/nodes/4b760c0b-b83a-4eee-aa29-c225cfabf19b.json +35 -0
  38. package/templates/demo/harbourstone/bundle/nodes/4e5c7f3f-54cb-4328-ad61-bc4c2736b890.json +35 -0
  39. package/templates/demo/harbourstone/bundle/nodes/62f479ff-0875-453e-99ae-3bf1bec5e3c8.json +35 -0
  40. package/templates/demo/harbourstone/bundle/nodes/68c9cfdf-6b40-47da-a1d2-17256a6cc6db.json +60 -0
  41. package/templates/demo/harbourstone/bundle/nodes/6ad8f0f3-9334-47f1-b805-80c4b4b4fa88.json +101 -0
  42. package/templates/demo/harbourstone/bundle/nodes/6be45535-83e5-4469-acf0-4127016721ae.json +60 -0
  43. package/templates/demo/harbourstone/bundle/nodes/6d8d6398-738f-4f38-ad3c-e5d6e9a971fe.json +60 -0
  44. package/templates/demo/harbourstone/bundle/nodes/7b4713f8-d917-457d-a9d8-7dd01a3617b4.json +60 -0
  45. package/templates/demo/harbourstone/bundle/nodes/88ec1185-53b5-439a-a2ce-3f56603be4ff.json +35 -0
  46. package/templates/demo/harbourstone/bundle/nodes/97469df2-107c-4010-8c14-4de88f735529.json +35 -0
  47. package/templates/demo/harbourstone/bundle/nodes/a2eb439f-71d9-4ea6-89d7-c5bc72618281.json +35 -0
  48. package/templates/demo/harbourstone/bundle/nodes/a562f0a2-cb6e-4ead-a1ce-4d180632419f.json +101 -0
  49. package/templates/demo/harbourstone/bundle/nodes/a5e36a18-a2ef-4eb5-85b4-7e12b21cca06.json +35 -0
  50. package/templates/demo/harbourstone/bundle/nodes/b1876d3a-50a7-4358-84bf-a0899932ffa9.json +35 -0
  51. package/templates/demo/harbourstone/bundle/nodes/b4e38bbd-c1a3-431a-b7a9-5868aa32993a.json +35 -0
  52. package/templates/demo/harbourstone/bundle/nodes/c114b7d8-0138-404b-9d8f-a39d992577a2.json +60 -0
  53. package/templates/demo/harbourstone/bundle/nodes/cb4c569e-c28a-43b6-a4d7-d33bb544e973.json +136 -0
  54. package/templates/demo/harbourstone/bundle/nodes/cd681b4b-9c4e-4624-9c13-450aa6a9c135.json +101 -0
  55. package/templates/demo/harbourstone/bundle/nodes/d60ef12b-0f0a-4db5-9763-21fa52b8d4da.json +150 -0
  56. package/templates/demo/harbourstone/bundle/nodes/d7f13222-d060-4496-b86d-bef21da963c1.json +35 -0
  57. package/templates/demo/harbourstone/bundle/nodes/f36dd4a9-927c-4ca3-a790-c9c859ac7302.json +35 -0
  58. package/templates/demo/harbourstone/bundle/nodes/fd337567-df67-41ca-ae94-9d84d8d6042f.json +60 -0
  59. package/templates/demo/harbourstone/files/components/pages/contactPage.tsx +36 -0
  60. package/templates/demo/harbourstone/files/components/pages/contentPage.tsx +54 -0
  61. package/templates/demo/harbourstone/files/components/pages/expression.tsx +33 -0
  62. package/templates/demo/harbourstone/files/components/pages/homePage.tsx +71 -0
  63. package/templates/demo/harbourstone/files/components/pages/whiskyList.tsx +19 -0
  64. package/templates/demo/harbourstone/files/components/shared/bottling.tsx +59 -0
  65. package/templates/demo/harbourstone/files/components/shared/highlights.tsx +39 -0
  66. package/templates/demo/harbourstone/files/components/shared/layout.tsx +49 -0
  67. package/templates/demo/harbourstone/files/components/shared/section-intro.tsx +40 -0
  68. package/templates/demo/harbourstone/files/components/shared/site-footer.tsx +14 -0
  69. package/templates/demo/harbourstone/files/components/shared/site-header.tsx +57 -0
  70. package/templates/demo/harbourstone/files/css/site.css +720 -0
  71. package/templates/demo/harbourstone/files/schema/content-types/contact-page.toml +75 -0
  72. package/templates/demo/harbourstone/files/schema/content-types/content-page.toml +89 -0
  73. package/templates/demo/harbourstone/files/schema/content-types/expression.toml +78 -0
  74. package/templates/demo/harbourstone/files/schema/content-types/highlight.toml +27 -0
  75. package/templates/demo/harbourstone/files/schema/content-types/home-page.toml +104 -0
  76. package/templates/demo/harbourstone/files/schema/content-types/tasting-note.toml +26 -0
  77. package/templates/demo/harbourstone/files/schema/content-types/whisky-list.toml +35 -0
  78. package/templates/demo/harbourstone/files/schema/data-types/highlight-picker.toml +10 -0
  79. package/templates/demo/harbourstone/files/schema/data-types/tasting-note-picker.toml +11 -0
  80. package/templates/demo/harbourstone/files/schema/forms/contact.toml +119 -0
  81. package/templates/demo/harbourstone/files/schema/schema.toml +2 -0
  82. package/templates/demo/harbourstone/template.json +10 -0
  83. package/templates/starter/bundle/bundle.json +49 -0
  84. package/templates/starter/bundle/nodes/634dd948-cf83-4cad-9b7b-7c938b33da76.json +62 -0
  85. package/templates/starter/bundle/nodes/64d95359-d91a-4050-b440-3e5124a74999.json +62 -0
  86. package/templates/starter/bundle/nodes/d2997ebb-36ca-47cb-bbc8-31fefca787c0.json +45 -0
  87. package/templates/starter/files/components/pages/contentPage.tsx +25 -0
  88. package/templates/starter/files/components/shared/layout.tsx +24 -0
  89. package/templates/starter/files/components/shared/site-footer.tsx +9 -0
  90. package/templates/starter/files/components/shared/site-header.tsx +40 -0
  91. package/templates/starter/files/css/site.css +117 -0
  92. package/templates/starter/files/schema/content-types/content-page.toml +51 -0
  93. package/templates/starter/files/schema/schema.toml +2 -0
  94. package/templates/starter/template.json +4 -0
  95. package/README.md +0 -3
@@ -0,0 +1,75 @@
1
+ # A page type of its own rather than another `contentPage`: the layout is a form
2
+ # beside an address panel, which is a different thing from prose with a picture,
3
+ # and branching one template on which properties happen to be filled is how a
4
+ # view becomes unreadable.
5
+ [content-type]
6
+ key = "7100a925-a7e5-48a4-ad8e-120fc08cf987"
7
+ alias = "contactPage"
8
+ name = "Contact Page"
9
+ description = "A form and the details beside it"
10
+ icon = "icon-message"
11
+ components = ["pages/contactPage"]
12
+ default-component = "pages/contactPage"
13
+
14
+ [[tab]]
15
+ name = "Header"
16
+
17
+ [[tab.property]]
18
+ key = "753d8c52-4949-4e92-a76a-fa02da0fd199"
19
+ alias = "eyebrow"
20
+ name = "Eyebrow"
21
+ type = "textstring"
22
+
23
+ [[tab.property]]
24
+ key = "1e8f3a9d-5bdf-4a01-a6c7-cc4a055fae22"
25
+ alias = "title"
26
+ name = "Title"
27
+ type = "textstring"
28
+ mandatory = true
29
+
30
+ [[tab.property]]
31
+ key = "cf4561c0-82bb-4ad5-9f88-bd3fbd210b7c"
32
+ alias = "standfirst"
33
+ name = "Standfirst"
34
+ type = "textarea"
35
+
36
+ [[tab]]
37
+ name = "Form"
38
+
39
+ # `formPicker` is seeded with the other built-in data types, so a property can
40
+ # use it with no file of its own. The value is a form's UUID from
41
+ # `schema/forms/`, and the value converter hands the view the definition rather
42
+ # than the key — see `components/contactPage.tsx`.
43
+ [[tab.property]]
44
+ key = "9f2c71b5-5de4-4a6e-9c0a-1b7d84f3a2ce"
45
+ alias = "enquiryForm"
46
+ name = "Form"
47
+ description = "Leave empty for a page that only gives the address."
48
+ type = "formPicker"
49
+
50
+ [[tab]]
51
+ name = "Details"
52
+
53
+ [[tab.property]]
54
+ key = "74ad36ef-7bc9-44a5-833b-a5ebbc055198"
55
+ alias = "asideEyebrow"
56
+ name = "Eyebrow"
57
+ type = "textstring"
58
+
59
+ [[tab.property]]
60
+ key = "f280c253-5a8e-4db2-8cd6-516066061242"
61
+ alias = "asideHeading"
62
+ name = "Heading"
63
+ type = "textstring"
64
+
65
+ [[tab.property]]
66
+ key = "5611c2fa-720b-447a-9b01-c8e761e738ac"
67
+ alias = "asideBody"
68
+ name = "Address and contact"
69
+ type = "richtext"
70
+
71
+ [[tab.property]]
72
+ key = "278a95aa-9a7d-47bc-ad09-545104a1a7cd"
73
+ alias = "asideImage"
74
+ name = "Image"
75
+ type = "imageMediaPicker"
@@ -0,0 +1,89 @@
1
+ [content-type]
2
+ key = "086fc24d-2c96-4298-8678-145b38dcc14a"
3
+ alias = "contentPage"
4
+ name = "Content Page"
5
+ description = "A page of prose with an image section and a band of highlights"
6
+ icon = "icon-document"
7
+ allow-children = ["contentPage"]
8
+ components = ["pages/contentPage"]
9
+ default-component = "pages/contentPage"
10
+
11
+ [[tab]]
12
+ name = "Header"
13
+
14
+ [[tab.property]]
15
+ key = "69bc242b-d03f-4b59-911f-98887d4e93d3"
16
+ alias = "eyebrow"
17
+ name = "Eyebrow"
18
+ description = "The small line above the heading"
19
+ type = "textstring"
20
+
21
+ [[tab.property]]
22
+ key = "4501d20d-3b78-40a4-97e4-dd25b2d8535a"
23
+ alias = "title"
24
+ name = "Title"
25
+ type = "textstring"
26
+ mandatory = true
27
+
28
+ [[tab.property]]
29
+ key = "33199ac7-8128-4dc4-bae1-554b2a622447"
30
+ alias = "standfirst"
31
+ name = "Standfirst"
32
+ description = "A paragraph under the title"
33
+ type = "textarea"
34
+
35
+ [[tab]]
36
+ name = "Section"
37
+
38
+ [[tab.property]]
39
+ key = "6e9917d3-0a7c-4568-9e43-7468c6181d9c"
40
+ alias = "heroImage"
41
+ name = "Image"
42
+ type = "imageMediaPicker"
43
+
44
+ [[tab.property]]
45
+ key = "93877ded-cbb6-440a-8042-06508caec630"
46
+ alias = "sectionEyebrow"
47
+ name = "Eyebrow"
48
+ type = "textstring"
49
+
50
+ [[tab.property]]
51
+ key = "317b652e-ceca-4e98-b89f-7a8cac855854"
52
+ alias = "sectionHeading"
53
+ name = "Heading"
54
+ type = "textstring"
55
+
56
+ [[tab.property]]
57
+ key = "f3a8a9f6-f841-486b-be9e-038bd15df843"
58
+ alias = "bodyText"
59
+ name = "Body"
60
+ type = "richtext"
61
+
62
+ [[tab]]
63
+ name = "Highlights"
64
+
65
+ [[tab.property]]
66
+ key = "986368b7-8b5e-4b0c-a5bb-7b9c0a789998"
67
+ alias = "highlightsEyebrow"
68
+ name = "Eyebrow"
69
+ type = "textstring"
70
+
71
+ [[tab.property]]
72
+ key = "e0c93426-bf71-4ba9-a9a7-ebd97bce7a63"
73
+ alias = "highlightsHeading"
74
+ name = "Heading"
75
+ type = "textstring"
76
+
77
+ # The same element type the home page picks its figures from. Leave this empty
78
+ # and the whole dark band disappears — see `components/contentPage.tsx`.
79
+ [[tab.property]]
80
+ key = "93a7b537-c3e7-4826-9ec8-ce8f150bce50"
81
+ alias = "highlights"
82
+ name = "Highlights"
83
+ type = "highlightPicker"
84
+
85
+ [[tab.property]]
86
+ key = "d1b0e86e-65aa-497f-825b-b48fd301e52a"
87
+ alias = "highlightsImage"
88
+ name = "Image"
89
+ type = "imageMediaPicker"
@@ -0,0 +1,78 @@
1
+ [content-type]
2
+ key = "cf0bade1-5027-4f98-b7b3-0f7ae51f0a7f"
3
+ alias = "expression"
4
+ name = "Expression"
5
+ description = "One bottling in the range"
6
+ icon = "icon-wine-glass"
7
+ components = ["pages/expression"]
8
+ default-component = "pages/expression"
9
+
10
+ [[tab]]
11
+ name = "Content"
12
+
13
+ [[tab.property]]
14
+ key = "52a26147-233c-41f3-84f3-cf8921b696c5"
15
+ alias = "title"
16
+ name = "Title"
17
+ type = "textstring"
18
+ mandatory = true
19
+
20
+ [[tab.property]]
21
+ key = "25738367-ed14-4985-9843-04716417c88a"
22
+ alias = "kind"
23
+ name = "Kind"
24
+ description = "House malt, Lightly peated, Sherry matured, Cask strength"
25
+ type = "textstring"
26
+
27
+ [[tab.property]]
28
+ key = "f4238bf1-3d9d-4dbc-b6f4-9800e1dfdc79"
29
+ alias = "summary"
30
+ name = "Summary"
31
+ description = "One line, shown wherever this bottling is listed"
32
+ type = "textarea"
33
+
34
+ [[tab.property]]
35
+ key = "df466e38-c8c5-4b8f-b56b-fff051d724cc"
36
+ alias = "bottleImage"
37
+ name = "Bottle"
38
+ type = "imageMediaPicker"
39
+
40
+ [[tab.property]]
41
+ key = "5b509286-46c1-4863-8b6d-d054a1501164"
42
+ alias = "bodyText"
43
+ name = "Body"
44
+ type = "richtext"
45
+
46
+ [[tab]]
47
+ name = "Specification"
48
+
49
+ [[tab.property]]
50
+ key = "ff73013c-fdb2-4cd6-9afa-e117d8d223a9"
51
+ alias = "abv"
52
+ name = "ABV"
53
+ description = "As it is printed on the label, e.g. 46%"
54
+ type = "textstring"
55
+
56
+ [[tab.property]]
57
+ key = "f1053b53-6cbc-4b6b-85b3-9f5c5a73750f"
58
+ alias = "age"
59
+ name = "Age"
60
+ description = "Years in cask. Leave empty for a batch release."
61
+ type = "numeric"
62
+
63
+ [[tab.property]]
64
+ key = "4622644d-c3b4-44e3-abc1-318229680f1e"
65
+ alias = "batch"
66
+ name = "Batch"
67
+ description = "Shown instead of an age, e.g. 07"
68
+ type = "textstring"
69
+
70
+ [[tab]]
71
+ name = "Tasting"
72
+
73
+ [[tab.property]]
74
+ key = "ac279149-fa32-4ce0-91a8-d32b7160d36f"
75
+ alias = "tastingNotes"
76
+ name = "Tasting notes"
77
+ description = "Nose, palate and finish, picked from the Library"
78
+ type = "tastingNotePicker"
@@ -0,0 +1,27 @@
1
+ # A second element type, and the point of it is reuse: the home page picks four
2
+ # of these as the figures beside the house style, and the About page picks four
3
+ # more as the decisions that set it. Same type, two content types, no second
4
+ # shape to maintain.
5
+ [content-type]
6
+ key = "2e4e319f-2627-43da-8200-27d6197aced7"
7
+ alias = "highlight"
8
+ name = "Highlight"
9
+ description = "A short heading and a line under it, reusable across pages"
10
+ icon = "icon-list"
11
+ is-element = true
12
+ allow-in-library = true
13
+
14
+ [[property]]
15
+ key = "f441928a-273d-4a6a-94d9-f363d448107e"
16
+ alias = "heading"
17
+ name = "Heading"
18
+ description = "A year, a number, or a single word"
19
+ type = "textstring"
20
+ mandatory = true
21
+
22
+ [[property]]
23
+ key = "b5e05c31-681a-473a-9597-777eb27517c5"
24
+ alias = "detail"
25
+ name = "Detail"
26
+ type = "textarea"
27
+ mandatory = true
@@ -0,0 +1,104 @@
1
+ [content-type]
2
+ key = "e7fa436b-a7bc-4413-8d12-7eb535b61cb2"
3
+ alias = "homePage"
4
+ name = "Home Page"
5
+ description = "The site's landing page"
6
+ icon = "icon-home"
7
+ allow-at-root = true
8
+ allow-children = ["contentPage", "whiskyList", "contactPage"]
9
+ components = ["pages/homePage"]
10
+ default-component = "pages/homePage"
11
+
12
+ [[tab]]
13
+ name = "Hero"
14
+
15
+ [[tab.property]]
16
+ key = "4beadbaf-51d7-40bc-bb3e-3560413b42dc"
17
+ alias = "eyebrow"
18
+ name = "Eyebrow"
19
+ description = "The small line above the heading"
20
+ type = "textstring"
21
+
22
+ [[tab.property]]
23
+ key = "be74a0df-3e9d-47f3-b60e-778a89682a80"
24
+ alias = "title"
25
+ name = "Title"
26
+ description = "Shown as the page heading"
27
+ type = "textstring"
28
+ mandatory = true
29
+
30
+ [[tab.property]]
31
+ key = "a540c93a-228b-49f6-931a-be1b986bedd1"
32
+ alias = "strapline"
33
+ name = "Strapline"
34
+ description = "One line under the heading"
35
+ type = "textarea"
36
+
37
+ [[tab.property]]
38
+ key = "ad73357a-4beb-497d-9b55-9fe5222f781e"
39
+ alias = "heroImage"
40
+ name = "Hero image"
41
+ type = "imageMediaPicker"
42
+
43
+ [[tab.property]]
44
+ key = "768f61dc-4808-40d4-a9cd-515516848640"
45
+ alias = "heroCtaLabel"
46
+ name = "Hero button"
47
+ description = "Links to the range. Leave empty for no button."
48
+ type = "textstring"
49
+
50
+ [[tab]]
51
+ name = "House style"
52
+
53
+ [[tab.property]]
54
+ key = "5f5aab62-b28d-4a2e-9f0b-6d6f888f9de0"
55
+ alias = "styleEyebrow"
56
+ name = "Eyebrow"
57
+ type = "textstring"
58
+
59
+ [[tab.property]]
60
+ key = "2c0f6d01-068a-444a-9f74-bb8d5642574c"
61
+ alias = "styleHeading"
62
+ name = "Heading"
63
+ type = "textstring"
64
+
65
+ [[tab.property]]
66
+ key = "0aad18a5-a627-42f5-a95f-311fdaed30ae"
67
+ alias = "styleIntro"
68
+ name = "Introduction"
69
+ type = "richtext"
70
+
71
+ [[tab.property]]
72
+ key = "2d297b00-721d-462c-939c-c462467b40d3"
73
+ alias = "stats"
74
+ name = "Figures"
75
+ description = "Picked from the Library; shown as a grid under the introduction"
76
+ type = "highlightPicker"
77
+
78
+ [[tab.property]]
79
+ key = "3de44366-c05d-4036-aa92-481d4763c6e2"
80
+ alias = "styleImage"
81
+ name = "Image"
82
+ type = "imageMediaPicker"
83
+
84
+ [[tab]]
85
+ name = "Range"
86
+
87
+ [[tab.property]]
88
+ key = "827433bb-9a7c-47d7-84e5-9d386bcc9e73"
89
+ alias = "rangeEyebrow"
90
+ name = "Eyebrow"
91
+ type = "textstring"
92
+
93
+ [[tab.property]]
94
+ key = "74c2e4dd-34b7-4905-baeb-c6c100602bd8"
95
+ alias = "rangeHeading"
96
+ name = "Heading"
97
+ type = "textstring"
98
+
99
+ [[tab.property]]
100
+ key = "af8b51ac-208e-40ad-a311-80495dced2a7"
101
+ alias = "rangeCtaLabel"
102
+ name = "Button"
103
+ description = "Links to the range. Leave empty for no button."
104
+ type = "textstring"
@@ -0,0 +1,26 @@
1
+ # An element type: content with no URL of its own, created in the Library and
2
+ # pointed at from a page. `is-element` makes it one; `allow-in-library` is what
3
+ # puts it in the Library's Create dialog, and Umbraco requires both.
4
+ [content-type]
5
+ key = "55138391-faf2-4795-9ed6-43d581d350a4"
6
+ alias = "tastingNote"
7
+ name = "Tasting Note"
8
+ description = "Nose, palate or finish, reusable across bottlings"
9
+ icon = "icon-coffee"
10
+ is-element = true
11
+ allow-in-library = true
12
+
13
+ [[property]]
14
+ key = "b182753f-d1a1-4c2c-9bd5-1252d0eb7f60"
15
+ alias = "aspect"
16
+ name = "Aspect"
17
+ description = "Nose, Palate or Finish"
18
+ type = "textstring"
19
+ mandatory = true
20
+
21
+ [[property]]
22
+ key = "c9b32002-2aa3-4218-a0ae-6185c066161d"
23
+ alias = "note"
24
+ name = "Note"
25
+ type = "textarea"
26
+ mandatory = true
@@ -0,0 +1,35 @@
1
+ # `collection` gives the backoffice a list view of the children instead of a
2
+ # tree branch, which is what a range of bottlings wants.
3
+ [content-type]
4
+ key = "57a5b3bd-c465-4509-9833-e20a06f28717"
5
+ alias = "whiskyList"
6
+ name = "Whisky List"
7
+ description = "The range: a parent for the bottlings"
8
+ icon = "icon-bulleted-list"
9
+ allow-children = ["expression"]
10
+ collection = "listViewContent"
11
+ components = ["pages/whiskyList"]
12
+ default-component = "pages/whiskyList"
13
+
14
+ [[tab]]
15
+ name = "Content"
16
+
17
+ [[tab.property]]
18
+ key = "13785a42-6d0a-4152-89ec-c765db766547"
19
+ alias = "eyebrow"
20
+ name = "Eyebrow"
21
+ type = "textstring"
22
+
23
+ [[tab.property]]
24
+ key = "727804c0-7d4a-43d9-a473-71c9e27397c0"
25
+ alias = "title"
26
+ name = "Title"
27
+ type = "textstring"
28
+ mandatory = true
29
+
30
+ [[tab.property]]
31
+ key = "9c83bcea-a70e-4a3f-8185-ad04ddec55f1"
32
+ alias = "standfirst"
33
+ name = "Standfirst"
34
+ description = "A paragraph under the title"
35
+ type = "textarea"
@@ -0,0 +1,10 @@
1
+ # The same Element Picker schema as the tasting notes beside it, narrowed to a
2
+ # different element type. Two data types over one editor is how a picker is kept
3
+ # from offering everything in the Library.
4
+ [data-type]
5
+ key = "0a46b720-4f6c-4f8f-9c80-d3b018389006"
6
+ alias = "highlightPicker"
7
+ name = "Highlight Picker"
8
+ editor = "Umbraco.ElementPicker"
9
+ editor-ui = "Umb.PropertyEditorUi.ElementPicker"
10
+ config = { allowedContentTypes = "2e4e319f-2627-43da-8200-27d6197aced7" }
@@ -0,0 +1,11 @@
1
+ # Umbraco ships the Element Picker's schema but seeds no data type for it, so a
2
+ # site declares its own. `allowedContentTypes` is a comma-separated list of element
3
+ # type keys; it narrows the picker, and `crombolo generate` reads it to type the
4
+ # value as `Array<TypedElement<TastingNote>>` rather than `Array<PublishedElement>`.
5
+ [data-type]
6
+ key = "3f99cab4-4712-4514-a4be-dbb45c73ce80"
7
+ alias = "tastingNotePicker"
8
+ name = "Tasting Note Picker"
9
+ editor = "Umbraco.ElementPicker"
10
+ editor-ui = "Umb.PropertyEditorUi.ElementPicker"
11
+ config = { allowedContentTypes = "55138391-faf2-4795-9ed6-43d581d350a4" }
@@ -0,0 +1,119 @@
1
+ # A form is structure, so it is a file like the content types beside it and a
2
+ # change to it shows up in a diff (`docs/18-forms.md`). The Contact page points
3
+ # at this one through its `enquiryForm` property, and `components/contactPage.tsx`
4
+ # renders it with `<Form>`.
5
+ #
6
+ # Submissions land in the Forms section under Entries. `phone` is marked
7
+ # sensitive, so it is redacted for anyone without the sensitive-data permission
8
+ # — in the API response and in the CSV export, not merely in the screen.
9
+ [form]
10
+ key = "7b1f4c20-9a63-4e18-8d25-3c6f5a1e9b04"
11
+ alias = "contactEnquiry"
12
+ name = "Write to the cove"
13
+ store-entries = true
14
+ requires-approval = false
15
+ submit-label = "Send message"
16
+ message-on-submit = "Received. We answer from the stillhouse office within two working days."
17
+ # A field no visitor ever fills, and a floor on how fast the form can come back:
18
+ # between them they stop the bulk of automated submissions without a captcha.
19
+ honeypot = true
20
+ minimum-submit-seconds = 3
21
+
22
+ [[page]]
23
+
24
+ [[page.group]]
25
+ columns = 1
26
+
27
+ [[page.group.field]]
28
+ key = "7b1f4c20-0001-4e18-8d25-3c6f5a1e9b04"
29
+ alias = "visitorName"
30
+ type = "shortAnswer"
31
+ caption = "Name"
32
+ mandatory = true
33
+ mandatory-message = "We need a name to reply to"
34
+ autocomplete = "name"
35
+
36
+ [[page.group.field]]
37
+ key = "7b1f4c20-0002-4e18-8d25-3c6f5a1e9b04"
38
+ alias = "visitorEmail"
39
+ type = "email"
40
+ caption = "Email"
41
+ mandatory = true
42
+ mandatory-message = "We need an email address to reply to"
43
+ autocomplete = "email"
44
+
45
+ [[page.group.field]]
46
+ key = "7b1f4c20-0003-4e18-8d25-3c6f5a1e9b04"
47
+ alias = "topic"
48
+ type = "dropdown"
49
+ caption = "Subject"
50
+ mandatory = true
51
+ default-value = "Book a distillery visit"
52
+ values = [
53
+ "Book a distillery visit",
54
+ "Trade and allocation",
55
+ "Press",
56
+ "Something else",
57
+ ]
58
+
59
+ [[page.group.field]]
60
+ key = "7b1f4c20-0004-4e18-8d25-3c6f5a1e9b04"
61
+ alias = "company"
62
+ type = "shortAnswer"
63
+ caption = "Company"
64
+ help-text = "Who you buy for, and where"
65
+ mandatory = true
66
+ mandatory-message = "We need the company name for a trade enquiry"
67
+
68
+ # A condition may only look backwards, at a field already answered above —
69
+ # so this one names `topic` and not something further down the form. It is
70
+ # evaluated on the server as well as in the browser, and the server's
71
+ # answer is the one that counts: a mandatory field the condition hides is
72
+ # not demanded, and a hidden field's value is discarded.
73
+ [page.group.field.condition]
74
+ action = "show"
75
+ match = "all"
76
+ rule = [{ field = "topic", operator = "is", value = "Trade and allocation" }]
77
+
78
+ [[page.group.field]]
79
+ key = "7b1f4c20-0005-4e18-8d25-3c6f5a1e9b04"
80
+ alias = "phone"
81
+ type = "shortAnswer"
82
+ caption = "Phone"
83
+ help-text = "Only if you would rather we rang"
84
+ sensitive = true
85
+ autocomplete = "tel"
86
+
87
+ [[page.group.field]]
88
+ key = "7b1f4c20-0006-4e18-8d25-3c6f5a1e9b04"
89
+ alias = "message"
90
+ type = "longAnswer"
91
+ caption = "Message"
92
+ placeholder = "Preferred dates, party size, or the bottling you are after."
93
+ mandatory = true
94
+ mandatory-message = "Tell us what you are after"
95
+ rows = 5
96
+
97
+ [[page.group.field]]
98
+ key = "7b1f4c20-0007-4e18-8d25-3c6f5a1e9b04"
99
+ alias = "consent"
100
+ type = "dataConsent"
101
+ caption = "I am happy for Harbourstone to hold these details in order to answer my message."
102
+ mandatory = true
103
+ mandatory-message = "We cannot store your message without this"
104
+
105
+ # Telling somebody about a submission takes an e-mail provider, which this
106
+ # template does not configure — see `docs/14-configuration.md`. With
107
+ # CROMBOLO_EMAIL_* set, uncomment this and the message is mailed on submit; the
108
+ # queue retries, so a provider that is briefly down loses nothing.
109
+ #
110
+ # [[workflow]]
111
+ # key = "7b1f4c20-0008-4e18-8d25-3c6f5a1e9b04"
112
+ # type = "sendEmail"
113
+ # name = "Tell the stillhouse office"
114
+ # on = "submit"
115
+ #
116
+ # [workflow.settings]
117
+ # to = "visitors@harbourstone.scot"
118
+ # reply-to = "{visitorEmail}"
119
+ # subject = "Website: {topic}"
@@ -0,0 +1,2 @@
1
+ [schema]
2
+ version = "1.0.0"
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "Harbourstone Distillery",
3
+ "description": "a coastal distillery: a range with tasting-note elements, reusable highlights, a contact form, photographs and a stylesheet",
4
+ "bundles": [
5
+ {
6
+ "package": "@crombolo/simple-redirects",
7
+ "import": "redirects"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "formatVersion": 1,
3
+ "id": "da9fd74e-b964-44b4-8d61-afa7f65a28d2",
4
+ "createdAt": "2026-10-01T00:00:00.000Z",
5
+ "createdBy": "bun run build:template",
6
+ "integrity": "sha256-3ef21d4b047d85bfef8aeaac90255348bf636ba6ff3c0d0e155a06a2225269de",
7
+ "snapshot": "published",
8
+ "provenance": {
9
+ "siteName": "Starter",
10
+ "schemaVersion": "1.0.0",
11
+ "schemaRevision": "0",
12
+ "schemaHash": "81d3ebeb2c46ec1a17f0bf253e1bf711c47390ac49eb3f32a60b23e3ace89b16"
13
+ },
14
+ "selector": {
15
+ "roots": [
16
+ "64d95359-d91a-4050-b440-3e5124a74999",
17
+ "634dd948-cf83-4cad-9b7b-7c938b33da76",
18
+ "d2997ebb-36ca-47cb-bbc8-31fefca787c0"
19
+ ],
20
+ "descendants": true,
21
+ "asGiven": [
22
+ "starter"
23
+ ]
24
+ },
25
+ "counts": {
26
+ "document": 3
27
+ },
28
+ "dependencies": {
29
+ "carried": [
30
+ "634dd948-cf83-4cad-9b7b-7c938b33da76",
31
+ "64d95359-d91a-4050-b440-3e5124a74999",
32
+ "d2997ebb-36ca-47cb-bbc8-31fefca787c0"
33
+ ],
34
+ "expected": [],
35
+ "schema": {
36
+ "contentTypes": [
37
+ {
38
+ "key": "8491ffa4-9b2f-48b0-a3c0-f40c1034216e",
39
+ "alias": "contentPage"
40
+ }
41
+ ],
42
+ "components": [
43
+ "pages/contentPage"
44
+ ],
45
+ "languages": []
46
+ }
47
+ },
48
+ "blobs": []
49
+ }