1 |
|
2 | (function() {
|
3 | var access_exists, changecase, crystal, cson, debug, detail_types, fs, merge, mkdirp, mustache, pluralize, process, processModel;
|
4 |
|
5 | crystal = {
|
6 | format: require('./format')
|
7 | };
|
8 |
|
9 | changecase = require('change-case');
|
10 |
|
11 | cson = require('season');
|
12 |
|
13 | debug = require('debug')('build');
|
14 |
|
15 | fs = require('fs');
|
16 |
|
17 | merge = require('merge');
|
18 |
|
19 | mkdirp = require('mkdirp');
|
20 |
|
21 | mustache = require('mustache');
|
22 |
|
23 | pluralize = require('pluralize');
|
24 |
|
25 | detail_types = ['bool', 'child', 'created', 'date', 'deleted', 'decimal', 'email', 'id', 'model', 'number', 'parent', 'password', 'select', 'string', 'text', 'time', 'updated'];
|
26 |
|
27 | access_exists = function(role, arr) {
|
28 | var j, len, obj;
|
29 | for (j = 0, len = arr.length; j < len; j++) {
|
30 | obj = arr[j];
|
31 | if (obj.role.id === role) {
|
32 | return true;
|
33 | }
|
34 | }
|
35 | return false;
|
36 | };
|
37 |
|
38 | process = function(config, spec) {
|
39 | var gen, model, model_name;
|
40 | config = config || this.config;
|
41 | if (!config) {
|
42 | throw new Error('"config" required for process(config, spec)');
|
43 | }
|
44 | spec = spec || this.spec;
|
45 | if (!spec) {
|
46 | throw new Error('"spec" required for process(config, spec)');
|
47 | }
|
48 | gen = {};
|
49 | spec = merge.recursive(spec, config.spec || {});
|
50 | if (spec.models) {
|
51 | gen.model = {};
|
52 | gen.models = [];
|
53 | for (model_name in spec.models) {
|
54 | model = processModel(model_name, spec);
|
55 | gen.model[model_name] = model;
|
56 | gen.models.push(model);
|
57 | }
|
58 | }
|
59 | return gen;
|
60 | };
|
61 |
|
62 | processModel = function(model_name, spec) {
|
63 | var access, detail, detail_gen, detail_name, detail_options, i, model, model_gen, role, role_data;
|
64 | model = spec.models[model_name];
|
65 | if (!model.plural) {
|
66 | model.plural = pluralize(model_name);
|
67 | }
|
68 | model_gen = {
|
69 | access: {},
|
70 | has: {},
|
71 | id: model_name,
|
72 | name: crystal.format(model_name, model.plural)
|
73 | };
|
74 | model_gen.model = model_gen;
|
75 | if (model.details) {
|
76 | model_gen.detail = {};
|
77 | model_gen.details = [];
|
78 | for (detail_name in model.details) {
|
79 | detail = model.details[detail_name];
|
80 | if (!detail.plural) {
|
81 | detail.plural = pluralize(detail_name);
|
82 | }
|
83 | detail_gen = {
|
84 | access: {},
|
85 | "default": detail["default"],
|
86 | id: detail_name,
|
87 | name: crystal.format(detail_name, detail.plural)
|
88 | };
|
89 | detail_gen.detail = detail_gen;
|
90 | detail_gen.model = model_gen;
|
91 | if (model.access) {
|
92 | for (role in model.access) {
|
93 | if (Object.prototype.toString.call(model.access[role].permissions === '[object Object]')) {
|
94 | role_data = {
|
95 | role: {
|
96 | access: {
|
97 | create: false,
|
98 | read: false,
|
99 | update: false,
|
100 | "delete": false
|
101 | },
|
102 | name: crystal.format(role)
|
103 | }
|
104 | };
|
105 | for (access in model.access[role].permissions) {
|
106 | if (model.access[role].permissions[access] === '*' || model.access[role].permissions[access].indexOf(detail_name) !== -1) {
|
107 | if (!detail_gen.access[access]) {
|
108 | detail_gen.access[access] = {
|
109 | roles: []
|
110 | };
|
111 | }
|
112 | if (!model_gen.access[access]) {
|
113 | model_gen.access[access] = {
|
114 | roles: []
|
115 | };
|
116 | }
|
117 | if (!access_exists(role, detail_gen.access[access].roles)) {
|
118 | detail_gen.access[access].roles.push({
|
119 | role: {
|
120 | id: role,
|
121 | name: crystal.format(role)
|
122 | }
|
123 | });
|
124 | }
|
125 | if (!access_exists(role, model_gen.access[access].roles)) {
|
126 | model_gen.access[access].roles.push({
|
127 | role: {
|
128 | id: role,
|
129 | name: crystal.format(role)
|
130 | }
|
131 | });
|
132 | }
|
133 | }
|
134 | }
|
135 | } else if (model.access[role].permissions === '*' || model.access[role].permissions.indexOf(detail_name) !== -1) {
|
136 | if (!detail_gen.access.create) {
|
137 | detail_gen.access.create = {
|
138 | roles: []
|
139 | };
|
140 | detail_gen.access.create.detail = detail_gen;
|
141 | detail_gen.access.create.model = model_gen;
|
142 | }
|
143 | if (!detail_gen.access.read) {
|
144 | detail_gen.access.read = {
|
145 | roles: []
|
146 | };
|
147 | detail_gen.access.read.detail = detail_gen;
|
148 | detail_gen.access.read.model = model_gen;
|
149 | }
|
150 | if (!detail_gen.access.update) {
|
151 | detail_gen.access.update = {
|
152 | roles: []
|
153 | };
|
154 | detail_gen.access.update.detail = detail_gen;
|
155 | detail_gen.access.update.model = model_gen;
|
156 | }
|
157 | if (!detail_gen.access["delete"]) {
|
158 | detail_gen.access["delete"] = {
|
159 | roles: []
|
160 | };
|
161 | detail_gen.access["delete"].detail = detail_gen;
|
162 | detail_gen.access["delete"].model = model_gen;
|
163 | }
|
164 | if (!access_exists(role, detail_gen.access.create.roles)) {
|
165 | detail_gen.access.create.roles.push({
|
166 | role: {
|
167 | id: role,
|
168 | name: crystal.format(role)
|
169 | }
|
170 | });
|
171 | }
|
172 | if (!access_exists(role, detail_gen.access.read.roles)) {
|
173 | detail_gen.access.read.roles.push({
|
174 | role: {
|
175 | id: role,
|
176 | name: crystal.format(role)
|
177 | }
|
178 | });
|
179 | }
|
180 | if (!access_exists(role, detail_gen.access.update.roles)) {
|
181 | detail_gen.access.update.roles.push({
|
182 | role: {
|
183 | id: role,
|
184 | name: crystal.format(role)
|
185 | }
|
186 | });
|
187 | }
|
188 | if (!access_exists(role, detail_gen.access["delete"].roles)) {
|
189 | detail_gen.access["delete"].roles.push({
|
190 | role: {
|
191 | id: role,
|
192 | name: crystal.format(role)
|
193 | }
|
194 | });
|
195 | }
|
196 | if (!model_gen.access.create) {
|
197 | model_gen.access.create = {
|
198 | roles: []
|
199 | };
|
200 | }
|
201 | if (!model_gen.access.read) {
|
202 | model_gen.access.read = {
|
203 | roles: []
|
204 | };
|
205 | }
|
206 | if (!model_gen.access.update) {
|
207 | model_gen.access.update = {
|
208 | roles: []
|
209 | };
|
210 | }
|
211 | if (!model_gen.access["delete"]) {
|
212 | model_gen.access["delete"] = {
|
213 | roles: []
|
214 | };
|
215 | }
|
216 | if (!access_exists(role, model_gen.access.create.roles)) {
|
217 | model_gen.access.create.roles.push({
|
218 | role: {
|
219 | id: role,
|
220 | name: crystal.format(role)
|
221 | }
|
222 | });
|
223 | }
|
224 | if (!access_exists(role, model_gen.access.read.roles)) {
|
225 | model_gen.access.read.roles.push({
|
226 | role: {
|
227 | id: role,
|
228 | name: crystal.format(role)
|
229 | }
|
230 | });
|
231 | }
|
232 | if (!access_exists(role, model_gen.access.update.roles)) {
|
233 | model_gen.access.update.roles.push({
|
234 | role: {
|
235 | id: role,
|
236 | name: crystal.format(role)
|
237 | }
|
238 | });
|
239 | }
|
240 | if (!access_exists(role, model_gen.access["delete"].roles)) {
|
241 | model_gen.access["delete"].roles.push({
|
242 | role: {
|
243 | id: role,
|
244 | name: crystal.format(role)
|
245 | }
|
246 | });
|
247 | }
|
248 | }
|
249 | }
|
250 | }
|
251 | if (!detail_gen.access.create && !detail_gen.access.read && !detail_gen.access.update && !detail_gen.access["delete"]) {
|
252 | delete detail_gen.access;
|
253 | }
|
254 | if (detail.detail) {
|
255 | detail_gen.association = {};
|
256 | detail_gen.association.detail = {
|
257 | name: crystal.format(detail.detail)
|
258 | };
|
259 | }
|
260 | if (detail.model) {
|
261 | if (!detail_gen.association) {
|
262 | detail_gen.association = {};
|
263 | }
|
264 | detail_gen.association.model = {
|
265 | name: crystal.format(detail.model)
|
266 | };
|
267 | }
|
268 | if (detail.multiple !== void 0) {
|
269 | if (detail.multiple === true) {
|
270 | detail_gen.multiple = true;
|
271 | } else if (detail.multiple === false) {
|
272 | detail_gen.multiple = false;
|
273 | } else {
|
274 | debug('Invalid value for "multiple": %s', detail.multiple);
|
275 | }
|
276 | }
|
277 | if (detail.options) {
|
278 | detail_options = [];
|
279 | for (i in detail.options) {
|
280 | detail_options.push({
|
281 | option: detail.options[i]
|
282 | });
|
283 | }
|
284 | detail_gen.options = detail_options;
|
285 | }
|
286 | if (detail.required !== void 0) {
|
287 | if (detail.required === true) {
|
288 | detail_gen.required = true;
|
289 | } else if (detail.required === false) {
|
290 | detail_gen.required = false;
|
291 | } else {
|
292 | debug('Invalid value for "required": %s', detail.required);
|
293 | }
|
294 | }
|
295 | if (detail.type) {
|
296 | if (detail_types.indexOf(detail.type) === -1) {
|
297 | console.log("Unknown type (" + detail.type + ") for detail (" + detail_name + ")");
|
298 | } else {
|
299 | detail_gen.is = {};
|
300 | detail_gen.is[detail.type] = true;
|
301 | detail_gen.type = detail.type;
|
302 | model_gen.has[detail.type] = true;
|
303 | }
|
304 | }
|
305 | if (detail.unique !== void 0) {
|
306 | if (detail.unique === true) {
|
307 | detail_gen.unique = {
|
308 | is: {
|
309 | bool: true
|
310 | },
|
311 | value: true
|
312 | };
|
313 | } else if (detail.unique === false) {
|
314 | detail_gen.unique = {
|
315 | is: {
|
316 | bool: true
|
317 | },
|
318 | value: false
|
319 | };
|
320 | } else {
|
321 | detail_gen.unique = {
|
322 | is: {
|
323 | model: true
|
324 | },
|
325 | model: {
|
326 | name: crystal.format(detail.unique)
|
327 | },
|
328 | value: detail.unique
|
329 | };
|
330 | }
|
331 | }
|
332 | model_gen.detail[detail_name] = detail_gen;
|
333 | model_gen.details.push(detail_gen);
|
334 | }
|
335 | }
|
336 | if (!model_gen.access.create && !model_gen.access.read && !model_gen.access.update && !model_gen.access["delete"]) {
|
337 | delete model_gen.access;
|
338 | }
|
339 | return model_gen;
|
340 | };
|
341 |
|
342 | module.exports = process;
|
343 |
|
344 | }).call(this);
|