volt 0.8.21 → 0.8.22.beta1

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +15 -10
  3. data/CHANGELOG.md +8 -0
  4. data/Gemfile +7 -33
  5. data/Readme.md +2 -0
  6. data/VERSION +1 -1
  7. data/app/volt/assets/js/{setImmediate.js → volt_js_polyfills.js} +14 -0
  8. data/app/volt/models/user.rb +21 -26
  9. data/app/volt/tasks/live_query/data_store.rb +4 -0
  10. data/app/volt/tasks/store_tasks.rb +8 -11
  11. data/app/volt/tasks/user_tasks.rb +18 -17
  12. data/lib/volt.rb +7 -1
  13. data/lib/volt/cli.rb +2 -0
  14. data/lib/volt/config.rb +69 -29
  15. data/lib/volt/extra_core/object.rb +8 -0
  16. data/lib/volt/models/model_hash_behaviour.rb +26 -6
  17. data/lib/volt/models/persistors/model_store.rb +1 -2
  18. data/lib/volt/models/validations.rb +18 -9
  19. data/lib/volt/models/validators/length_validator.rb +1 -1
  20. data/lib/volt/models/validators/presence_validator.rb +1 -1
  21. data/lib/volt/models/validators/unique_validator.rb +1 -1
  22. data/lib/volt/page/bindings/template_binding.rb +2 -1
  23. data/lib/volt/page/page.rb +7 -2
  24. data/lib/volt/page/sub_context.rb +8 -4
  25. data/lib/volt/page/targets/base_section.rb +1 -1
  26. data/lib/volt/page/targets/dom_template.rb +1 -1
  27. data/lib/volt/server.rb +3 -2
  28. data/lib/volt/server/html_parser/view_scope.rb +1 -0
  29. data/lib/volt/server/rack/component_code.rb +8 -1
  30. data/lib/volt/server/rack/component_paths.rb +2 -1
  31. data/lib/volt/server/rack/quiet_common_logger.rb +34 -0
  32. data/lib/volt/spec/setup.rb +30 -1
  33. data/lib/volt/utils/generic_pool.rb +4 -0
  34. data/lib/volt/volt/users.rb +18 -0
  35. data/spec/apps/kitchen_sink/Gemfile +3 -0
  36. data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +6 -0
  37. data/spec/apps/kitchen_sink/app/main/config/routes.rb +5 -1
  38. data/spec/apps/kitchen_sink/app/main/models/user.rb +2 -0
  39. data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -1
  40. data/spec/apps/kitchen_sink/{public → config/base}/index.html +0 -0
  41. data/spec/integration/bindings_spec.rb +1 -1
  42. data/spec/integration/cookies_spec.rb +1 -1
  43. data/spec/integration/flash_spec.rb +3 -2
  44. data/spec/integration/list_spec.rb +1 -1
  45. data/spec/integration/templates_spec.rb +1 -1
  46. data/spec/integration/url_spec.rb +1 -1
  47. data/spec/integration/user_spec.rb +60 -0
  48. data/spec/models/model_spec.rb +0 -1
  49. data/spec/page/bindings/template_binding_spec.rb +0 -4
  50. data/spec/server/rack/asset_files_spec.rb +1 -1
  51. data/spec/spec_helper.rb +5 -0
  52. data/templates/component/tasks/.empty_directory +0 -0
  53. data/templates/newgem/app/newgem/views/main/{main.html → index.html} +0 -0
  54. data/templates/project/Gemfile.tt +0 -11
  55. data/templates/project/app/main/config/routes.rb +5 -0
  56. data/templates/project/app/main/tasks/.empty_directory +0 -0
  57. data/templates/project/app/main/views/main/main.html.tt +1 -0
  58. data/templates/project/config/app.rb.tt +8 -3
  59. data/volt.gemspec +4 -6
  60. metadata +58 -12
  61. data/spec/apps/kitchen_sink/app/main/controllers/users_test_controller.rb +0 -27
  62. data/spec/apps/kitchen_sink/app/main/views/users_test/index.html +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a638546992d567cf43d90ee011ecf7f30fa5880f
4
- data.tar.gz: c9d05f29f59cd52ff900ae25e0176536fc4842b6
3
+ metadata.gz: 710bbd40c4e0f2a2ee402f97df5d82d1a6a57704
4
+ data.tar.gz: d21e4a67eb50b440710ab0abbd20f5c4b90da1ca
5
5
  SHA512:
6
- metadata.gz: 4bb40aeba3bb1ffb8d680dc636ab2f4f0c2dfd64ee408994aa502f018a04729a8cd357b55c526c60ad7855b9c91f4635c75510abd445776d67a4e429e6217f37
7
- data.tar.gz: 72c91c7a5390e3c7bda4e02861dc108504b56422f36a1d787ec47abcc22ed754ccfb323ccab08282a9d2b8fa2fbcaac9f670a88116edee581bcde044598c9a0a
6
+ metadata.gz: 1b544c000e50d4760a799bb63ae4a90a772b2dddff295063c93316dc09335c6c7664b97cc05d77d361dfb587298b90800ad62608a567e224179b9e10e5bb3034
7
+ data.tar.gz: 63cca01208dd44244a9aeae62319c1187e8bd393846e1f904277a7f0ee021eecfe8d6573bfce15c85b66c36179eced0396e19e09a3eaeba89fd821174a6f6aef
data/.travis.yml CHANGED
@@ -1,16 +1,21 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.1.0"
4
- - "2.1.1"
5
- - "2.1.2"
6
- - "2.1.3"
7
- # - jruby-19mode # JRuby in 1.9 mode
8
- # - rbx
3
+ - 2.1.0
4
+ - 2.1.1
5
+ - 2.1.2
6
+ - 2.1.3
7
+ env:
8
+ global:
9
+ - secure: W03bt+hqLkAenymipqADIuRGZMiqu/sKx+9PXJJzCy0qAgmKs/PhPpHRpGpSmaYvVQQuiWX/rsw7xWXc2CHDJSp5aInd693xhJuSKXmnUp00r14/io+VWI9LE0lWjx4qdb6YQhdBTaxJB0+1sHDwU088yWBNnri/KwU4UlUgO5M=
10
+ - secure: X95q9DUVJRLIoxd116xEbi/3xL85XiGbWdz0p5z/UawShQalMHxLfPNdU9u5gyw99LrgxTdPsJOTps8hB3vhzp8qIegrM8i2AICcicXC1QDOWi7McXSH9SBmE1AjhlyE/PLLHwLDeqfvwNMPAOrDH1GOisQp505D7SSXUZ9m0GI=
11
+ matrix:
12
+ - NO_BROWSER=true
13
+ - BROWSER=sauce OS="Windows 8" USE_BROWSER="Firefox" VERSION="33"
9
14
  script: bundle exec rake
10
15
  notifications:
11
16
  webhooks:
12
17
  urls:
13
- - https://webhooks.gitter.im/e/046f551739ef8cf19b8c
14
- on_success: change # options: [always|never|change] default: always
15
- on_failure: always # options: [always|never|change] default: always
16
- on_start: false # default: false
18
+ - https://webhooks.gitter.im/e/046f551739ef8cf19b8c
19
+ on_success: change
20
+ on_failure: always
21
+ on_start: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.8.22 - 2014-...
4
+ ### Added
5
+ - Volt.config is now accessable from the client.
6
+
7
+ ## 0.8.21 - 2014-11-05
8
+ ### Changed
9
+ - fix merge conflict
10
+
3
11
  ## 0.8.20 - 2014-11-05
4
12
  ### Changed
5
13
  - fix secure random bug from 0.8.19 :-)
data/Gemfile CHANGED
@@ -2,35 +2,6 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- # gem 'rspec', '3.0.0.beta1'
6
- # gem 'opal', git: 'https://github.com/opal/opal.git'
7
- # gem 'opal-jquery', :git => 'https://github.com/opal/opal-jquery.git'
8
-
9
- #---------------------
10
- # Needed at the moment
11
- gem 'volt-sockjs', require: false, platforms: :mri
12
-
13
- # gem 'thor'
14
-
15
- # gem 'rack'
16
- # gem 'sprockets'
17
- # gem 'sprockets-sass'
18
- # gem 'sass'
19
-
20
- # gem 'mongo', require: false
21
- # gem 'pry', require: false
22
- # gem 'thin', require: false, platforms: :mri
23
-
24
- # Json parsing with multi_json, et al
25
- # gem 'multi_json'
26
- # gem 'oj', :platforms => :mri, :require => false
27
- # gem 'jrjackson', :platforms => :jruby, :require => false
28
-
29
- # gem 'rake', '10.0.4'
30
-
31
- # # Needed to get opal to work on rbx
32
- # gem 'racc', platforms: :rbx
33
-
34
5
  group :development do
35
6
  # For testing the kitchen sink app
36
7
  # Twitter bootstrap
@@ -39,11 +10,14 @@ group :development do
39
10
  # Simple theme for bootstrap, remove to theme yourself.
40
11
  gem 'volt-bootstrap-jumbotron-theme'
41
12
 
13
+ # For testing
14
+ gem 'volt-fields'
15
+
16
+ # For testing
17
+ gem 'volt-user-templates'
18
+
19
+ # For running rubocop
42
20
  gem 'rubocop', require: false
43
- # gem 'guard', '2.0.1' # bug in current guard
44
- # gem 'guard-rspec'
45
- # gem 'opal-rspec', '0.3.0.beta2'#, git: 'https://github.com/adambeynon/opal-rspec.git'
46
- # gem 'yard', require: false
47
21
  end
48
22
 
49
23
  group :development, :test do
data/Readme.md CHANGED
@@ -35,3 +35,5 @@ Read the [full docs on Volt here](http://voltframework.com/docs)
35
35
  You want to contribute? Great! Thanks for being awesome! At the moment, we have a big internal todo list, hop on https://gitter.im/voltrb/volt so we don't duplicate work. Pull requests are always welcome, but asking about helping on gitter should save some duplication.
36
36
 
37
37
  [![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)
38
+
39
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.21
1
+ 0.8.22.beta1
@@ -1,3 +1,17 @@
1
+ // For phantomjs
2
+
3
+ // Bind
4
+ if (!Function.prototype.bind) {
5
+ Function.prototype.bind = function (scope) {
6
+ var fn = this;
7
+ return function () {
8
+ return fn.apply(scope);
9
+ };
10
+ };
11
+ }
12
+
13
+
14
+ // setImmediate
1
15
  (function (global, undefined) {
2
16
  "use strict";
3
17
 
@@ -2,37 +2,32 @@ if RUBY_PLATFORM != 'opal'
2
2
  require 'bcrypt'
3
3
  end
4
4
 
5
- class User < Volt::Model
6
- validate :username, unique: true, length: 8
7
- if RUBY_PLATFORM == 'opal'
8
- # Don't validate on the server
9
- validate :password, length: 8
10
- end
11
-
12
- def password=(val)
13
- if Volt.server?
14
- # on the server, we bcrypt the password and store the result
15
- self._hashed_password = BCrypt::Password.create(val)
16
- else
17
- self._password = val
5
+ module Volt
6
+ class User < Model
7
+ # returns true if the user configured using the username
8
+ def self.login_field
9
+ if Volt.config.public.try(:auth).try(:use_username)
10
+ :username
11
+ else
12
+ :email
13
+ end
18
14
  end
19
- end
20
15
 
21
- # Login the user, return a promise for success
22
- def self.login(username, password)
23
- puts "Login now"
24
- UserTasks.login(username, password).then do |result|
25
- puts "Got: #{result.inspect}"
16
+ validate login_field, unique: true, length: 8
26
17
 
27
- # Assign the user_id cookie for the user
28
- $page.cookies._user_id = result
18
+ if RUBY_PLATFORM == 'opal'
19
+ # Don't validate on the server
20
+ validate :password, length: 8
21
+ end
29
22
 
30
- # Pass nil back
31
- nil
23
+ def password=(val)
24
+ if Volt.server?
25
+ # on the server, we bcrypt the password and store the result
26
+ self._hashed_password = BCrypt::Password.create(val)
27
+ else
28
+ self._password = val
29
+ end
32
30
  end
33
- end
34
31
 
35
- def self.logout
36
- $page.cookies.delete(:user_id)
37
32
  end
38
33
  end
@@ -18,4 +18,8 @@ class DataStore
18
18
 
19
19
  return cursor.to_a
20
20
  end
21
+
22
+ def drop_database
23
+ db.connection.drop_database(Volt.config.db_name)
24
+ end
21
25
  end
@@ -12,20 +12,17 @@ class StoreTasks < Volt::TaskHandler
12
12
  end
13
13
 
14
14
  def load_model(collection, path, data)
15
- puts "Load Model: #{path.inspect}"
16
15
  model_name = collection.singularize.camelize
17
16
 
18
- # TODO: Security check to make sure we have a valid model
19
- # and don't load classes we shouldn't
20
- begin
21
- model_class = Object.send(:const_get, model_name)
22
- rescue NameError => e
23
- model_class = Volt::Model
24
- end
17
+ # Fetch the model
18
+ collection = store.send(:"_#{path[-2]}")
19
+
20
+ # See if the model has already been made
21
+ model = collection.find_one({_id: data[:_id]})
22
+
23
+ # Otherwise assign to the collection
24
+ model ||= collection
25
25
 
26
- # Load the model, use the Store persistor and set the path
27
- model = model_class.new({}, persistor: Volt::Persistors::StoreFactory.new(nil), path: path)
28
- model.persistor.change_state_to(:loaded)
29
26
 
30
27
  # Create a buffer
31
28
  buffer = model.buffer
@@ -1,29 +1,30 @@
1
1
  class UserTasks < Volt::TaskHandler
2
- # Login a user, takes a username and password
3
2
 
4
- def login(username, password)
5
- puts "META: " + Thread.current['meta'].inspect
3
+ # Login a user, takes a login and password. Login can be either a username or an e-mail
4
+ # based on Volt.config.public.auth.use_username
5
+ def login(login, password)
6
+ query = {User.login_field => login}
6
7
 
7
- if Volt.user
8
- puts "USER: " + Volt.user._name
9
- end
10
-
11
- return store._users.find(username: username).then do |users|
8
+ return store._users.find(query).then do |users|
12
9
  user = users.first
13
10
 
14
- match_pass = BCrypt::Password.new(user._hashed_password)
15
- if match_pass == password
16
- raise "app_secret is not configured" unless Volt.config.app_secret
11
+ if user
12
+ match_pass = BCrypt::Password.new(user._hashed_password)
13
+ if match_pass == password
14
+ raise "app_secret is not configured" unless Volt.config.app_secret
17
15
 
18
- # TODO: returning here should be possible, but causes some issues
16
+ # TODO: returning here should be possible, but causes some issues
19
17
 
20
- # Salt the user id with the app_secret so the end user can't tamper with the cookie
21
- signature = BCrypt::Password.create("#{Volt.config.app_secret}::#{user._id}")
18
+ # Salt the user id with the app_secret so the end user can't tamper with the cookie
19
+ signature = BCrypt::Password.create("#{Volt.config.app_secret}::#{user._id}")
22
20
 
23
- # Return user_id:hash on user id
24
- next "#{user._id}:#{signature}"
21
+ # Return user_id:hash on user id
22
+ next "#{user._id}:#{signature}"
23
+ else
24
+ raise "Password did not match"
25
+ end
25
26
  else
26
- raise "Password did not match"
27
+ raise "User could not be found"
27
28
  end
28
29
  end
29
30
  end
data/lib/volt.rb CHANGED
@@ -2,11 +2,12 @@ require 'volt/volt/environment'
2
2
  require 'volt/extra_core/extra_core'
3
3
  require 'volt/reactive/computation'
4
4
  require 'volt/reactive/dependency'
5
+ require 'volt/config'
5
6
  if RUBY_PLATFORM == 'opal'
6
7
  else
7
- require 'volt/config'
8
8
  require 'volt/data_stores/data_store'
9
9
  end
10
+ require 'volt/volt/users'
10
11
 
11
12
  module Volt
12
13
  @in_browser = if RUBY_PLATFORM == 'opal'
@@ -83,6 +84,11 @@ module Volt
83
84
  end
84
85
  end
85
86
 
87
+ # True if the user is logged in and the user is loaded
88
+ def user?
89
+ !!user
90
+ end
91
+
86
92
  # Return the current user.
87
93
  def user
88
94
  user_id = self.user_id
data/lib/volt/cli.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # Load in the gemfile
1
2
  require 'bundler/setup'
3
+
2
4
  require 'thor'
3
5
  require 'volt/extra_core/extra_core'
4
6
  require 'volt/cli/generate'
data/lib/volt/config.rb CHANGED
@@ -1,42 +1,82 @@
1
1
  # Config lets a user set global config options for Volt.
2
- require 'configurations'
3
- module Volt
4
- include Configurations
5
-
6
- class << self
7
- def defaults
8
- app_name = File.basename(Dir.pwd)
9
- {
10
- app_name: app_name,
11
- db_name: ENV['DB_NAME'] || (app_name + '_' + Volt.env.to_s),
12
- db_host: ENV['DB_HOST'] || 'localhost',
13
- db_port: (ENV['DB_PORT'] || 27_017).to_i,
14
- db_driver: ENV['DB_DRIVER'] || 'mongo',
15
- }
2
+ # The hash is setup on the server, then passed to the client on initial page render.
3
+ if RUBY_PLATFORM == 'opal'
4
+ require 'ostruct'
5
+
6
+ # TODO: Temporary fix for missing on OpenStruct in opal
7
+ class OpenStruct
8
+ def respond_to?(method_name)
9
+ @table.key?(method_name) || super
16
10
  end
11
+ end
17
12
 
18
- # Resets the configuration to the default (empty hash)
19
- def reset_config!
20
- self.configure do |c|
21
- c.from_h(defaults)
13
+ module Volt
14
+ class << self
15
+ # Returns the config
16
+ def config
17
+ @config
22
18
  end
23
- end
24
19
 
25
- # Load in all .rb files in the config folder
26
- def run_files_in_config_folder
27
- Dir[Dir.pwd + '/config/*.rb'].each do |config_file|
28
- require(config_file)
20
+ # Called on page load to pass the backend config to the client
21
+ def setup_client_config(config_hash)
22
+ # Only Volt.config.public is passed from the server (for security reasons)
23
+ @config = wrap_config({public: config_hash})
29
24
  end
30
- end
31
25
 
32
- alias_method :setup, :configure
33
- alias_method :config, :configuration
34
- end
26
+ # Wraps the config hash in an OpenStruct so it can be accessed in the same way
27
+ # as the server side config.
28
+ def wrap_config(hash)
29
+ new_hash = {}
30
+
31
+ hash.each_pair do |key, value|
32
+ if value.is_a?(Hash)
33
+ new_hash[key] = wrap_config(value)
34
+ else
35
+ new_hash[key] = value
36
+ end
37
+ end
35
38
 
36
- configuration_defaults do |c|
37
- c.from_h(Volt.defaults)
39
+ OpenStruct.new(new_hash)
40
+ end
41
+ end
38
42
  end
43
+ else
44
+ require 'configurations'
45
+ module Volt
46
+ include Configurations
39
47
 
48
+ class << self
49
+ def defaults
50
+ app_name = File.basename(Dir.pwd)
51
+ {
52
+ app_name: app_name,
53
+ db_name: ENV['DB_NAME'] || (app_name + '_' + Volt.env.to_s),
54
+ db_host: ENV['DB_HOST'] || 'localhost',
55
+ db_port: (ENV['DB_PORT'] || 27_017).to_i,
56
+ db_driver: ENV['DB_DRIVER'] || 'mongo',
57
+ }
58
+ end
59
+
60
+ # Resets the configuration to the default (empty hash)
61
+ def reset_config!
62
+ self.configure do |c|
63
+ c.from_h(defaults)
64
+ end
65
+ end
66
+
67
+ # Load in all .rb files in the config folder
68
+ def run_files_in_config_folder
69
+ Dir[Volt.root + '/config/*.rb'].each do |config_file|
70
+ require(config_file)
71
+ end
72
+ end
40
73
 
74
+ alias_method :setup, :configure
75
+ alias_method :config, :configuration
76
+ end
41
77
 
78
+ configuration_defaults do |c|
79
+ c.from_h(Volt.defaults)
80
+ end
81
+ end
42
82
  end
@@ -32,4 +32,12 @@ class Object
32
32
  def deep_clone
33
33
  Marshal.load(Marshal.dump(self))
34
34
  end
35
+
36
+ def try(*a, &b)
37
+ if a.empty? && block_given?
38
+ yield self
39
+ else
40
+ public_send(*a, &b) if respond_to?(a.first)
41
+ end
42
+ end
35
43
  end