pinstripe 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.pinstripe +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +24 -0
- data/LICENSE +20 -0
- data/README.md +5 -0
- data/Rakefile +10 -0
- data/exe/pinstripe +4 -0
- data/lib/pinstripe/call_handler.rb +12 -0
- data/lib/pinstripe/command.rb +20 -0
- data/lib/pinstripe/commands/list_commands.rb +16 -0
- data/lib/pinstripe/commands/start_console.rb +14 -0
- data/lib/pinstripe/concern.rb +19 -0
- data/lib/pinstripe/database/row.rb +48 -0
- data/lib/pinstripe/database/table.rb +131 -0
- data/lib/pinstripe/database/table_alias_manager.rb +20 -0
- data/lib/pinstripe/database/union.rb +20 -0
- data/lib/pinstripe/database.rb +56 -0
- data/lib/pinstripe/helper.rb +20 -0
- data/lib/pinstripe/helpers.rb +8 -0
- data/lib/pinstripe/inflector/inflections.rb +122 -0
- data/lib/pinstripe/inflector.rb +28 -0
- data/lib/pinstripe/monkey_patches/pluralize.rb +8 -0
- data/lib/pinstripe/monkey_patches/require_all.rb +18 -0
- data/lib/pinstripe/monkey_patches/singularize.rb +8 -0
- data/lib/pinstripe/monkey_patches/to_params_hash.rb +20 -0
- data/lib/pinstripe/params_hash.rb +44 -0
- data/lib/pinstripe/project.rb +29 -0
- data/lib/pinstripe/registry.rb +46 -0
- data/lib/pinstripe/resource_factories/call_handler.rb +8 -0
- data/lib/pinstripe/resource_factories/env.rb +9 -0
- data/lib/pinstripe/resource_factories/environment.rb +8 -0
- data/lib/pinstripe/resource_factories/project.rb +8 -0
- data/lib/pinstripe/resource_factory.rb +32 -0
- data/lib/pinstripe/resource_provider.rb +50 -0
- data/lib/pinstripe/version.rb +3 -0
- data/lib/pinstripe/workspace.rb +8 -0
- data/lib/pinstripe.rb +24 -0
- data/package.json +15 -0
- data/pinstripe +4 -0
- data/pinstripe.gemspec +38 -0
- data/rollup.config.js +19 -0
- data/web/javascripts/_pinstripe/event_wrapper.js +29 -0
- data/web/javascripts/_pinstripe/index.js +3 -0
- data/web/javascripts/_pinstripe/initialize.js +29 -0
- data/web/javascripts/_pinstripe/node_wrapper.js +354 -0
- data/web/javascripts/_pinstripe/node_wrappers/anchor.js +56 -0
- data/web/javascripts/_pinstripe/node_wrappers/document.js +27 -0
- data/web/javascripts/_pinstripe/node_wrappers/form.js +52 -0
- data/web/javascripts/_pinstripe/node_wrappers/frame.js +72 -0
- data/web/javascripts/_pinstripe/node_wrappers/index.js +8 -0
- data/web/javascripts/_pinstripe/node_wrappers/input.js +23 -0
- data/web/javascripts/_pinstripe/node_wrappers/modal.js +36 -0
- data/web/javascripts/_pinstripe/node_wrappers/script.js +17 -0
- data/web/javascripts/_pinstripe/string_reader.js +24 -0
- data/web/javascripts/_pinstripe/url.js +94 -0
- data/web/javascripts/_pinstripe/util/benchmark.js +10 -0
- data/web/javascripts/_pinstripe/util/capitalize.js +4 -0
- data/web/javascripts/_pinstripe/util/index.js +4 -0
- data/web/javascripts/_pinstripe/util/unescape_html.js +13 -0
- data/web/javascripts/_pinstripe/virtual_node.js +156 -0
- data/yarn.lock +72 -0
- metadata +162 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require "pinstripe/params_hash"
|
3
|
+
|
4
|
+
class Hash
|
5
|
+
|
6
|
+
def to_params_hash
|
7
|
+
Pinstripe::ParamsHash.new(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class Array
|
13
|
+
|
14
|
+
def to_params_hash
|
15
|
+
out = Pinstripe::ParamsHash.new
|
16
|
+
each_with_index{|value, key| out[key] = value}
|
17
|
+
out
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
class Pinstripe::ParamsHash < Hash
|
3
|
+
|
4
|
+
def initialize(hash = {})
|
5
|
+
merge!(hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
def []=(key, value)
|
9
|
+
super(key.to_s, normalize_value(value))
|
10
|
+
end
|
11
|
+
|
12
|
+
def[](key)
|
13
|
+
super(key.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge!(hash)
|
17
|
+
hash.each{|key, value| self[key] = value }
|
18
|
+
end
|
19
|
+
|
20
|
+
def merge(hash)
|
21
|
+
out = clone
|
22
|
+
out.merge!(hash)
|
23
|
+
out
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(name, *args, &block)
|
27
|
+
if args.length == 0 && !block
|
28
|
+
self[name]
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def normalize_value(value)
|
37
|
+
if value.respond_to? :to_params_hash
|
38
|
+
value.to_params_hash
|
39
|
+
else
|
40
|
+
value.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require "bundler"
|
3
|
+
|
4
|
+
class Pinstripe::Project
|
5
|
+
|
6
|
+
attr_reader :root_path, :load_paths
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@root_path = find_path(Dir.pwd, ".pinstripe")
|
10
|
+
@load_paths = $LOAD_PATH.map{|load_path| find_path(load_path, ".pinstripe") }.compact
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def find_path(path, file_name)
|
16
|
+
current_path = path
|
17
|
+
while true
|
18
|
+
candidate_file_path = "#{current_path}/#{file_name}"
|
19
|
+
return current_path if File.file?(candidate_file_path)
|
20
|
+
if matches = current_path.match(/\A(.*)\/([^\/]+)\z/)
|
21
|
+
current_path = matches[1]
|
22
|
+
else
|
23
|
+
break
|
24
|
+
end
|
25
|
+
end
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
module Pinstripe::Registry
|
3
|
+
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
def registered?
|
7
|
+
registered_classes.values.include? self
|
8
|
+
end
|
9
|
+
|
10
|
+
def registered_classes
|
11
|
+
@registered_classes ||= superclass.respond_to?(:registered_classes) ? superclass.registered_classes : {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def register(name, &block)
|
15
|
+
raise "Class has already been registered" if registered?
|
16
|
+
name = name.to_s
|
17
|
+
instance_eval{ @name = name }
|
18
|
+
registered_classes[name] = self
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def define(name, *args, &block)
|
23
|
+
klass = Class.new(self)
|
24
|
+
klass.register(name, *args)
|
25
|
+
klass.class_eval(&block) if block
|
26
|
+
klass
|
27
|
+
end
|
28
|
+
|
29
|
+
def for(name, options = {})
|
30
|
+
name = name.to_s
|
31
|
+
registered_classes[name] || begin
|
32
|
+
klass = Class.new(self)
|
33
|
+
if options[:register_if_not_exists]
|
34
|
+
klass.register name
|
35
|
+
else
|
36
|
+
klass.instance_eval{ @name = name }
|
37
|
+
end
|
38
|
+
klass
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create(name, *args, &block)
|
43
|
+
self.for(name).new(*args, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
require "pinstripe/registry"
|
3
|
+
require "pinstripe/helper"
|
4
|
+
|
5
|
+
class Pinstripe::ResourceFactory
|
6
|
+
|
7
|
+
extend Pinstripe::Registry
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def register(name, options = {})
|
11
|
+
super(name)
|
12
|
+
|
13
|
+
@shared = options.to_params_hash.shared == "true"
|
14
|
+
|
15
|
+
Pinstripe::Helper.define name do
|
16
|
+
def call
|
17
|
+
::Pinstripe.resource_provider[self.class.name]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def shared?
|
23
|
+
@shared
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def create
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Pinstripe::ResourceProvider
|
4
|
+
|
5
|
+
attr_reader :shared_resources
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@shared_resources = {}
|
9
|
+
@mutex = Mutex.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def thead_resources
|
13
|
+
Thread.current["PINSTRIPE_RESOURCES"] ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](name)
|
17
|
+
name = name.to_s
|
18
|
+
|
19
|
+
return thead_resources[name] if !thead_resources[name].nil?
|
20
|
+
return shared_resources[name] if !shared_resources[name].nil?
|
21
|
+
|
22
|
+
resource_factory = Pinstripe::ResourceFactory.create(name)
|
23
|
+
|
24
|
+
if resource_factory.class.shared?
|
25
|
+
@mutex.synchronize { shared_resources[name] ||= resource_factory.create }
|
26
|
+
shared_resources[name]
|
27
|
+
else
|
28
|
+
thead_resources[name] = resource_factory.create
|
29
|
+
thead_resources[name]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def []=(name, value)
|
34
|
+
thead_resources[name.to_s] = value
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset(shared = false, thread = true, &block)
|
39
|
+
previous_shared_resources = shared_resources
|
40
|
+
previous_thread_resources = thread_resources
|
41
|
+
@mutex.syncronize { @shared_resources = {} } if shared
|
42
|
+
Thread.current["PINSTRIPE_RESOURCES"] = {} if thread
|
43
|
+
if block
|
44
|
+
block.call
|
45
|
+
@mutex.synchronize { @shared_resources = previous_shared_resources } if shared
|
46
|
+
Thread.current["PINSTRIPE_RESOURCES"] = previous_thread_resources if thread
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/pinstripe.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require "pinstripe/monkey_patches/require_all"
|
3
|
+
|
4
|
+
module Pinstripe
|
5
|
+
|
6
|
+
require_all("pinstripe/monkey_patches")
|
7
|
+
require_all("pinstripe")
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def resource_provider
|
12
|
+
@resource_provider ||= ResourceProvider.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
resource_provider.reset do
|
17
|
+
resource_provider["env"] = env
|
18
|
+
resource_provider["call_handler"].handle_call
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/package.json
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"name": "pinstripe",
|
3
|
+
"version": "0.1.0",
|
4
|
+
"main": "web/javascripts/bundle.js",
|
5
|
+
"module": "web/javascripts/_pinstripe/index.js",
|
6
|
+
"license": "MIT",
|
7
|
+
"scripts": {
|
8
|
+
"build": "rollup --config",
|
9
|
+
"clean": "rm -rf ./node_modules && rm -rf ./dist"
|
10
|
+
},
|
11
|
+
"devDependencies": {
|
12
|
+
"rollup": "^2.0.2",
|
13
|
+
"rollup-plugin-node-resolve": "^5.2.0"
|
14
|
+
}
|
15
|
+
}
|
data/pinstripe
ADDED
data/pinstripe.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "pinstripe/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "pinstripe"
|
7
|
+
spec.version = Pinstripe::VERSION
|
8
|
+
spec.authors = ["Jody Salt"]
|
9
|
+
spec.email = ["jody@jodysalt.com"]
|
10
|
+
|
11
|
+
spec.summary = "An entrepreneurial full stack web framework!"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
#spec.description = %q{TODO: Write a longer description or delete this line.}
|
15
|
+
#spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
16
|
+
|
17
|
+
#spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
18
|
+
|
19
|
+
#spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
#spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
21
|
+
#spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "mysql2", "~> 0.5"
|
33
|
+
|
34
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
35
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
36
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
37
|
+
|
38
|
+
end
|
data/rollup.config.js
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
import resolve from "rollup-plugin-node-resolve"
|
3
|
+
|
4
|
+
export default [
|
5
|
+
{
|
6
|
+
input: 'web/javascripts/_pinstripe/index.js',
|
7
|
+
output: {
|
8
|
+
file: `web/javascripts/bundle.js`,
|
9
|
+
format: 'iife',
|
10
|
+
sourcemap: true
|
11
|
+
},
|
12
|
+
plugins: [resolve()],
|
13
|
+
onwarn(warning, warn) {
|
14
|
+
const ignoreCodes = ['EVAL', 'CIRCULAR_DEPENDENCY']
|
15
|
+
if (ignoreCodes.some(code => code == warning.code)) return
|
16
|
+
warn(warning)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
]
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
import { NodeWrapper } from './node_wrapper'
|
3
|
+
|
4
|
+
export class EventWrapper {
|
5
|
+
|
6
|
+
static instanceFor(event){
|
7
|
+
if(!event.$p){
|
8
|
+
event.$p = new this(event)
|
9
|
+
}
|
10
|
+
return event.$p
|
11
|
+
}
|
12
|
+
|
13
|
+
constructor(event){
|
14
|
+
this.event = event
|
15
|
+
}
|
16
|
+
|
17
|
+
get target(){
|
18
|
+
return NodeWrapper.instanceFor(this.event.target)
|
19
|
+
}
|
20
|
+
|
21
|
+
stopPropagation(){
|
22
|
+
this.event.stopPropagation()
|
23
|
+
}
|
24
|
+
|
25
|
+
preventDefault(){
|
26
|
+
this.event.preventDefault()
|
27
|
+
}
|
28
|
+
|
29
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
import { NodeWrapper } from './node_wrapper'
|
3
|
+
|
4
|
+
let ready = false;
|
5
|
+
|
6
|
+
function initializeTree(node){
|
7
|
+
NodeWrapper.instanceFor(node).descendants
|
8
|
+
}
|
9
|
+
|
10
|
+
const observer = new MutationObserver(mutations => {
|
11
|
+
if(ready){
|
12
|
+
mutations.forEach(
|
13
|
+
mutation => mutation.addedNodes.forEach(
|
14
|
+
node => initializeTree(node)
|
15
|
+
)
|
16
|
+
)
|
17
|
+
}
|
18
|
+
})
|
19
|
+
|
20
|
+
observer.observe(document.documentElement, {
|
21
|
+
attributes: false,
|
22
|
+
childList: true,
|
23
|
+
subtree: true
|
24
|
+
});
|
25
|
+
|
26
|
+
setTimeout(() => {
|
27
|
+
ready = true
|
28
|
+
initializeTree(document)
|
29
|
+
}, 0)
|