Skip to content

Commit 4b0e135

Browse files
devel-padunglas
authored andcommitted
Add Quasar Framework generator. (#134)
* Add quasar generator. * Fix issues. * Add quasar test. * Fields by type. * Add initial dates as now for create form. * Painting code. * Again. * Fix linting errors.
1 parent 4f86a44 commit 4b0e135

38 files changed

+1517
-23
lines changed

src/generators.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ReactGenerator from "./generators/ReactGenerator";
33
import ReactNativeGenerator from "./generators/ReactNativeGenerator";
44
import TypescriptInterfaceGenerator from "./generators/TypescriptInterfaceGenerator";
55
import VueGenerator from "./generators/VueGenerator";
6+
import QuasarGenerator from "./generators/QuasarGenerator";
67

78
function wrap(cl) {
89
return ({ hydraPrefix, templateDirectory }) =>
@@ -21,5 +22,7 @@ export default function generators(generator = "react") {
2122
return wrap(TypescriptInterfaceGenerator);
2223
case "vue":
2324
return wrap(VueGenerator);
25+
case "quasar":
26+
return wrap(QuasarGenerator);
2427
}
2528
}

src/generators/QuasarGenerator.js

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import chalk from "chalk";
2+
import BaseGenerator from "./BaseGenerator";
3+
import handlebars from "handlebars";
4+
import hbh_comparison from "handlebars-helpers/lib/comparison";
5+
6+
export default class extends BaseGenerator {
7+
constructor(params) {
8+
super(params);
9+
10+
this.registerTemplates(`quasar/`, [
11+
// modules
12+
"store/modules/foo/index.js",
13+
"store/modules/foo/create/actions.js",
14+
"store/modules/foo/create/getters.js",
15+
"store/modules/foo/create/index.js",
16+
"store/modules/foo/create/mutation_types.js",
17+
"store/modules/foo/create/mutations.js",
18+
"store/modules/foo/delete/actions.js",
19+
"store/modules/foo/delete/getters.js",
20+
"store/modules/foo/delete/index.js",
21+
"store/modules/foo/delete/mutation_types.js",
22+
"store/modules/foo/delete/mutations.js",
23+
"store/modules/foo/list/actions.js",
24+
"store/modules/foo/list/getters.js",
25+
"store/modules/foo/list/index.js",
26+
"store/modules/foo/list/mutation_types.js",
27+
"store/modules/foo/list/mutations.js",
28+
"store/modules/foo/show/actions.js",
29+
"store/modules/foo/show/getters.js",
30+
"store/modules/foo/show/index.js",
31+
"store/modules/foo/show/mutation_types.js",
32+
"store/modules/foo/show/mutations.js",
33+
"store/modules/foo/update/actions.js",
34+
"store/modules/foo/update/getters.js",
35+
"store/modules/foo/update/index.js",
36+
"store/modules/foo/update/mutation_types.js",
37+
"store/modules/foo/update/mutations.js",
38+
39+
// components
40+
"components/foo/Create.vue",
41+
"components/foo/Form.vue",
42+
"components/foo/List.vue",
43+
"components/foo/Update.vue",
44+
"components/foo/Show.vue",
45+
46+
// routes
47+
"router/foo.js",
48+
49+
// error
50+
"error/SubmissionError.js",
51+
52+
// utils
53+
"utils/fetch.js"
54+
]);
55+
56+
handlebars.registerHelper("compare", hbh_comparison.compare);
57+
}
58+
59+
help(resource) {
60+
const titleLc = resource.title.toLowerCase();
61+
62+
console.log(
63+
'Code for the "%s" resource type has been generated!',
64+
resource.title
65+
);
66+
console.log(
67+
"Paste the following definitions in your application configuration:"
68+
);
69+
console.log(
70+
chalk.green(`
71+
//Add to quasar.conf
72+
// 1. in 'framework.components'
73+
'QTable',
74+
'QTh',
75+
'QTr',
76+
'QTd',
77+
'QAjaxBar',
78+
'QBreadcrumbs',
79+
'QBreadcrumbsEl',
80+
'QSpace',
81+
'QInput',
82+
'QForm',
83+
'QSelect',
84+
'QMarkupTable',
85+
'QDate',
86+
'QTime',
87+
'QCheckbox',
88+
'QPopupProxy',
89+
90+
// 2. in 'framework.config', customize later
91+
notify: {
92+
position: 'top',
93+
multiLine: true,
94+
timeout: 0,
95+
},
96+
97+
// 3. in 'framework.directives
98+
'ClosePopup'
99+
100+
// 4. in 'framework.plugins
101+
'Notify'
102+
103+
//import routes
104+
import ${titleLc}Routes from './router/${titleLc}';
105+
106+
// Add routes to VueRouter
107+
const router = new VueRouter({
108+
// ...
109+
routes: [
110+
...${titleLc}Routes,
111+
]
112+
});
113+
114+
// Add the modules in the store
115+
import ${titleLc} from './store/modules/${titleLc}/';
116+
117+
export const store = new Vuex.Store({
118+
// ...
119+
modules: {
120+
${titleLc}
121+
}
122+
});
123+
`)
124+
);
125+
}
126+
127+
generate(api, resource, dir) {
128+
const lc = resource.title.toLowerCase();
129+
const titleUcFirst =
130+
resource.title.charAt(0).toUpperCase() + resource.title.slice(1);
131+
132+
const context = {
133+
title: resource.title,
134+
name: resource.name,
135+
lc,
136+
uc: resource.title.toUpperCase(),
137+
fields: resource.readableFields,
138+
formFields: this.buildFields(resource.writableFields),
139+
hydraPrefix: this.hydraPrefix,
140+
titleUcFirst
141+
};
142+
143+
// Create directories
144+
// These directories may already exist
145+
for (let dir of [
146+
`${dir}/config`,
147+
`${dir}/error`,
148+
`${dir}/router`,
149+
`${dir}/utils`
150+
]) {
151+
this.createDir(dir, false);
152+
}
153+
154+
for (let dir of [
155+
`${dir}/store/modules/${lc}`,
156+
`${dir}/store/modules/${lc}/create`,
157+
`${dir}/store/modules/${lc}/delete`,
158+
`${dir}/store/modules/${lc}/list`,
159+
`${dir}/store/modules/${lc}/show`,
160+
`${dir}/store/modules/${lc}/update`,
161+
`${dir}/components/${lc}`
162+
]) {
163+
this.createDir(dir);
164+
}
165+
166+
for (let pattern of [
167+
// modules
168+
"store/modules/%s/index.js",
169+
"store/modules/%s/create/actions.js",
170+
"store/modules/%s/create/getters.js",
171+
"store/modules/%s/create/index.js",
172+
"store/modules/%s/create/mutation_types.js",
173+
"store/modules/%s/create/mutations.js",
174+
"store/modules/%s/delete/actions.js",
175+
"store/modules/%s/delete/getters.js",
176+
"store/modules/%s/delete/index.js",
177+
"store/modules/%s/delete/mutation_types.js",
178+
"store/modules/%s/delete/mutations.js",
179+
"store/modules/%s/list/actions.js",
180+
"store/modules/%s/list/getters.js",
181+
"store/modules/%s/list/index.js",
182+
"store/modules/%s/list/mutation_types.js",
183+
"store/modules/%s/list/mutations.js",
184+
"store/modules/%s/show/actions.js",
185+
"store/modules/%s/show/getters.js",
186+
"store/modules/%s/show/index.js",
187+
"store/modules/%s/show/mutation_types.js",
188+
"store/modules/%s/show/mutations.js",
189+
"store/modules/%s/update/actions.js",
190+
"store/modules/%s/update/getters.js",
191+
"store/modules/%s/update/index.js",
192+
"store/modules/%s/update/mutation_types.js",
193+
"store/modules/%s/update/mutations.js",
194+
195+
// components
196+
"components/%s/Create.vue",
197+
"components/%s/Form.vue",
198+
"components/%s/List.vue",
199+
"components/%s/Update.vue",
200+
"components/%s/Show.vue",
201+
202+
// routes
203+
"router/%s.js"
204+
]) {
205+
this.createFileFromPattern(pattern, dir, lc, context);
206+
}
207+
208+
// error
209+
this.createFile(
210+
"error/SubmissionError.js",
211+
`${dir}/error/SubmissionError.js`,
212+
context,
213+
false
214+
);
215+
216+
this.createEntrypoint(api.entrypoint, `${dir}/config/entrypoint.js`);
217+
this.createFile(
218+
"utils/fetch.js",
219+
`${dir}/utils/fetch.js`,
220+
{ hydraPrefix: this.hydraPrefix },
221+
false
222+
);
223+
}
224+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import Api from "@api-platform/api-doc-parser/lib/Api";
2+
import Resource from "@api-platform/api-doc-parser/lib/Resource";
3+
import Field from "@api-platform/api-doc-parser/lib/Field";
4+
import fs from "fs";
5+
import tmp from "tmp";
6+
import QuasarGenerator from "./QuasarGenerator";
7+
8+
test("Generate a Quasar app", () => {
9+
const generator = new QuasarGenerator({
10+
hydraPrefix: "hydra:",
11+
templateDirectory: `${__dirname}/../../templates`
12+
});
13+
const tmpobj = tmp.dirSync({ unsafeCleanup: true });
14+
15+
const fields = [
16+
new Field("bar", {
17+
id: "http://schema.org/url",
18+
range: "http://www.w3.org/2001/XMLSchema#string",
19+
reference: null,
20+
required: true,
21+
description: "An URL"
22+
})
23+
];
24+
const resource = new Resource("abc", "http://example.com/foos", {
25+
id: "foo",
26+
title: "Foo",
27+
readableFields: fields,
28+
writableFields: fields
29+
});
30+
const api = new Api("http://example.com", {
31+
entrypoint: "http://example.com:8080",
32+
title: "My API",
33+
resources: [resource]
34+
});
35+
generator.generate(api, resource, tmpobj.name);
36+
37+
expect(fs.existsSync(tmpobj.name + "/components/foo/Create.vue")).toBe(true);
38+
expect(fs.existsSync(tmpobj.name + "/components/foo/Form.vue")).toBe(true);
39+
expect(fs.existsSync(tmpobj.name + "/components/foo/List.vue")).toBe(true);
40+
expect(fs.existsSync(tmpobj.name + "/components/foo/Show.vue")).toBe(true);
41+
expect(fs.existsSync(tmpobj.name + "/components/foo/Update.vue")).toBe(true);
42+
43+
expect(fs.existsSync(tmpobj.name + "/config/entrypoint.js")).toBe(true);
44+
45+
expect(fs.existsSync(tmpobj.name + "/error/SubmissionError.js")).toBe(true);
46+
47+
expect(fs.existsSync(tmpobj.name + "/router/foo.js")).toBe(true);
48+
49+
expect(fs.existsSync(tmpobj.name + "/store/modules/foo/index.js")).toBe(true);
50+
51+
["create", "delete", "list", "show", "update"].forEach(action => {
52+
expect(
53+
fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/actions.js`)
54+
).toBe(true);
55+
expect(
56+
fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/getters.js`)
57+
).toBe(true);
58+
expect(
59+
fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/index.js`)
60+
).toBe(true);
61+
expect(
62+
fs.existsSync(
63+
`${tmpobj.name}/store/modules/foo/${action}/mutation_types.js`
64+
)
65+
).toBe(true);
66+
expect(
67+
fs.existsSync(`${tmpobj.name}/store/modules/foo/${action}/mutations.js`)
68+
).toBe(true);
69+
});
70+
71+
expect(fs.existsSync(tmpobj.name + "/utils/fetch.js")).toBe(true);
72+
73+
tmpobj.removeCallback();
74+
});

0 commit comments

Comments
 (0)