1+ import handlebars from "handlebars" ;
2+ import hbh_comparison from "handlebars-helpers/lib/comparison.js" ;
3+ import hbh_array from "handlebars-helpers/lib/array.js" ;
4+ import hbh_string from "handlebars-helpers/lib/string.js" ;
15import chalk from "chalk" ;
2- import BaseVueGenerator from "./VueBaseGenerator .js" ;
6+ import BaseGenerator from "./BaseGenerator .js" ;
37
4- export default class NuxtGenerator extends BaseVueGenerator {
8+ export default class NuxtGenerator extends BaseGenerator {
59 constructor ( params ) {
610 super ( params ) ;
711
12+ this . registerTemplates ( "common/" , [
13+ // types
14+ "types/collection.ts" ,
15+ "types/error.ts" ,
16+ "types/foo.ts" ,
17+ "types/item.ts" ,
18+ "types/view.ts" ,
19+
20+ // utils
21+ "utils/config.ts" ,
22+ "utils/date.ts" ,
23+ "utils/error.ts" ,
24+ "utils/mercure.ts" ,
25+ ] ) ;
26+
27+ this . registerTemplates ( "vue-common/" , [
28+ // composables
29+ "composables/mercureItem.ts" ,
30+ "composables/mercureList.ts" ,
31+ ] ) ;
32+
833 this . registerTemplates ( `nuxt/` , [
34+ // common components
35+ "components/common/FormRepeater.vue" ,
36+
937 // components
10- "components/ActionCell.vue" ,
11- "components/Alert.vue" ,
12- "components/ConfirmDelete.vue" ,
13- "components/DataFilter.vue" ,
14- "components/InputDate.vue" ,
15- "components/Loading.vue" ,
16- "components/Toolbar.vue" ,
17- "components/foo/Filter.vue" ,
18- "components/foo/Form.vue" ,
19-
20- // mixins
21- "mixins/create.js" ,
22- "mixins/list.js" ,
23- "mixins/notification.js" ,
24- "mixins/show.js" ,
25- "mixins/update.js" ,
38+ "components/foo/FooCreate.vue" ,
39+ "components/foo/FooForm.vue" ,
40+ "components/foo/FooList.vue" ,
41+ "components/foo/FooShow.vue" ,
42+ "components/foo/FooUpdate.vue" ,
43+
44+ // composables
45+ "composables/api.ts" ,
2646
2747 // pages
48+ "pages/index.vue" ,
2849 "pages/foos/create.vue" ,
2950 "pages/foos/index.vue" ,
30- "pages/foos/_id/edit.vue" ,
31- "pages/foos/_id/index.vue" ,
32-
33- // store
34- "store/crud.js" ,
35- "store/notifications.js" ,
36- "store/foo.js" ,
51+ "pages/foos/[id]/edit.vue" ,
52+ "pages/foos/[id]/index.vue" ,
53+ "pages/foos/page/[page].vue" ,
54+
55+ // stores
56+ "stores/foo/create.ts" ,
57+ "stores/foo/delete.ts" ,
58+ "stores/foo/list.ts" ,
59+ "stores/foo/show.ts" ,
60+ "stores/foo/update.ts" ,
61+
62+ // types
63+ "types/api.ts" ,
64+
65+ // utils
66+ "utils/resource.ts" ,
3767 ] ) ;
68+
69+ handlebars . registerHelper ( "compare" , hbh_comparison . compare ) ;
70+ handlebars . registerHelper ( "forEach" , hbh_array . forEach ) ;
71+ handlebars . registerHelper ( "lowercase" , hbh_string . lowercase ) ;
3872 }
3973
4074 help ( resource ) {
@@ -44,115 +78,144 @@ export default class NuxtGenerator extends BaseVueGenerator {
4478 ) ;
4579 }
4680
47- generateFiles ( api , resource , dir , params ) {
48- const context = super . getContextForResource ( resource , params ) ;
49- const lc = context . lc ;
50-
51- [
52- `${ dir } /config` ,
53- `${ dir } /error` ,
54- `${ dir } /mixins` ,
55- `${ dir } /services` ,
56- `${ dir } /store` ,
57- `${ dir } /utils` ,
58- `${ dir } /validators` ,
59- ] . forEach ( ( dir ) => this . createDir ( dir , false ) ) ;
60-
61- // error
62- this . createFile (
63- "error/SubmissionError.js" ,
64- `${ dir } /error/SubmissionError.js` ,
65- { } ,
66- false
67- ) ;
68-
69- // mixins
70- [
71- "mixins/create.js" ,
72- "mixins/list.js" ,
73- "mixins/notification.js" ,
74- "mixins/show.js" ,
75- "mixins/update.js" ,
76- ] . forEach ( ( file ) =>
77- this . createFile ( file , `${ dir } /${ file } ` , context , false )
78- ) ;
79-
80- // stores
81- this . createFile (
82- `store/modules/notifications.js` ,
83- `${ dir } /store/notifications.js` ,
84- { hydraPrefix : this . hydraPrefix } ,
85- false
86- ) ;
87-
88- this . createFile (
89- `store/crud.js` ,
90- `${ dir } /store/crud.js` ,
91- { hydraPrefix : this . hydraPrefix } ,
92- false
93- ) ;
94-
95- // validators
96- this . createFile (
97- "validators/date.js" ,
98- `${ dir } /validators/date.js` ,
99- { hydraPrefix : this . hydraPrefix } ,
100- false
101- ) ;
102-
103- // utils
104- [ "dates.js" , "fetch.js" , "hydra.js" ] . forEach ( ( file ) =>
105- this . createFile ( `utils/${ file } ` , `${ dir } /utils/${ file } ` , { } , false )
106- ) ;
81+ getContextForResource ( resource ) {
82+ const lc = resource . title . toLowerCase ( ) ;
83+ const titleUcFirst =
84+ resource . title . charAt ( 0 ) . toUpperCase ( ) + resource . title . slice ( 1 ) ;
85+ const fields = this . parseFields ( resource ) ;
86+ const hasIsRelation = fields . some ( ( field ) => field . isRelation ) ;
87+ const hasIsRelations = fields . some ( ( field ) => field . isRelations ) ;
88+ const hasRelations = hasIsRelation || hasIsRelations ;
89+
90+ const formFields = this . buildFields ( fields ) ;
91+
92+ return {
93+ title : resource . title ,
94+ name : resource . name ,
95+ lc,
96+ uc : resource . title . toUpperCase ( ) ,
97+ fields,
98+ hasIsRelation,
99+ hasIsRelations,
100+ hasRelations,
101+ formFields,
102+ hydraPrefix : this . hydraPrefix ,
103+ titleUcFirst,
104+ } ;
105+ }
107106
108- this . createEntrypoint ( api . entrypoint , `${ dir } /config/entrypoint.js` ) ;
107+ generate ( api , resource , dir ) {
108+ const context = this . getContextForResource ( resource ) ;
109+ const { lc, titleUcFirst } = context ;
109110
110111 [
112+ `${ dir } /assets` ,
113+ `${ dir } /assets/css` ,
114+ `${ dir } /components` ,
115+ `${ dir } /components/common` ,
111116 `${ dir } /components/${ lc } ` ,
117+ `${ dir } /composables` ,
118+ `${ dir } /pages` ,
112119 `${ dir } /pages/${ lc } s` ,
113- `${ dir } /pages/${ lc } s/_id` ,
114- ] . forEach ( ( dir ) => {
115- this . createDir ( dir ) ;
116- } ) ;
117-
118- this . createFile ( "services/api.js" , `${ dir } /services/api.js` , { } , false ) ;
120+ `${ dir } /pages/${ lc } s/[id]` ,
121+ `${ dir } /pages/${ lc } s/page` ,
122+ `${ dir } /stores` ,
123+ `${ dir } /stores/${ lc } ` ,
124+ `${ dir } /types` ,
125+ `${ dir } /utils` ,
126+ ] . forEach ( ( dir ) => this . createDir ( dir , false ) ) ;
119127
120128 [
121129 // components
122- "components/%s/Filter.vue" ,
123- "components/%s/Form.vue" ,
130+ "components/%s/%sCreate.vue" ,
131+ "components/%s/%sForm.vue" ,
132+ "components/%s/%sList.vue" ,
133+ "components/%s/%sShow.vue" ,
134+ "components/%s/%sUpdate.vue" ,
124135
125136 // pages
126137 "pages/%ss/create.vue" ,
127138 "pages/%ss/index.vue" ,
128- "pages/%ss/_id/edit.vue" ,
129- "pages/%ss/_id/index.vue" ,
130-
131- // service
132- "services/%s.js" ,
133-
134- // store
135- "store/%s.js" ,
139+ "pages/%ss/[id]/edit.vue" ,
140+ "pages/%ss/[id]/index.vue" ,
141+ "pages/%ss/page/[page].vue" ,
142+
143+ // stores
144+ "stores/%s/create.ts" ,
145+ "stores/%s/delete.ts" ,
146+ "stores/%s/list.ts" ,
147+ "stores/%s/show.ts" ,
148+ "stores/%s/update.ts" ,
149+
150+ // types
151+ "types/%s.ts" ,
136152 ] . forEach ( ( pattern ) =>
137- this . createFileFromPattern ( pattern , dir , [ lc ] , context )
153+ this . createFileFromPattern ( pattern , dir , [ lc , titleUcFirst ] , context )
138154 ) ;
139155
140- // components
141156 [
142- "ActionCell.vue" ,
143- "Alert.vue" ,
144- "ConfirmDelete.vue" ,
145- "DataFilter.vue" ,
146- "InputDate.vue" ,
147- "Loading.vue" ,
148- "Toolbar.vue" ,
149- ] . forEach ( ( file ) =>
150- this . createFile (
151- `components/${ file } ` ,
152- `${ dir } /components/${ file } ` ,
153- context ,
154- false
155- )
157+ // components
158+ "components/common/FormRepeater.vue" ,
159+
160+ // composables
161+ "composables/api.ts" ,
162+ "composables/mercureItem.ts" ,
163+ "composables/mercureList.ts" ,
164+
165+ // pages
166+ "pages/index.vue" ,
167+
168+ // types
169+ "types/api.ts" ,
170+ "types/collection.ts" ,
171+ "types/error.ts" ,
172+ "types/item.ts" ,
173+ "types/view.ts" ,
174+
175+ // utils
176+ "utils/date.ts" ,
177+ "utils/error.ts" ,
178+ "utils/mercure.ts" ,
179+
180+ // utils
181+ "utils/resource.ts" ,
182+ ] . forEach ( ( path ) =>
183+ this . createFile ( path , `${ dir } /${ path } ` , context , false )
156184 ) ;
185+
186+ // config
187+ this . createConfigFile ( `${ dir } /utils/config.ts` , {
188+ entrypoint : api . entrypoint ,
189+ } ) ;
190+ }
191+
192+ parseFields ( resource ) {
193+ const fields = [
194+ ...resource . writableFields ,
195+ ...resource . readableFields ,
196+ ] . reduce ( ( list , field ) => {
197+ if ( list [ field . name ] ) {
198+ return list ;
199+ }
200+
201+ const isReferences = Boolean (
202+ field . reference && field . maxCardinality !== 1
203+ ) ;
204+ const isEmbeddeds = Boolean ( field . embedded && field . maxCardinality !== 1 ) ;
205+
206+ return {
207+ ...list ,
208+ [ field . name ] : {
209+ ...field ,
210+ readonly : false ,
211+ isReferences,
212+ isEmbeddeds,
213+ isRelation : field . reference || field . embedded ,
214+ isRelations : isEmbeddeds || isReferences ,
215+ } ,
216+ } ;
217+ } , { } ) ;
218+
219+ return Object . values ( fields ) ;
157220 }
158221}
0 commit comments