lanes 0.0.8 → 0.1.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.
- checksums.yaml +4 -4
- data/client/lanes/components/ChoicesInput.coffee +1 -1
- data/client/lanes/components/grid/Grid.coffee +4 -4
- data/client/lanes/components/grid/PopOverEditor.coffee +1 -1
- data/client/lanes/components/popover/PopOver.coffee +3 -3
- data/client/lanes/components/record_finder/RecordFinder.coffee +4 -4
- data/client/lanes/components/select_field/SelectField.coffee +1 -1
- data/client/lanes/extension/Base.coffee +1 -1
- data/client/lanes/extension/Extensions.coffee +3 -3
- data/client/lanes/extension/GlAccounts.coffee +2 -2
- data/client/lanes/lib/namespace.coffee +1 -1
- data/client/lanes/minimal.js +1 -1
- data/client/lanes/{data/Model.coffee → models/Base.coffee} +29 -47
- data/client/lanes/models/Bootstrap.coffee +8 -0
- data/client/lanes/{data → models}/ChangeSet.coffee +3 -3
- data/client/lanes/{data → models}/Collection.coffee +20 -40
- data/client/lanes/{data → models}/Config.coffee +2 -2
- data/client/lanes/{data → models}/PubSub.coffee +4 -3
- data/client/lanes/{data → models}/Query.coffee +7 -7
- data/client/lanes/{data → models}/Screens.coffee +12 -12
- data/client/lanes/models/Sync.coffee +86 -0
- data/client/lanes/{data → models}/User.coffee +8 -8
- data/client/lanes/{data → models}/index.js +1 -1
- data/client/lanes/{data → models}/mixins/HasCodeField.coffee +2 -2
- data/client/lanes/screens/Base.coffee +1 -1
- data/client/lanes/screens/ChangeListener.coffee +1 -1
- data/client/lanes/screens/Instance.coffee +3 -3
- data/client/lanes/screens/screen-definitions.js.erb +2 -2
- data/client/lanes/views/Base.coffee +10 -10
- data/client/lanes/views/ModelObserver.coffee +1 -1
- data/client/lanes/views/PubSub.coffee +4 -4
- data/client/lanes/views/Viewport.coffee +1 -1
- data/client/lanes/workspace/ActiveScreensSwitcher.coffee +1 -1
- data/client/lanes/workspace/Pages.coffee +2 -2
- data/client/lanes/workspace/ScreensMenu.coffee +1 -1
- data/lanes.gemspec +2 -1
- data/lib/lanes/command/generate_model.rb +6 -7
- data/lib/lanes/command/named_command.rb +1 -1
- data/lib/lanes/command/templates/client/index.js +1 -1
- data/lib/lanes/command/templates/client/{data → models}/Model.coffee +3 -7
- data/lib/lanes/command/templates/client/views/View.coffee +1 -1
- data/lib/lanes/command/templates/spec/client/models/ModelSpec.coffee +5 -0
- data/lib/lanes/command/update_model.rb +4 -11
- data/lib/lanes/command.rb +4 -3
- data/lib/lanes/version.rb +1 -1
- data/spec/helpers/lanes-helpers.coffee +5 -4
- data/spec/lanes/{data/ModelSpec.coffee → models/BaseSpec.coffee} +23 -11
- data/spec/lanes/{data → models}/PubSubSpec.coffee +6 -6
- data/views/specs.erb +1 -4
- metadata +19 -20
- data/client/lanes/data/Bootstrap.coffee +0 -8
- data/client/lanes/data/Sync.coffee +0 -63
- data/lib/lanes/command/templates/spec/client/data/ModelSpec.coffee +0 -5
- data/lib/lanes/spec_asset_expander.rb +0 -43
@@ -1,4 +1,4 @@
|
|
1
|
-
class ScreenView extends Lanes.
|
1
|
+
class ScreenView extends Lanes.Models.BasicModel
|
2
2
|
|
3
3
|
session:
|
4
4
|
screen: 'object'
|
@@ -18,18 +18,18 @@ class ScreenView extends Lanes.Data.BasicModel
|
|
18
18
|
initialize: (options)->
|
19
19
|
super
|
20
20
|
@screen=options.screen
|
21
|
-
Lanes.
|
21
|
+
Lanes.Models.Screens.displaying.add( this )
|
22
22
|
this.active=true
|
23
23
|
|
24
24
|
renderScreen: ->
|
25
25
|
this.view.render()
|
26
26
|
|
27
27
|
remove: ->
|
28
|
-
Lanes.
|
28
|
+
Lanes.Models.Screens.displaying.remove( this )
|
29
29
|
|
30
30
|
|
31
31
|
|
32
|
-
class ScreenDefinition extends Lanes.
|
32
|
+
class ScreenDefinition extends Lanes.Models.BasicModel
|
33
33
|
|
34
34
|
session:
|
35
35
|
id: 'string'
|
@@ -45,7 +45,7 @@ class ScreenDefinition extends Lanes.Data.BasicModel
|
|
45
45
|
derived:
|
46
46
|
model_type:
|
47
47
|
deps: ['model'], fn: ->
|
48
|
-
Lanes.getPath(this.model,"Lanes.
|
48
|
+
Lanes.getPath(this.model,"Lanes.Models")
|
49
49
|
|
50
50
|
initialize: ->
|
51
51
|
@views = []
|
@@ -95,7 +95,7 @@ class ScreenDefinition extends Lanes.Data.BasicModel
|
|
95
95
|
# Lanes.warn(failures)
|
96
96
|
|
97
97
|
|
98
|
-
class ScreenViewSet extends Lanes.
|
98
|
+
class ScreenViewSet extends Lanes.Models.BasicCollection
|
99
99
|
|
100
100
|
model: ScreenView
|
101
101
|
|
@@ -133,7 +133,7 @@ class ScreenViewSet extends Lanes.Data.BasicCollection
|
|
133
133
|
|
134
134
|
|
135
135
|
|
136
|
-
class ScreenSet extends Lanes.
|
136
|
+
class ScreenSet extends Lanes.Models.BasicCollection
|
137
137
|
|
138
138
|
model: ScreenDefinition
|
139
139
|
|
@@ -145,7 +145,7 @@ class ScreenSet extends Lanes.Data.BasicCollection
|
|
145
145
|
|
146
146
|
|
147
147
|
|
148
|
-
class MenuGroup extends Lanes.
|
148
|
+
class MenuGroup extends Lanes.Models.BasicModel
|
149
149
|
|
150
150
|
session:
|
151
151
|
id: 'string'
|
@@ -155,18 +155,18 @@ class MenuGroup extends Lanes.Data.BasicModel
|
|
155
155
|
active: ['boolean', true, false]
|
156
156
|
|
157
157
|
screens: ->
|
158
|
-
@avail ||= new Lanes.
|
158
|
+
@avail ||= new Lanes.Models.SubCollection( Lanes.Models.Screens.all, {
|
159
159
|
filter: (screen)=>
|
160
160
|
screen.group_id == @id && Lanes.current_user.canRead(screen.model_type)
|
161
161
|
watched: ['group_id']
|
162
162
|
})
|
163
163
|
|
164
|
-
class MenuGroupSet extends Lanes.
|
164
|
+
class MenuGroupSet extends Lanes.Models.BasicCollection
|
165
165
|
constructor: -> super
|
166
166
|
model: MenuGroup
|
167
167
|
|
168
168
|
available: ->
|
169
|
-
@avail ||= new Lanes.
|
169
|
+
@avail ||= new Lanes.Models.SubCollection(this, {
|
170
170
|
filter: (mgs)=>
|
171
171
|
mgs.screens().filter()
|
172
172
|
mgs.screens().length > 0
|
@@ -174,7 +174,7 @@ class MenuGroupSet extends Lanes.Data.BasicCollection
|
|
174
174
|
|
175
175
|
|
176
176
|
|
177
|
-
Lanes.
|
177
|
+
Lanes.Models.Screens = {
|
178
178
|
all: new ScreenSet
|
179
179
|
displaying: new ScreenViewSet([],{ single_active_only: true })
|
180
180
|
groups: new MenuGroupSet
|
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
# a simple reimplentation
|
3
|
+
# to use traffic cop
|
4
|
+
methodMap = {
|
5
|
+
'create': 'POST',
|
6
|
+
'update': 'PUT',
|
7
|
+
'patch': 'PATCH',
|
8
|
+
'delete': 'DELETE',
|
9
|
+
'read': 'GET'
|
10
|
+
}
|
11
|
+
|
12
|
+
getValue = (object, prop)->
|
13
|
+
if !(object && object[prop])
|
14
|
+
return null;
|
15
|
+
return if _.isFunction(object[prop]) then object[prop]() else object[prop];
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
paramsMap = {
|
21
|
+
fields : 'f'
|
22
|
+
with : 'w'
|
23
|
+
query : 'q'
|
24
|
+
include : 'i'
|
25
|
+
order : 'o'
|
26
|
+
limit : 'l'
|
27
|
+
start : 's'
|
28
|
+
format : 'df'
|
29
|
+
}
|
30
|
+
|
31
|
+
Lanes.Models.Sync = {
|
32
|
+
urlError: ->
|
33
|
+
throw new Error('A "url" property or function must be specified')
|
34
|
+
|
35
|
+
copyServerReply: (record, reply)->
|
36
|
+
record.errors = reply?.errors
|
37
|
+
record.lastServerMessage = reply?.message
|
38
|
+
{ record: record, reply: reply }
|
39
|
+
|
40
|
+
# Wraps a sync request's error and success functions
|
41
|
+
# Copies any errors onto the model and sets it's data on success
|
42
|
+
wrapRequest: (record, options)->
|
43
|
+
error = options.error
|
44
|
+
success = options.success
|
45
|
+
options.promise = new _.Promise( (resolve,reject)->
|
46
|
+
options.resolvePromise = resolve
|
47
|
+
options.rejectPromise = reject
|
48
|
+
)
|
49
|
+
options.error = (reply, resp, req)->
|
50
|
+
options.rejectPromise( this.copyServerResp(record,resp.responseJSON || {error: resp.responseText}) )
|
51
|
+
error?.apply(options.scope, arguments)
|
52
|
+
|
53
|
+
options.success = (reply,resp,req)->
|
54
|
+
record.setFromServer( reply.data, options ) if reply?.data?
|
55
|
+
options.resolvePromise( Lanes.Models.Sync.copyServerReply(record,reply) )
|
56
|
+
success?.apply(options.scope, arguments)
|
57
|
+
options
|
58
|
+
|
59
|
+
perform: (method, model, options={})->
|
60
|
+
query = {}
|
61
|
+
for key, value of options
|
62
|
+
query[ paramsMap[key] ] = value if paramsMap[key]
|
63
|
+
|
64
|
+
# Default JSON-request options.
|
65
|
+
params = {
|
66
|
+
type: methodMap[method]
|
67
|
+
dataType: "json"
|
68
|
+
data: query
|
69
|
+
}
|
70
|
+
|
71
|
+
# Ensure that we have a URL.
|
72
|
+
params.url = _.result(model, "url") or Lanes.Models.Sync.urlError() unless options.url
|
73
|
+
params.url += '.json'
|
74
|
+
params.headers = {
|
75
|
+
X_CSRF_TOKEN: Lanes.Models.Config.csrf_token
|
76
|
+
}
|
77
|
+
params.contentType = "application/json"
|
78
|
+
if options.data || _.contains(['create','update','patch'], method)
|
79
|
+
params.data = JSON.stringify( options.data || model.dataForSave(options) )
|
80
|
+
delete options.data
|
81
|
+
|
82
|
+
# Make the request, allowing the user to override any Ajax options.
|
83
|
+
xhr = options.xhr = Lanes.$.ajax(_.extend(params, options))
|
84
|
+
model.trigger "request", model, xhr, options
|
85
|
+
xhr
|
86
|
+
}
|
@@ -1,17 +1,17 @@
|
|
1
|
-
unless Lanes.
|
1
|
+
unless Lanes.Models.Roles
|
2
2
|
|
3
|
-
class Lanes.
|
3
|
+
class Lanes.Models.Role extends Lanes.Models.BasicModel
|
4
4
|
props:
|
5
5
|
id: 'string'
|
6
6
|
name: 'string'
|
7
7
|
member: { type: 'boolean', default: false }
|
8
8
|
|
9
|
-
class Lanes.
|
10
|
-
model: Lanes.
|
9
|
+
class Lanes.Models.Roles extends Lanes.Models.BasicCollection
|
10
|
+
model: Lanes.Models.Role
|
11
11
|
|
12
12
|
|
13
|
-
unless Lanes.
|
14
|
-
class Lanes.
|
13
|
+
unless Lanes.Models.User
|
14
|
+
class Lanes.Models.User extends Lanes.Models.Base
|
15
15
|
|
16
16
|
constructor: (attributes,access)->
|
17
17
|
super
|
@@ -24,7 +24,7 @@ unless Lanes.Data.User
|
|
24
24
|
isLoggedIn:
|
25
25
|
fn: -> false
|
26
26
|
allRoles:
|
27
|
-
fn: -> new Lanes.
|
27
|
+
fn: -> new Lanes.Models.Roles
|
28
28
|
|
29
29
|
session:
|
30
30
|
access_data: 'object'
|
@@ -43,4 +43,4 @@ unless Lanes.Data.User
|
|
43
43
|
canDelete: (model) -> true
|
44
44
|
|
45
45
|
unless Lanes.current_user
|
46
|
-
Lanes.current_user = new Lanes.
|
46
|
+
Lanes.current_user = new Lanes.Models.User
|
@@ -1,9 +1,9 @@
|
|
1
|
-
Lanes.
|
1
|
+
Lanes.Models.Mixins.HasCodeField = {
|
2
2
|
|
3
3
|
INVALID: /[^A-Z0-9a-z]/
|
4
4
|
|
5
5
|
included: ->
|
6
|
-
this.prototype.INVALID_CODE_CLanes.RS ||= Lanes.
|
6
|
+
this.prototype.INVALID_CODE_CLanes.RS ||= Lanes.Models.mixins.Lanes.sCodeField.INVALID
|
7
7
|
|
8
8
|
initialize: ->
|
9
9
|
this.on('change:code', this.upcaseCode )
|
@@ -17,7 +17,7 @@ class ScreenBase
|
|
17
17
|
reset: Lanes.emptyFn
|
18
18
|
|
19
19
|
template: ->
|
20
|
-
this.
|
20
|
+
this.FILE.extension.toLowerCase() + "/screens/" + _.underscore( this.FILE.file ) + "/layout";
|
21
21
|
|
22
22
|
render: ->
|
23
23
|
previouslyRendered = this.rendered
|
@@ -11,7 +11,7 @@ Lanes.Screens.ChangeListener = {
|
|
11
11
|
|
12
12
|
derived:
|
13
13
|
changes: deps:[], fn: ->
|
14
|
-
new Lanes.
|
14
|
+
new Lanes.Models.ChangeSetCollection([],{ parent: this })
|
15
15
|
changes_visible: { deps: ['change_count'], fn:-> @change_count > 0 }
|
16
16
|
|
17
17
|
bindings:
|
@@ -6,7 +6,7 @@ class Lanes.Screens.Instance
|
|
6
6
|
|
7
7
|
constructor: (selector, options)->
|
8
8
|
this.viewport = new Lanes.Views.Viewport({ selector: selector, instance: this });
|
9
|
-
Lanes.
|
9
|
+
Lanes.Models.Bootstrap.initialize(options);
|
10
10
|
Lanes.$(document).ready => @boot(options)
|
11
11
|
|
12
12
|
boot: (options)->
|
@@ -25,13 +25,13 @@ class Lanes.Screens.Instance
|
|
25
25
|
title: => @getAttribute('data-tooltip-message')
|
26
26
|
});
|
27
27
|
Lanes.Views.Keys.initialize();
|
28
|
-
Lanes.
|
28
|
+
Lanes.Models.PubSub.initialize() if options.pub_sub;
|
29
29
|
|
30
30
|
view = Lanes.getPath(options.root_view);
|
31
31
|
if view
|
32
32
|
this.displayInitialView(view);
|
33
33
|
else
|
34
|
-
definition=Lanes.
|
34
|
+
definition=Lanes.Models.Screens.all.findWhere({view: options.root_view});
|
35
35
|
if definition
|
36
36
|
definition.getScreen().then( (screen)=>
|
37
37
|
# break out of the promise so an errors during render get thrown properly
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% Lanes::Screens::Group.each(self) do | spec | %>
|
2
|
-
Lanes.
|
2
|
+
Lanes.Models.Screens.groups.add( <%= spec.to_json %> );
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<% Lanes::Screens::Definition.each(self) do | spec | %>
|
6
|
-
Lanes.
|
6
|
+
Lanes.Models.Screens.register( <%= spec.to_json %> );
|
7
7
|
<% end %>
|
@@ -42,7 +42,7 @@ class ViewBase
|
|
42
42
|
rendered:
|
43
43
|
deps: ["el"], fn: -> !!@el
|
44
44
|
|
45
|
-
|
45
|
+
hasModels:
|
46
46
|
deps: ["model"], fn: -> !!@model
|
47
47
|
|
48
48
|
viewport:
|
@@ -147,8 +147,8 @@ class ViewBase
|
|
147
147
|
renderWithTemplate: (templateArg)->
|
148
148
|
template = templateArg || this.resultsFor('template')
|
149
149
|
throw new Error('Template string or function needed.') unless template
|
150
|
-
template_fn = Lanes.Templates.find(template, this.
|
151
|
-
newDom = if template_fn then template_fn( _.result(this,'
|
150
|
+
template_fn = Lanes.Templates.find(template, this.FILE.extension)
|
151
|
+
newDom = if template_fn then template_fn( _.result(this,'templateModels')) else template
|
152
152
|
newDom = Lanes.Vendor.domify(newDom) if _.isString(newDom);
|
153
153
|
parent = this.el && this.el.parentNode;
|
154
154
|
parent.replaceChild(newDom, this.el) if parent
|
@@ -159,18 +159,18 @@ class ViewBase
|
|
159
159
|
this.el = newDom;
|
160
160
|
return this;
|
161
161
|
|
162
|
-
templateName: -> _.underscore( this.
|
162
|
+
templateName: -> _.underscore( this.FILE.file )
|
163
163
|
|
164
164
|
template: ->
|
165
|
-
this.
|
165
|
+
this.FILE.extension.toLowerCase() + "/views/" + _.result(this,'templateName')
|
166
166
|
|
167
|
-
|
167
|
+
FILE: FILE
|
168
168
|
|
169
|
-
|
169
|
+
templateModels: ->
|
170
170
|
{ model: this.model, collection: this.collection }
|
171
171
|
|
172
172
|
renderTemplate:(name,data={})->
|
173
|
-
template = Lanes.Templates.find(name, this.
|
173
|
+
template = Lanes.Templates.find(name, this.FILE.name)
|
174
174
|
if template
|
175
175
|
template(data)
|
176
176
|
else
|
@@ -179,7 +179,7 @@ class ViewBase
|
|
179
179
|
|
180
180
|
renderTemplateMethod: (method)->
|
181
181
|
return null unless name = _.result(this, method)
|
182
|
-
this.renderTemplate(name, _.result(this, "#{method}
|
182
|
+
this.renderTemplate(name, _.result(this, "#{method}Models") || @model)
|
183
183
|
|
184
184
|
|
185
185
|
# Remove this view by taking the element out of the DOM, and removing any
|
@@ -302,7 +302,7 @@ class ViewBase
|
|
302
302
|
Lanes.getPath(subview.component, Lanes.Components)
|
303
303
|
else if subview.view
|
304
304
|
if _.isString(subview.view)
|
305
|
-
Lanes.getPath(subview.view, this.
|
305
|
+
Lanes.getPath(subview.view, this.FILE.namespace['Views'] )
|
306
306
|
else
|
307
307
|
subview.view
|
308
308
|
Lanes.warn( "Unable to obtain view for %o", subview) if ! klass
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Responsible for adding and removing a view's model(s) from
|
1
|
+
# Responsible for adding and removing a view's model(s) from Models.PubSub
|
2
2
|
class Lanes.Views.PubSub extends Lanes.Views.ModelObserver
|
3
3
|
|
4
4
|
model_events:
|
@@ -17,13 +17,13 @@ class Lanes.Views.PubSub extends Lanes.Views.ModelObserver
|
|
17
17
|
this.showUpdate(field) if field = @view.query("[name=#{field}]")
|
18
18
|
|
19
19
|
bindModel: (model)->
|
20
|
-
Lanes.
|
20
|
+
Lanes.Models.PubSub.add(model)
|
21
21
|
super
|
22
22
|
|
23
23
|
unBindModel: (model)->
|
24
|
-
Lanes.
|
24
|
+
Lanes.Models.PubSub.remove(model)
|
25
25
|
super
|
26
26
|
|
27
27
|
teardown: ->
|
28
28
|
super
|
29
|
-
Lanes.
|
29
|
+
Lanes.Models.PubSub.remove(model) if model = this.getModel()
|
@@ -51,7 +51,7 @@ class Lanes.Workspace.ActiveScreenSwitcher extends Lanes.Views.Base
|
|
51
51
|
constructor: ->
|
52
52
|
super
|
53
53
|
_.bindAll(this, 'resetShownControls')
|
54
|
-
@collection = Lanes.
|
54
|
+
@collection = Lanes.Models.Screens.displaying
|
55
55
|
this.listenTo( @collection, "change:active", this.onActiveChange )
|
56
56
|
this.listenTo( this.viewport, "change:width", this.resetShownControls )
|
57
57
|
this.listenTo( Lanes.current_user, "change:isLoggedIn", this.closeScreens)
|
@@ -17,8 +17,8 @@ class Lanes.Workspace.Pages extends Lanes.Views.Base
|
|
17
17
|
screens_menu_container: '.screens-menu-container'
|
18
18
|
|
19
19
|
initialize: (options)->
|
20
|
-
this.listenTo( Lanes.
|
21
|
-
this.listenTo( Lanes.
|
20
|
+
this.listenTo( Lanes.Models.Screens.displaying, "change:active", this.onActiveChange )
|
21
|
+
this.listenTo( Lanes.Models.Screens.displaying, "remove", this.onRemove )
|
22
22
|
this.listenTo( @model,'change:screen_menu_position', this.moveScreensMenu )
|
23
23
|
super
|
24
24
|
|
@@ -71,7 +71,7 @@ class Lanes.Workspace.ScreensMenu extends Lanes.Views.Base
|
|
71
71
|
initialize: ->
|
72
72
|
super
|
73
73
|
this.listenTo(Lanes.current_user, "change:isLoggedIn", this.resetGroups)
|
74
|
-
@groups = Lanes.
|
74
|
+
@groups = Lanes.Models.Screens.groups.available()
|
75
75
|
this
|
76
76
|
|
77
77
|
resetGroups: ->
|
data/lanes.gemspec
CHANGED
@@ -13,7 +13,8 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.summary = %q{Lanes is a framework for easily writing single page web applications}
|
14
14
|
spec.description = %q{Lanes is a framework for writing single page web applications. It's a full stack framework that contains both server and client.}
|
15
15
|
|
16
|
-
spec.homepage = "http://
|
16
|
+
spec.homepage = "http://lanesframework.org/"
|
17
|
+
|
17
18
|
spec.license = "MIT"
|
18
19
|
|
19
20
|
spec.files = `git ls-files`.split($/)
|
@@ -7,8 +7,7 @@ module Lanes
|
|
7
7
|
RESERVED_YAML_KEYWORDS = %w(y yes n no true false on off null)
|
8
8
|
OPTIONS ||= {
|
9
9
|
timestamps: true,
|
10
|
-
parent: "Lanes::Model"
|
11
|
-
client_collection_parent: "Lanes.Data.Collection"
|
10
|
+
parent: "Lanes::Model"
|
12
11
|
}
|
13
12
|
|
14
13
|
class_options OPTIONS
|
@@ -42,10 +41,10 @@ module Lanes
|
|
42
41
|
|
43
42
|
def create_client
|
44
43
|
self.fields.unshift ModelAttribute.parse("id:integer")
|
45
|
-
template "client/
|
46
|
-
"#{client_dir}/
|
47
|
-
template "spec/client/
|
48
|
-
"#{spec_dir}/
|
44
|
+
template "client/models/Model.coffee", \
|
45
|
+
"#{client_dir}/models/#{class_name}.coffee"
|
46
|
+
template "spec/client/models/ModelSpec.coffee", \
|
47
|
+
"#{spec_dir}/models/#{class_name}Spec.coffee"
|
49
48
|
end
|
50
49
|
|
51
50
|
def add_route
|
@@ -86,7 +85,7 @@ module Lanes
|
|
86
85
|
|
87
86
|
def client_parent
|
88
87
|
if options[:parent] == 'Lanes::Model'
|
89
|
-
"Lanes.
|
88
|
+
"Lanes.Models.Base"
|
90
89
|
else
|
91
90
|
"Lanes.#{namespace.camelize}.#{options[:parent]}"
|
92
91
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class <%= namespace.camelize %>.
|
1
|
+
class <%= namespace.camelize %>.Models.<%= class_name %> extends <%= client_parent %>
|
2
2
|
|
3
3
|
api_path: '<%= name.downcase.pluralize.underscore.dasherize %>'
|
4
|
-
|
4
|
+
FILE: FILE
|
5
5
|
|
6
6
|
props:
|
7
7
|
<% fields.each do |field| -%>
|
@@ -15,10 +15,6 @@ class <%= namespace.camelize %>.Data.<%= class_name %> extends <%= client_parent
|
|
15
15
|
|
16
16
|
associations:
|
17
17
|
<% reference_fields.each do |field| -%>
|
18
|
-
<%= sprintf("%-#{max_field_length}s ",field.name) %>: { <%= field.belongs_to? ? 'model' : 'collection' -%>: "
|
18
|
+
<%= sprintf("%-#{max_field_length}s ",field.name) %>: { <%= field.belongs_to? ? 'model' : 'collection' -%>: "<%= namespace.camelize %>.<%= field.name.camelize %>" }
|
19
19
|
<% end -%>
|
20
20
|
<% end -%>
|
21
|
-
|
22
|
-
class <%= namespace.camelize %>.Data.<%= class_name %>Collection extends <%= options[:client_collection_parent] %>
|
23
|
-
|
24
|
-
model: <%= namespace.camelize %>.Data.<%= class_name %>
|
@@ -3,22 +3,15 @@ require_relative 'model_attribute'
|
|
3
3
|
module Lanes
|
4
4
|
module Command
|
5
5
|
|
6
|
-
class UpdateModel <
|
6
|
+
class UpdateModel < NamedCommand
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
argument :name
|
11
|
-
attr_reader :namespace, :class_name, :namespaced_name
|
12
|
-
|
13
|
-
def self.source_root
|
14
|
-
Pathname.new(__FILE__).dirname.join("templates")
|
15
|
-
end
|
8
|
+
attr_reader :namespaced_name
|
16
9
|
|
17
10
|
def read_class
|
18
11
|
if name=~/::/
|
19
12
|
(@namespace,@name) = name.split("::")
|
20
13
|
else
|
21
|
-
ext = Command.load_current_extension
|
14
|
+
ext = Command.load_current_extension(raise_on_fail:true)
|
22
15
|
@namespace = ext.identifier
|
23
16
|
end
|
24
17
|
class_name = name.camelize
|
@@ -27,7 +20,7 @@ module Lanes
|
|
27
20
|
if !@klass
|
28
21
|
raise Thor::Error.new("#{namespaced_name} was not found")
|
29
22
|
end
|
30
|
-
@file = Pathname.new("
|
23
|
+
@file = Pathname.new(client_dir).join("models/#{class_name}.coffee")
|
31
24
|
unless @file.exist?
|
32
25
|
raise Thor::Error.new("Model #{@file} doesn't exist")
|
33
26
|
end
|
data/lib/lanes/command.rb
CHANGED
@@ -25,8 +25,9 @@ module Lanes
|
|
25
25
|
if ext
|
26
26
|
begin
|
27
27
|
require(ext)
|
28
|
-
rescue
|
29
|
-
|
28
|
+
rescue =>e
|
29
|
+
stack = e.backtrace[0..4].join("\n")
|
30
|
+
raise Thor::Error.new("Loading ./lib/*/extension.rb failed with: #{e}\n#{stack}")
|
30
31
|
end
|
31
32
|
all = Extensions.all
|
32
33
|
if all.any?
|
@@ -39,7 +40,7 @@ module Lanes
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def _maybe_fail(should_raise)
|
42
|
-
raise Thor::Error.new("Unable to locate Lanes environment") if should_raise
|
43
|
+
raise Thor::Error.new("Unable to locate Lanes environment.\nDoes ./lib/*/extension.rb exist?") if should_raise
|
43
44
|
return nil
|
44
45
|
end
|
45
46
|
end
|
data/lib/lanes/version.rb
CHANGED
@@ -11,7 +11,7 @@ Lanes.Vendor.MessageBus = {
|
|
11
11
|
start: Lanes.emptyFn
|
12
12
|
}
|
13
13
|
|
14
|
-
class Lanes.Testing.Model extends Lanes.
|
14
|
+
class Lanes.Testing.Model extends Lanes.Models.Base
|
15
15
|
api_path: "test"
|
16
16
|
props:
|
17
17
|
id: 'number',
|
@@ -29,7 +29,7 @@ class Lanes.Testing.Model extends Lanes.Data.Model
|
|
29
29
|
deps: ['something', 'fireDanger', 'active'],
|
30
30
|
fn: -> this.something + this.active;
|
31
31
|
|
32
|
-
class Lanes.Testing.Collection extends Lanes.
|
32
|
+
class Lanes.Testing.Collection extends Lanes.Models.Collection
|
33
33
|
model: Lanes.Testing.Model
|
34
34
|
|
35
35
|
syncResponse = (method,model,options)->
|
@@ -37,6 +37,7 @@ syncResponse = (method,model,options)->
|
|
37
37
|
options.success(model, syncReply, {})
|
38
38
|
if options.failure && !syncReply.success
|
39
39
|
options.failure(model, syncReply, {})
|
40
|
+
_.Promise.resolve(model,options)
|
40
41
|
|
41
42
|
syncReply = {}
|
42
43
|
|
@@ -55,7 +56,7 @@ beforeEach ->
|
|
55
56
|
Lanes.Testing.syncSpy = jasmine.createSpy('sync').and.callFake(syncResponse)
|
56
57
|
Lanes.Testing.syncSpy.lastOptions = ->
|
57
58
|
this.calls.mostRecent().args[2]
|
58
|
-
Lanes.
|
59
|
-
Lanes.
|
59
|
+
Lanes.Models.Base::sync = Lanes.Testing.syncSpy
|
60
|
+
Lanes.Models.Collection::sync = Lanes.Testing.syncSpy
|
60
61
|
|
61
62
|
|