startback-web 0.19.4 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/Rakefile +18 -0
- data/lib/startback/web/magic_assets/ng_html_transformer.rb +80 -0
- data/lib/startback/web/magic_assets/rake_tasks.rb +64 -0
- data/lib/startback/web/magic_assets.rb +98 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/unit/web/fixtures/assets/app/hello.es6 +4 -0
- data/spec/unit/web/fixtures/assets/app/hello.html +1 -0
- data/spec/unit/web/fixtures/assets/index.es6 +1 -0
- data/spec/unit/web/test_magic_assets.rb +82 -0
- data/tasks/test.rake +13 -0
- metadata +40 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc59d2b7846dfa966401941c601e3a95ca892786837950865d7f09535b807dec
|
4
|
+
data.tar.gz: 52dfe020cb40a77d1bc92a63dde56dcfa1dbc4b2e13458a6741631ae6235cbe7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 912506d50d46152122641b181cbf08297955b1ec22b852aed97ce0747f029769f191357a4bf5ba9444f49430dfb260380c80bfa3df8655721aeb315f330bde6e
|
7
|
+
data.tar.gz: f4f53e58e7d8232340e88a7d466edf1ed095443a44518952524d6a6fdcac019748bf7772baf03d68b36de5acef0fa6f8b00bd2ee336d57c6412dff9674446c4b
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
def shell(*cmds)
|
4
|
+
cmd = cmds.join("\n")
|
5
|
+
puts cmd
|
6
|
+
system cmd
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Install all tasks found in tasks folder
|
11
|
+
#
|
12
|
+
# See .rake files there for complete documentation.
|
13
|
+
#
|
14
|
+
Dir["tasks/*.rake"].each do |taskfile|
|
15
|
+
load taskfile
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :test
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Startback
|
2
|
+
module Web
|
3
|
+
class MagicAssets
|
4
|
+
#
|
5
|
+
# Plugin for MagicAssets that compiles .html angular templates in the
|
6
|
+
# assets structure to javascript files filling angular's template cache.
|
7
|
+
#
|
8
|
+
# Heavily inspired, yet over-simplified version, of angular-rails-templates
|
9
|
+
# See https://github.com/pitr/angular-rails-templates, licensed under MIT
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# use Startback::Web::MagicAssets, {
|
14
|
+
# plugins: [Startback::Web::MagicAssets::NgHtmlTransfomer.new]
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
class NgHtmlTransformer
|
18
|
+
|
19
|
+
DEFAULT_OPTIONS = {
|
20
|
+
:path => '/assets',
|
21
|
+
:ng_module => 'templates',
|
22
|
+
:mime_type => 'text/ng-html',
|
23
|
+
:extensions => [".html"]
|
24
|
+
}
|
25
|
+
|
26
|
+
def initialize(options = {})
|
27
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
28
|
+
end
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def install(sprockets)
|
32
|
+
sprockets.register_mime_type options[:mime_type], extensions: options[:extensions]
|
33
|
+
sprockets.register_transformer options[:mime_type], 'application/javascript', self
|
34
|
+
end
|
35
|
+
|
36
|
+
TPL = <<-EOF
|
37
|
+
angular.module("<%= ng_module %>").run(["$templateCache", function($templateCache) {
|
38
|
+
$templateCache.put("<%= angular_template_name %>", <%= html %>)
|
39
|
+
}]);
|
40
|
+
EOF
|
41
|
+
|
42
|
+
# inspired by Rails' action_view/helpers/javascript_helper.rb
|
43
|
+
JS_ESCAPE_MAP = {
|
44
|
+
'\\' => '\\\\',
|
45
|
+
"\r\n" => '\n',
|
46
|
+
"\n" => '\n',
|
47
|
+
"\r" => '\n',
|
48
|
+
'"' => '\\"',
|
49
|
+
"'" => "\\'"
|
50
|
+
}
|
51
|
+
|
52
|
+
# We want to deliver the shortist valid javascript escaped string
|
53
|
+
# Count the number of " vs '
|
54
|
+
# If more ', escape "
|
55
|
+
# If more ", escape '
|
56
|
+
# If equal, prefer to escape "
|
57
|
+
|
58
|
+
def escape_javascript(raw)
|
59
|
+
if raw
|
60
|
+
quote = raw.count(%{'}) >= raw.count(%{"}) ? %{"} : %{'}
|
61
|
+
escaped = raw.gsub(/(\\|\r\n|[\n\r#{quote}])/u) {|match| JS_ESCAPE_MAP[match] }
|
62
|
+
"#{quote}#{escaped}#{quote}"
|
63
|
+
else
|
64
|
+
'""'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def call(input)
|
69
|
+
file_path = input[:filename]
|
70
|
+
angular_template_name = "#{options[:path]}/#{input[:name]}.html"
|
71
|
+
source_file = file_path
|
72
|
+
ng_module = options[:ng_module]
|
73
|
+
html = escape_javascript(input[:data].chomp)
|
74
|
+
ERB.new(TPL).result(binding)
|
75
|
+
end
|
76
|
+
|
77
|
+
end # class NgHtmlTransformer
|
78
|
+
end # class MagicAssets
|
79
|
+
end # module Web
|
80
|
+
end # module Startback
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Startback
|
2
|
+
module Web
|
3
|
+
class MagicAssets
|
4
|
+
class RakeTasks
|
5
|
+
|
6
|
+
DEFAULT_OPTIONS = {
|
7
|
+
:namespace => :assets
|
8
|
+
}
|
9
|
+
|
10
|
+
def initialize(rake, options)
|
11
|
+
@rake = rake
|
12
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
13
|
+
install
|
14
|
+
end
|
15
|
+
attr_reader :rake, :options
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def install
|
20
|
+
require 'securerandom'
|
21
|
+
|
22
|
+
ns = options[:namespace]
|
23
|
+
target_folder = options[:target]
|
24
|
+
assets = options[:assets]
|
25
|
+
assets = MagicAssets.new(assets) if assets.is_a?(Hash)
|
26
|
+
version = SecureRandom.urlsafe_base64
|
27
|
+
|
28
|
+
rake.instance_exec do
|
29
|
+
namespace(ns) do
|
30
|
+
|
31
|
+
desc 'Cleans generated assets'
|
32
|
+
task :clean do
|
33
|
+
FileUtils.rm_rf target_folder
|
34
|
+
end
|
35
|
+
|
36
|
+
task :prepare do
|
37
|
+
FileUtils.mkdir_p target_folder
|
38
|
+
(target_folder/"VERSION").write(version)
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'compile javascript assets'
|
42
|
+
task :compile_js do
|
43
|
+
assets['vendor.js'].write_to(target_folder/"vendor-#{version}.min.js")
|
44
|
+
assets['app.js'].write_to(target_folder/"app-#{version}.min.js")
|
45
|
+
puts "successfully compiled js assets"
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'compile css assets'
|
49
|
+
task :compile_css do
|
50
|
+
assets['vendor.css'].write_to(target_folder/"vendor-#{version}.min.css")
|
51
|
+
assets['app.css'].write_to(target_folder/"app-#{version}.min.css")
|
52
|
+
puts "successfully compiled css assets"
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'compile assets'
|
56
|
+
task :compile => [:clean, :prepare, :compile_js, :compile_css]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end # class MagicAssets
|
63
|
+
end # module Web
|
64
|
+
end # module Startback
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
module Startback
|
3
|
+
module Web
|
4
|
+
#
|
5
|
+
# Rack application & middleware that can be used to simplify javascript
|
6
|
+
# and css assets management, using Sprockets.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
#
|
10
|
+
# # Used as rack app, typically under a path
|
11
|
+
# Rack::Builder.new do
|
12
|
+
# map '/assets' do
|
13
|
+
# run Startback::Web::MagicAssets.new({
|
14
|
+
# folder: "/path/to/assets/src"
|
15
|
+
# })
|
16
|
+
# end
|
17
|
+
# run MyApp
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # Used as a rack middleware, e.g. in a Sinatra application
|
21
|
+
# use Startback::Web::MagicAssets, {
|
22
|
+
# folder: "/path/to/assets/src",
|
23
|
+
# path: "/assets"
|
24
|
+
# }
|
25
|
+
#
|
26
|
+
# Sprocket configuration can be done through the `:sprocket` option:
|
27
|
+
#
|
28
|
+
# use Startback::Web::MagicAssets, {
|
29
|
+
# sprockets: {
|
30
|
+
# :css_compressor => :scss
|
31
|
+
# }
|
32
|
+
# }
|
33
|
+
#
|
34
|
+
class MagicAssets
|
35
|
+
|
36
|
+
DEFAULT_OPTIONS = {
|
37
|
+
sprockets: {},
|
38
|
+
plugins: {}
|
39
|
+
}
|
40
|
+
|
41
|
+
def initialize(app, options = {})
|
42
|
+
app, options = nil, app if app.is_a?(Hash)
|
43
|
+
@app = app
|
44
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
45
|
+
@sprockets = build_sprockets
|
46
|
+
end
|
47
|
+
attr_reader :sprockets
|
48
|
+
|
49
|
+
def call(env)
|
50
|
+
if new_env = is_match?(env)
|
51
|
+
@sprockets.call(new_env)
|
52
|
+
else
|
53
|
+
@app.call(env)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def [](*args, &bl)
|
58
|
+
@sprockets.[](*args, &bl)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def path
|
64
|
+
@options[:path]
|
65
|
+
end
|
66
|
+
|
67
|
+
def is_match?(env)
|
68
|
+
if @app.nil?
|
69
|
+
# Not used as a middleware, use this env and match
|
70
|
+
env
|
71
|
+
elsif env['PATH_INFO'].start_with?(path)
|
72
|
+
# Used as a middleware, and PATH_INFO starts with the
|
73
|
+
# assets path => strip it for sprockets
|
74
|
+
env.merge("PATH_INFO" => env["PATH_INFO"].sub(path, ""))
|
75
|
+
else
|
76
|
+
# No match, let @app execute with the untouched environment
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_sprockets
|
82
|
+
Sprockets::Environment.new.tap{|s|
|
83
|
+
Array(@options[:folder]).each do |folder|
|
84
|
+
s.append_path(folder)
|
85
|
+
end
|
86
|
+
@options[:sprockets].each_pair do |k,v|
|
87
|
+
s.public_send(:"#{k}=", v)
|
88
|
+
end
|
89
|
+
@options[:plugins].each do |p|
|
90
|
+
p.install(s)
|
91
|
+
end
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
end # class MagicAssets
|
96
|
+
end # module Web
|
97
|
+
end # module Startback
|
98
|
+
require_relative 'magic_assets/rake_tasks'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<p>Hello {{who}}</p>
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require_tree ./app
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'startback/web/magic_assets'
|
3
|
+
require 'startback/web/magic_assets/ng_html_transformer'
|
4
|
+
|
5
|
+
module Startback
|
6
|
+
module Web
|
7
|
+
describe MagicAssets do
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
context 'when used as an app' do
|
11
|
+
let(:app){
|
12
|
+
MagicAssets.new({
|
13
|
+
folder: Path.dir/"fixtures/assets"
|
14
|
+
})
|
15
|
+
}
|
16
|
+
|
17
|
+
it 'works as expected' do
|
18
|
+
get "/index.js"
|
19
|
+
expect(last_response.status).to eql(200)
|
20
|
+
expect(last_response.body).to match(/function test/)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'delegates a [] call to sprockets' do
|
24
|
+
result = app['index.js']
|
25
|
+
expect(result.to_s).to match(/function test/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns a 404 on unknown' do
|
29
|
+
get '/nosuchone.js'
|
30
|
+
expect(last_response.status).to eql(404)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when used as a middleware' do
|
35
|
+
let(:app){
|
36
|
+
Rack::Builder.new do
|
37
|
+
use MagicAssets, {
|
38
|
+
folder: Path.dir/"fixtures/assets",
|
39
|
+
path: "/my-assets"
|
40
|
+
}
|
41
|
+
run ->(t){
|
42
|
+
[200, {}, ["Hello world"]]
|
43
|
+
}
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
it 'lets unrelated things pass' do
|
48
|
+
get "/hello"
|
49
|
+
expect(last_response.status).to eql(200)
|
50
|
+
expect(last_response.body).to eql("Hello world")
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'serves the assets under the chosen path' do
|
54
|
+
get "/my-assets/index.js"
|
55
|
+
expect(last_response.status).to eql(200)
|
56
|
+
expect(last_response.body).to match(/function test/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when registering the NgHtmlTransformer' do
|
61
|
+
let(:app){
|
62
|
+
plugin = MagicAssets::NgHtmlTransformer.new({
|
63
|
+
ng_module: "test.templates"
|
64
|
+
})
|
65
|
+
MagicAssets.new({
|
66
|
+
folder: Path.dir/"fixtures/assets",
|
67
|
+
plugins: [plugin]
|
68
|
+
})
|
69
|
+
}
|
70
|
+
|
71
|
+
it 'works as expected' do
|
72
|
+
get "/index.js"
|
73
|
+
expect(last_response.status).to eql(200)
|
74
|
+
expect(last_response.body).to match(/function test/)
|
75
|
+
expect(last_response.body).to match(/Hello \{\{who\}\}/)
|
76
|
+
expect(last_response.body).to match(/angular.module\("test.templates"\)/)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
namespace :test do
|
4
|
+
|
5
|
+
desc "Run RSpec unit tests"
|
6
|
+
RSpec::Core::RakeTask.new(:unit) do |t|
|
7
|
+
t.pattern = "spec/unit/**/test_*.rb"
|
8
|
+
t.rspec_opts = %{-Ilib -Ispec --color --backtrace --format progress --format RspecJunitFormatter --out spec/rspec-unit.xml}
|
9
|
+
end
|
10
|
+
|
11
|
+
task :all => [:unit]
|
12
|
+
end
|
13
|
+
task :test => :'test:all'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: startback-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -36,40 +36,40 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 0.
|
39
|
+
version: '0.6'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '0.
|
42
|
+
version: '0.7'
|
43
43
|
type: :development
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
49
|
+
version: '0.6'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '0.
|
52
|
+
version: '0.7'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: webspicy
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 0.
|
59
|
+
version: 0.26.0
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '0.
|
62
|
+
version: '0.27'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 0.26.0
|
70
70
|
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: '0.
|
72
|
+
version: '0.27'
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: rake
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,20 +84,34 @@ dependencies:
|
|
84
84
|
- - ">="
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rack-test
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
87
101
|
- !ruby/object:Gem::Dependency
|
88
102
|
name: startback
|
89
103
|
requirement: !ruby/object:Gem::Requirement
|
90
104
|
requirements:
|
91
105
|
- - '='
|
92
106
|
- !ruby/object:Gem::Version
|
93
|
-
version: 0.
|
107
|
+
version: 1.0.1
|
94
108
|
type: :runtime
|
95
109
|
prerelease: false
|
96
110
|
version_requirements: !ruby/object:Gem::Requirement
|
97
111
|
requirements:
|
98
112
|
- - '='
|
99
113
|
- !ruby/object:Gem::Version
|
100
|
-
version: 0.
|
114
|
+
version: 1.0.1
|
101
115
|
- !ruby/object:Gem::Dependency
|
102
116
|
name: sprockets
|
103
117
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,12 +206,23 @@ dependencies:
|
|
192
206
|
- - "<"
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '5.0'
|
195
|
-
description:
|
209
|
+
description: Startback for website
|
196
210
|
email: blambeau@gmail.com
|
197
211
|
executables: []
|
198
212
|
extensions: []
|
199
213
|
extra_rdoc_files: []
|
200
|
-
files:
|
214
|
+
files:
|
215
|
+
- Gemfile
|
216
|
+
- Rakefile
|
217
|
+
- lib/startback/web/magic_assets.rb
|
218
|
+
- lib/startback/web/magic_assets/ng_html_transformer.rb
|
219
|
+
- lib/startback/web/magic_assets/rake_tasks.rb
|
220
|
+
- spec/spec_helper.rb
|
221
|
+
- spec/unit/web/fixtures/assets/app/hello.es6
|
222
|
+
- spec/unit/web/fixtures/assets/app/hello.html
|
223
|
+
- spec/unit/web/fixtures/assets/index.es6
|
224
|
+
- spec/unit/web/test_magic_assets.rb
|
225
|
+
- tasks/test.rake
|
201
226
|
homepage: https://www.enspirit.be
|
202
227
|
licenses:
|
203
228
|
- MIT
|
@@ -220,5 +245,5 @@ requirements: []
|
|
220
245
|
rubygems_version: 3.3.5
|
221
246
|
signing_key:
|
222
247
|
specification_version: 4
|
223
|
-
summary:
|
248
|
+
summary: Startback for website
|
224
249
|
test_files: []
|