surikat 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/surikat.iml +23 -24
- data/.idea/workspace.xml +252 -121
- data/README.md +215 -97
- data/lib/surikat/version.rb +1 -1
- data/surikat.gemspec +1 -1
- metadata +4 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b6c6bd2513b0a892a144969b6c1fd54c279d1a6
|
4
|
+
data.tar.gz: dc52b35c4cc5e8f9d3cc554063776092b3b083d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ba5112d7fdca949395a52ae301e67ee8476cda05a5ff49e6eeba93fb17dd67d450a27162803469a8e040e139ccae7b7be18a366f77914c0f6fe377fcdbb58e8
|
7
|
+
data.tar.gz: 9a3104b535783d41f45bb950ee5029cb24ef2853b58dd70df59173da71fcca140e763d0d32ec1ab654a93cd48ee9696c91b0cc5e4ff626d28ec836ac10b3290c
|
data/.idea/surikat.iml
CHANGED
@@ -7,47 +7,46 @@
|
|
7
7
|
<content url="file://$MODULE_DIR$" />
|
8
8
|
<orderEntry type="inheritedJdk" />
|
9
9
|
<orderEntry type="sourceFolder" forTests="false" />
|
10
|
-
<orderEntry type="library" scope="PROVIDED" name="actionpack (v5.2.
|
11
|
-
<orderEntry type="library" scope="PROVIDED" name="actionview (v5.2.
|
12
|
-
<orderEntry type="library" scope="PROVIDED" name="activemodel (v5.2.
|
13
|
-
<orderEntry type="library" scope="PROVIDED" name="activerecord (v5.2.
|
14
|
-
<orderEntry type="library" scope="PROVIDED" name="activesupport (v5.2.
|
10
|
+
<orderEntry type="library" scope="PROVIDED" name="actionpack (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
11
|
+
<orderEntry type="library" scope="PROVIDED" name="actionview (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
12
|
+
<orderEntry type="library" scope="PROVIDED" name="activemodel (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
13
|
+
<orderEntry type="library" scope="PROVIDED" name="activerecord (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="activesupport (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
15
15
|
<orderEntry type="library" scope="PROVIDED" name="arel (v9.0.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
16
16
|
<orderEntry type="library" scope="PROVIDED" name="builder (v3.2.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
17
17
|
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.16.2, RVM: ruby-2.4.1) [gem]" level="application" />
|
18
18
|
<orderEntry type="library" scope="PROVIDED" name="coderay (v1.1.2, RVM: ruby-2.4.1) [gem]" level="application" />
|
19
|
-
<orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
20
20
|
<orderEntry type="library" scope="PROVIDED" name="crass (v1.0.4, RVM: ruby-2.4.1) [gem]" level="application" />
|
21
21
|
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
22
22
|
<orderEntry type="library" scope="PROVIDED" name="erubi (v1.7.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
23
|
-
<orderEntry type="library" scope="PROVIDED" name="graphql (v1.8.
|
24
|
-
<orderEntry type="library" scope="PROVIDED" name="graphql-libgraphqlparser (v1.
|
25
|
-
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.
|
26
|
-
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.2.
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="graphql (v1.8.11, RVM: ruby-2.4.1) [gem]" level="application" />
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="graphql-libgraphqlparser (v1.3.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.1.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.2.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
27
27
|
<orderEntry type="library" scope="PROVIDED" name="method_source (v0.8.2, RVM: ruby-2.4.1) [gem]" level="application" />
|
28
28
|
<orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.3.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
29
29
|
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.11.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
30
|
-
<orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.8.
|
31
|
-
<orderEntry type="library" scope="PROVIDED" name="oj (v3.
|
32
|
-
<orderEntry type="library" scope="PROVIDED" name="passenger (v5.3.
|
33
|
-
<orderEntry type="library" scope="PROVIDED" name="polyamorous (v1.3.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
30
|
+
<orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.8.5, RVM: ruby-2.4.1) [gem]" level="application" />
|
31
|
+
<orderEntry type="library" scope="PROVIDED" name="oj (v3.7.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
32
|
+
<orderEntry type="library" scope="PROVIDED" name="passenger (v5.3.6, RVM: ruby-2.4.1) [gem]" level="application" />
|
34
33
|
<orderEntry type="library" scope="PROVIDED" name="pry (v0.11.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
35
34
|
<orderEntry type="library" scope="PROVIDED" name="rack (v2.0.5, RVM: ruby-2.4.1) [gem]" level="application" />
|
36
|
-
<orderEntry type="library" scope="PROVIDED" name="rack-app (v7.5.
|
37
|
-
<orderEntry type="library" scope="PROVIDED" name="rack-test (v1.
|
35
|
+
<orderEntry type="library" scope="PROVIDED" name="rack-app (v7.5.2, RVM: ruby-2.4.1) [gem]" level="application" />
|
36
|
+
<orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
38
37
|
<orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, RVM: ruby-2.4.1) [gem]" level="application" />
|
39
38
|
<orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.0.4, RVM: ruby-2.4.1) [gem]" level="application" />
|
40
|
-
<orderEntry type="library" scope="PROVIDED" name="railties (v5.2.
|
39
|
+
<orderEntry type="library" scope="PROVIDED" name="railties (v5.2.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
41
40
|
<orderEntry type="library" scope="PROVIDED" name="rake (v10.5.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
42
|
-
<orderEntry type="library" scope="PROVIDED" name="ransack (
|
43
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.
|
44
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.
|
45
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.
|
46
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.
|
47
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.
|
41
|
+
<orderEntry type="library" scope="PROVIDED" name="ransack (v2.1.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
42
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.8.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
43
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.8.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
44
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.8.1, RVM: ruby-2.4.1) [gem]" level="application" />
|
45
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.8.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
46
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.8.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
48
47
|
<orderEntry type="library" scope="PROVIDED" name="slop (v3.6.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
49
48
|
<orderEntry type="library" scope="PROVIDED" name="sqlite3 (v1.3.13, RVM: ruby-2.4.1) [gem]" level="application" />
|
50
|
-
<orderEntry type="library" scope="PROVIDED" name="standalone_migrations (v5.2.
|
49
|
+
<orderEntry type="library" scope="PROVIDED" name="standalone_migrations (v5.2.6, RVM: ruby-2.4.1) [gem]" level="application" />
|
51
50
|
<orderEntry type="library" scope="PROVIDED" name="thor (v0.20.0, RVM: ruby-2.4.1) [gem]" level="application" />
|
52
51
|
<orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.6, RVM: ruby-2.4.1) [gem]" level="application" />
|
53
52
|
<orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.5, RVM: ruby-2.4.1) [gem]" level="application" />
|
data/.idea/workspace.xml
CHANGED
@@ -1,20 +1,62 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<project version="4">
|
3
3
|
<component name="ChangeListManager">
|
4
|
-
<list default="true" id="66400b9f-bfb7-48ab-a1ab-331b1d21e8c6" name="Default" comment="
|
5
|
-
<change beforePath="$PROJECT_DIR$/.
|
4
|
+
<list default="true" id="66400b9f-bfb7-48ab-a1ab-331b1d21e8c6" name="Default" comment="changes to README">
|
5
|
+
<change beforePath="$PROJECT_DIR$/.idea/surikat.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/surikat.iml" afterDir="false" />
|
6
|
+
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
7
|
+
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
6
8
|
<change beforePath="$PROJECT_DIR$/lib/surikat/version.rb" beforeDir="false" afterPath="$PROJECT_DIR$/lib/surikat/version.rb" afterDir="false" />
|
9
|
+
<change beforePath="$PROJECT_DIR$/surikat-0.3.1.gem" beforeDir="false" afterPath="$PROJECT_DIR$/surikat-0.3.1.gem" afterDir="false" />
|
10
|
+
<change beforePath="$PROJECT_DIR$/surikat.gemspec" beforeDir="false" afterPath="$PROJECT_DIR$/surikat.gemspec" afterDir="false" />
|
7
11
|
</list>
|
8
12
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
9
|
-
<option name="TRACKING_ENABLED" value="true" />
|
10
13
|
<option name="SHOW_DIALOG" value="false" />
|
11
14
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
12
15
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
13
16
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
14
17
|
</component>
|
18
|
+
<component name="FUSProjectUsageTrigger">
|
19
|
+
<session id="-1896855594">
|
20
|
+
<usages-collector id="statistics.lifecycle.project">
|
21
|
+
<counts>
|
22
|
+
<entry key="project.open.time.1" value="1" />
|
23
|
+
<entry key="project.opened" value="1" />
|
24
|
+
</counts>
|
25
|
+
</usages-collector>
|
26
|
+
<usages-collector id="statistics.file.extensions.open">
|
27
|
+
<counts>
|
28
|
+
<entry key="gemspec" value="1" />
|
29
|
+
<entry key="md" value="1" />
|
30
|
+
<entry key="rb" value="1" />
|
31
|
+
</counts>
|
32
|
+
</usages-collector>
|
33
|
+
<usages-collector id="statistics.file.types.open">
|
34
|
+
<counts>
|
35
|
+
<entry key="Markdown" value="1" />
|
36
|
+
<entry key="Ruby" value="2" />
|
37
|
+
</counts>
|
38
|
+
</usages-collector>
|
39
|
+
<usages-collector id="statistics.file.extensions.edit">
|
40
|
+
<counts>
|
41
|
+
<entry key="gemspec" value="5" />
|
42
|
+
<entry key="md" value="1413" />
|
43
|
+
<entry key="rb" value="2" />
|
44
|
+
</counts>
|
45
|
+
</usages-collector>
|
46
|
+
<usages-collector id="statistics.file.types.edit">
|
47
|
+
<counts>
|
48
|
+
<entry key="Markdown" value="1413" />
|
49
|
+
<entry key="Ruby" value="7" />
|
50
|
+
</counts>
|
51
|
+
</usages-collector>
|
52
|
+
<usages-collector id="statistics.actions.runAnything" />
|
53
|
+
<usages-collector id="statistics.js.language.service.starts" />
|
54
|
+
<usages-collector id="statistics.vcs.git.usages" />
|
55
|
+
</session>
|
56
|
+
</component>
|
15
57
|
<component name="FileEditorManager">
|
16
58
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
17
|
-
<file
|
59
|
+
<file pinned="true" current-in-tab="false">
|
18
60
|
<entry file="file://$PROJECT_DIR$/TODO">
|
19
61
|
<provider selected="true" editor-type-id="text-editor">
|
20
62
|
<state relative-caret-position="544">
|
@@ -23,65 +65,32 @@
|
|
23
65
|
</provider>
|
24
66
|
</entry>
|
25
67
|
</file>
|
26
|
-
<file
|
27
|
-
<entry file="file://$PROJECT_DIR$/
|
28
|
-
<provider selected="true" editor-type-id="text-editor">
|
29
|
-
<state relative-caret-position="288">
|
30
|
-
<caret line="253" column="15" selection-start-line="253" selection-start-column="15" selection-end-line="253" selection-end-column="15" />
|
31
|
-
</state>
|
32
|
-
</provider>
|
33
|
-
</entry>
|
34
|
-
</file>
|
35
|
-
<file leaf-file-name="version.rb" pinned="false" current-in-tab="false">
|
36
|
-
<entry file="file://$PROJECT_DIR$/lib/surikat/version.rb">
|
37
|
-
<provider selected="true" editor-type-id="text-editor">
|
38
|
-
<state relative-caret-position="17">
|
39
|
-
<caret line="1" column="18" selection-start-line="1" selection-start-column="18" selection-end-line="1" selection-end-column="18" />
|
40
|
-
</state>
|
41
|
-
</provider>
|
42
|
-
</entry>
|
43
|
-
</file>
|
44
|
-
<file leaf-file-name="config.ru.tmpl" pinned="false" current-in-tab="false">
|
45
|
-
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/config.ru.tmpl">
|
46
|
-
<provider selected="true" editor-type-id="text-editor">
|
47
|
-
<state relative-caret-position="274">
|
48
|
-
<caret line="21" column="2" selection-start-line="21" selection-start-column="2" selection-end-line="21" selection-end-column="2" />
|
49
|
-
</state>
|
50
|
-
</provider>
|
51
|
-
</entry>
|
52
|
-
</file>
|
53
|
-
<file leaf-file-name=".gitignore" pinned="false" current-in-tab="true">
|
54
|
-
<entry file="file://$PROJECT_DIR$/.gitignore">
|
55
|
-
<provider selected="true" editor-type-id="text-editor">
|
56
|
-
<state relative-caret-position="238">
|
57
|
-
<caret line="14" column="4" selection-start-line="14" selection-start-column="4" selection-end-line="14" selection-end-column="4" />
|
58
|
-
</state>
|
59
|
-
</provider>
|
60
|
-
</entry>
|
61
|
-
</file>
|
62
|
-
<file leaf-file-name="aaa_queries.rb.tmpl" pinned="false" current-in-tab="false">
|
63
|
-
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/aaa_queries.rb.tmpl">
|
68
|
+
<file pinned="false" current-in-tab="false">
|
69
|
+
<entry file="file://$PROJECT_DIR$/surikat.gemspec">
|
64
70
|
<provider selected="true" editor-type-id="text-editor">
|
65
|
-
<state relative-caret-position="
|
66
|
-
<caret line="
|
71
|
+
<state relative-caret-position="679">
|
72
|
+
<caret line="50" column="50" selection-start-line="50" selection-start-column="50" selection-end-line="50" selection-end-column="50" />
|
67
73
|
</state>
|
68
74
|
</provider>
|
69
75
|
</entry>
|
70
76
|
</file>
|
71
|
-
<file
|
72
|
-
<entry file="file://$PROJECT_DIR$/
|
73
|
-
<provider selected="true" editor-type-id="text-editor">
|
74
|
-
<state>
|
75
|
-
<
|
77
|
+
<file pinned="false" current-in-tab="false">
|
78
|
+
<entry file="file://$PROJECT_DIR$/README.md">
|
79
|
+
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
80
|
+
<state split_layout="SPLIT">
|
81
|
+
<first_editor relative-caret-position="-296">
|
82
|
+
<caret line="470" column="6" selection-start-line="470" selection-start-column="6" selection-end-line="470" selection-end-column="6" />
|
83
|
+
</first_editor>
|
84
|
+
<second_editor />
|
76
85
|
</state>
|
77
86
|
</provider>
|
78
87
|
</entry>
|
79
88
|
</file>
|
80
|
-
<file
|
81
|
-
<entry file="file://$PROJECT_DIR$/
|
89
|
+
<file pinned="false" current-in-tab="true">
|
90
|
+
<entry file="file://$PROJECT_DIR$/lib/surikat/version.rb">
|
82
91
|
<provider selected="true" editor-type-id="text-editor">
|
83
|
-
<state relative-caret-position="
|
84
|
-
<caret line="
|
92
|
+
<state relative-caret-position="17">
|
93
|
+
<caret line="1" column="18" selection-start-line="1" selection-start-column="18" selection-end-line="1" selection-end-column="18" />
|
85
94
|
</state>
|
86
95
|
</provider>
|
87
96
|
</entry>
|
@@ -97,7 +106,6 @@
|
|
97
106
|
</component>
|
98
107
|
<component name="FindInProjectRecents">
|
99
108
|
<findStrings>
|
100
|
-
<find>.send</find>
|
101
109
|
<find>Input</find>
|
102
110
|
<find>Create a mig</find>
|
103
111
|
<find>'fields'</find>
|
@@ -127,6 +135,7 @@
|
|
127
135
|
<find>Expected argum</find>
|
128
136
|
<find>def cast</find>
|
129
137
|
<find>limit</find>
|
138
|
+
<find>unkno</find>
|
130
139
|
</findStrings>
|
131
140
|
<replaceStrings>
|
132
141
|
<replace>@@routes</replace>
|
@@ -179,10 +188,8 @@
|
|
179
188
|
<option value="$PROJECT_DIR$/bin/console" />
|
180
189
|
<option value="$PROJECT_DIR$/lib/surikat/templates/console.tmpl" />
|
181
190
|
<option value="$PROJECT_DIR$/lib/surikat/session_manager.rb" />
|
182
|
-
<option value="$PROJECT_DIR$/surikat.gemspec" />
|
183
191
|
<option value="$PROJECT_DIR$/bin/postinstall" />
|
184
192
|
<option value="$PROJECT_DIR$/lib/surikat/base_model.rb" />
|
185
|
-
<option value="$PROJECT_DIR$/README.md" />
|
186
193
|
<option value="$PROJECT_DIR$/lib/surikat/templates/aaa_spec.rb.tmpl" />
|
187
194
|
<option value="$PROJECT_DIR$/lib/surikat/templates/base_spec.rb.tmpl" />
|
188
195
|
<option value="$PROJECT_DIR$/lib/surikat/templates/hello_spec.rb.tmpl" />
|
@@ -192,8 +199,10 @@
|
|
192
199
|
<option value="$PROJECT_DIR$/lib/surikat.rb" />
|
193
200
|
<option value="$PROJECT_DIR$/lib/surikat/templates/config.ru.tmpl" />
|
194
201
|
<option value="$PROJECT_DIR$/lib/surikat/templates/aaa_queries.rb.tmpl" />
|
195
|
-
<option value="$PROJECT_DIR$/lib/surikat/version.rb" />
|
196
202
|
<option value="$PROJECT_DIR$/.gitignore" />
|
203
|
+
<option value="$PROJECT_DIR$/surikat.gemspec" />
|
204
|
+
<option value="$PROJECT_DIR$/README.md" />
|
205
|
+
<option value="$PROJECT_DIR$/lib/surikat/version.rb" />
|
197
206
|
</list>
|
198
207
|
</option>
|
199
208
|
</component>
|
@@ -288,6 +297,116 @@
|
|
288
297
|
<recent name="$PROJECT_DIR$/lib/surikat" />
|
289
298
|
</key>
|
290
299
|
</component>
|
300
|
+
<component name="RestoreUpdateTree" date="Moments ago" ActionInfo="_Update">
|
301
|
+
<UpdatedFiles>
|
302
|
+
<FILE-GROUP>
|
303
|
+
<option name="myUpdateName" value="Updated from server" />
|
304
|
+
<option name="myStatusName" value="Changed on server" />
|
305
|
+
<option name="mySupportsDeletion" value="false" />
|
306
|
+
<option name="myCanBeAbsent" value="false" />
|
307
|
+
<option name="myId" value="CHANGED_ON_SERVER" />
|
308
|
+
<FILE-GROUP>
|
309
|
+
<option name="myUpdateName" value="Updated" />
|
310
|
+
<option name="myStatusName" value="Changed" />
|
311
|
+
<option name="mySupportsDeletion" value="false" />
|
312
|
+
<option name="myCanBeAbsent" value="false" />
|
313
|
+
<option name="myId" value="UPDATED" />
|
314
|
+
<PATH vcs="Git" revision="">$PROJECT_DIR$/README.md</PATH>
|
315
|
+
</FILE-GROUP>
|
316
|
+
<FILE-GROUP>
|
317
|
+
<option name="myUpdateName" value="Created" />
|
318
|
+
<option name="myStatusName" value="Created" />
|
319
|
+
<option name="mySupportsDeletion" value="false" />
|
320
|
+
<option name="myCanBeAbsent" value="false" />
|
321
|
+
<option name="myId" value="CREATED" />
|
322
|
+
</FILE-GROUP>
|
323
|
+
<FILE-GROUP>
|
324
|
+
<option name="myUpdateName" value="Deleted" />
|
325
|
+
<option name="myStatusName" value="Deleted" />
|
326
|
+
<option name="mySupportsDeletion" value="false" />
|
327
|
+
<option name="myCanBeAbsent" value="true" />
|
328
|
+
<option name="myId" value="REMOVED_FROM_REPOSITORY" />
|
329
|
+
</FILE-GROUP>
|
330
|
+
<FILE-GROUP>
|
331
|
+
<option name="myUpdateName" value="Restored" />
|
332
|
+
<option name="myStatusName" value="Will be restored" />
|
333
|
+
<option name="mySupportsDeletion" value="false" />
|
334
|
+
<option name="myCanBeAbsent" value="false" />
|
335
|
+
<option name="myId" value="RESTORED" />
|
336
|
+
</FILE-GROUP>
|
337
|
+
</FILE-GROUP>
|
338
|
+
<FILE-GROUP>
|
339
|
+
<option name="myUpdateName" value="Modified" />
|
340
|
+
<option name="myStatusName" value="Modified" />
|
341
|
+
<option name="mySupportsDeletion" value="false" />
|
342
|
+
<option name="myCanBeAbsent" value="false" />
|
343
|
+
<option name="myId" value="MODIFIED" />
|
344
|
+
</FILE-GROUP>
|
345
|
+
<FILE-GROUP>
|
346
|
+
<option name="myUpdateName" value="Skipped" />
|
347
|
+
<option name="myStatusName" value="Skipped" />
|
348
|
+
<option name="mySupportsDeletion" value="false" />
|
349
|
+
<option name="myCanBeAbsent" value="false" />
|
350
|
+
<option name="myId" value="SKIPPED" />
|
351
|
+
</FILE-GROUP>
|
352
|
+
<FILE-GROUP>
|
353
|
+
<option name="myUpdateName" value="Merged with conflicts" />
|
354
|
+
<option name="myStatusName" value="Will be merged with conflicts" />
|
355
|
+
<option name="mySupportsDeletion" value="false" />
|
356
|
+
<option name="myCanBeAbsent" value="false" />
|
357
|
+
<option name="myId" value="MERGED_WITH_CONFLICTS" />
|
358
|
+
</FILE-GROUP>
|
359
|
+
<FILE-GROUP>
|
360
|
+
<option name="myUpdateName" value="Merged with tree conflicts" />
|
361
|
+
<option name="myStatusName" value="Merged with tree conflicts" />
|
362
|
+
<option name="mySupportsDeletion" value="false" />
|
363
|
+
<option name="myCanBeAbsent" value="false" />
|
364
|
+
<option name="myId" value="MERGED_WITH_TREE_CONFLICT" />
|
365
|
+
</FILE-GROUP>
|
366
|
+
<FILE-GROUP>
|
367
|
+
<option name="myUpdateName" value="Merged with property conflicts" />
|
368
|
+
<option name="myStatusName" value="Will be merged with property conflicts" />
|
369
|
+
<option name="mySupportsDeletion" value="false" />
|
370
|
+
<option name="myCanBeAbsent" value="false" />
|
371
|
+
<option name="myId" value="MERGED_WITH_PROPERTY_CONFLICT" />
|
372
|
+
</FILE-GROUP>
|
373
|
+
<FILE-GROUP>
|
374
|
+
<option name="myUpdateName" value="Merged" />
|
375
|
+
<option name="myStatusName" value="Will be merged" />
|
376
|
+
<option name="mySupportsDeletion" value="false" />
|
377
|
+
<option name="myCanBeAbsent" value="false" />
|
378
|
+
<option name="myId" value="MERGED" />
|
379
|
+
</FILE-GROUP>
|
380
|
+
<FILE-GROUP>
|
381
|
+
<option name="myUpdateName" value="Not in repository" />
|
382
|
+
<option name="myStatusName" value="Not in repository" />
|
383
|
+
<option name="mySupportsDeletion" value="true" />
|
384
|
+
<option name="myCanBeAbsent" value="false" />
|
385
|
+
<option name="myId" value="UNKNOWN" />
|
386
|
+
</FILE-GROUP>
|
387
|
+
<FILE-GROUP>
|
388
|
+
<option name="myUpdateName" value="Locally added" />
|
389
|
+
<option name="myStatusName" value="Locally added" />
|
390
|
+
<option name="mySupportsDeletion" value="false" />
|
391
|
+
<option name="myCanBeAbsent" value="false" />
|
392
|
+
<option name="myId" value="LOCALLY_ADDED" />
|
393
|
+
</FILE-GROUP>
|
394
|
+
<FILE-GROUP>
|
395
|
+
<option name="myUpdateName" value="Locally removed" />
|
396
|
+
<option name="myStatusName" value="Locally removed" />
|
397
|
+
<option name="mySupportsDeletion" value="false" />
|
398
|
+
<option name="myCanBeAbsent" value="false" />
|
399
|
+
<option name="myId" value="LOCALLY_REMOVED" />
|
400
|
+
</FILE-GROUP>
|
401
|
+
<FILE-GROUP>
|
402
|
+
<option name="myUpdateName" value="Switched" />
|
403
|
+
<option name="myStatusName" value="Switched" />
|
404
|
+
<option name="mySupportsDeletion" value="false" />
|
405
|
+
<option name="myCanBeAbsent" value="false" />
|
406
|
+
<option name="myId" value="SWITCHED" />
|
407
|
+
</FILE-GROUP>
|
408
|
+
</UpdatedFiles>
|
409
|
+
</component>
|
291
410
|
<component name="RunDashboard">
|
292
411
|
<option name="ruleStates">
|
293
412
|
<list>
|
@@ -319,7 +438,8 @@
|
|
319
438
|
<workItem from="1529097539864" duration="5610000" />
|
320
439
|
<workItem from="1529237138248" duration="137000" />
|
321
440
|
<workItem from="1529238510739" duration="161000" />
|
322
|
-
<workItem from="1529241304174" duration="
|
441
|
+
<workItem from="1529241304174" duration="10796000" />
|
442
|
+
<workItem from="1541434034250" duration="2366000" />
|
323
443
|
</task>
|
324
444
|
<task id="LOCAL-00001" summary="no gem">
|
325
445
|
<created>1527697580402</created>
|
@@ -475,11 +595,32 @@
|
|
475
595
|
<option name="project" value="LOCAL" />
|
476
596
|
<updated>1529417838725</updated>
|
477
597
|
</task>
|
478
|
-
<
|
598
|
+
<task id="LOCAL-00023" summary="version 0.3.1">
|
599
|
+
<created>1529417932539</created>
|
600
|
+
<option name="number" value="00023" />
|
601
|
+
<option name="presentableId" value="LOCAL-00023" />
|
602
|
+
<option name="project" value="LOCAL" />
|
603
|
+
<updated>1529417932539</updated>
|
604
|
+
</task>
|
605
|
+
<task id="LOCAL-00024" summary="version 0.3.1">
|
606
|
+
<created>1529418019177</created>
|
607
|
+
<option name="number" value="00024" />
|
608
|
+
<option name="presentableId" value="LOCAL-00024" />
|
609
|
+
<option name="project" value="LOCAL" />
|
610
|
+
<updated>1529418019177</updated>
|
611
|
+
</task>
|
612
|
+
<task id="LOCAL-00025" summary="changes to README">
|
613
|
+
<created>1529418190580</created>
|
614
|
+
<option name="number" value="00025" />
|
615
|
+
<option name="presentableId" value="LOCAL-00025" />
|
616
|
+
<option name="project" value="LOCAL" />
|
617
|
+
<updated>1529418190581</updated>
|
618
|
+
</task>
|
619
|
+
<option name="localTasksCounter" value="26" />
|
479
620
|
<servers />
|
480
621
|
</component>
|
481
622
|
<component name="TimeTrackingManager">
|
482
|
-
<option name="totallyTimeSpent" value="
|
623
|
+
<option name="totallyTimeSpent" value="153242000" />
|
483
624
|
</component>
|
484
625
|
<component name="TodoView">
|
485
626
|
<todo-panel id="selected-file">
|
@@ -494,26 +635,27 @@
|
|
494
635
|
<frame x="-1889" y="23" width="1889" height="1057" extended-state="0" />
|
495
636
|
<editor active="true" />
|
496
637
|
<layout>
|
497
|
-
<window_info
|
498
|
-
<window_info
|
499
|
-
<window_info
|
500
|
-
<window_info anchor="bottom" id="
|
501
|
-
<window_info anchor="bottom" id="
|
502
|
-
<window_info anchor="bottom" id="Version Control" order="10" />
|
503
|
-
<window_info anchor="right" id="Mongo Explorer" order="3" />
|
504
|
-
<window_info anchor="bottom" id="Terminal" order="8" />
|
505
|
-
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.48665956" visible="true" weight="0.2512182" />
|
506
|
-
<window_info anchor="right" id="Database" order="4" />
|
638
|
+
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.48565355" visible="true" weight="0.2512182" />
|
639
|
+
<window_info id="Structure" order="1" sideWeight="0.5143464" side_tool="true" visible="true" weight="0.2512182" />
|
640
|
+
<window_info id="Favorites" order="2" side_tool="true" />
|
641
|
+
<window_info anchor="bottom" id="GraphQL" weight="0.32943678" />
|
642
|
+
<window_info anchor="bottom" id="Message" order="0" />
|
507
643
|
<window_info anchor="bottom" id="Find" order="1" weight="0.32977587" />
|
508
|
-
<window_info
|
644
|
+
<window_info anchor="bottom" id="Run" order="2" weight="0.32977587" />
|
509
645
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
510
|
-
<window_info id="
|
511
|
-
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
646
|
+
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
512
647
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
648
|
+
<window_info anchor="bottom" id="TODO" order="6" weight="0.32977587" />
|
649
|
+
<window_info anchor="bottom" id="Database Changes" order="7" show_stripe_button="false" />
|
650
|
+
<window_info anchor="bottom" id="Terminal" order="8" />
|
651
|
+
<window_info anchor="bottom" id="Messages" order="9" weight="0.32977587" />
|
652
|
+
<window_info anchor="bottom" id="Version Control" order="10" />
|
653
|
+
<window_info anchor="bottom" id="Event Log" order="11" side_tool="true" />
|
513
654
|
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
514
655
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
515
|
-
<window_info anchor="
|
516
|
-
<window_info anchor="
|
656
|
+
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
657
|
+
<window_info anchor="right" id="Mongo Explorer" order="3" />
|
658
|
+
<window_info anchor="right" id="Database" order="4" />
|
517
659
|
</layout>
|
518
660
|
</component>
|
519
661
|
<component name="TypeScriptGeneratedFilesManager">
|
@@ -541,22 +683,11 @@
|
|
541
683
|
<MESSAGE value="added support for preflight" />
|
542
684
|
<MESSAGE value="fixed small session issues" />
|
543
685
|
<MESSAGE value="added frontend-demo" />
|
544
|
-
<
|
545
|
-
|
546
|
-
|
547
|
-
<breakpoint-manager>
|
548
|
-
<option name="time" value="4" />
|
549
|
-
</breakpoint-manager>
|
686
|
+
<MESSAGE value="version 0.3.1" />
|
687
|
+
<MESSAGE value="changes to README" />
|
688
|
+
<option name="LAST_COMMIT_MESSAGE" value="changes to README" />
|
550
689
|
</component>
|
551
690
|
<component name="editorHistoryManager">
|
552
|
-
<entry file="file://$PROJECT_DIR$/lib/surikat/main.rb" />
|
553
|
-
<entry file="file://$PROJECT_DIR$/TODO">
|
554
|
-
<provider selected="true" editor-type-id="text-editor">
|
555
|
-
<state relative-caret-position="204">
|
556
|
-
<caret line="12" column="12" lean-forward="true" selection-start-line="12" selection-start-column="12" selection-end-line="12" selection-end-column="12" />
|
557
|
-
</state>
|
558
|
-
</provider>
|
559
|
-
</entry>
|
560
691
|
<entry file="file://$PROJECT_DIR$/lib/surikat/main.rb" />
|
561
692
|
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/aaa.yml.tmpl" />
|
562
693
|
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/aaa.rb.tmpl" />
|
@@ -1180,13 +1311,6 @@
|
|
1180
1311
|
</state>
|
1181
1312
|
</provider>
|
1182
1313
|
</entry>
|
1183
|
-
<entry file="file://$PROJECT_DIR$/surikat.gemspec">
|
1184
|
-
<provider selected="true" editor-type-id="text-editor">
|
1185
|
-
<state relative-caret-position="488">
|
1186
|
-
<caret line="39" column="2" selection-start-line="39" selection-start-column="2" selection-end-line="39" selection-end-column="2" />
|
1187
|
-
</state>
|
1188
|
-
</provider>
|
1189
|
-
</entry>
|
1190
1314
|
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/application.yml.tmpl">
|
1191
1315
|
<provider selected="true" editor-type-id="text-editor">
|
1192
1316
|
<state relative-caret-position="221">
|
@@ -1264,23 +1388,6 @@
|
|
1264
1388
|
</state>
|
1265
1389
|
</provider>
|
1266
1390
|
</entry>
|
1267
|
-
<entry file="file://$PROJECT_DIR$/README.md">
|
1268
|
-
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
1269
|
-
<state split_layout="SPLIT">
|
1270
|
-
<first_editor relative-caret-position="-2426">
|
1271
|
-
<caret line="227" column="197" selection-start-line="227" selection-start-column="197" selection-end-line="227" selection-end-column="197" />
|
1272
|
-
</first_editor>
|
1273
|
-
<second_editor />
|
1274
|
-
</state>
|
1275
|
-
</provider>
|
1276
|
-
</entry>
|
1277
|
-
<entry file="file://$PROJECT_DIR$/TODO">
|
1278
|
-
<provider selected="true" editor-type-id="text-editor">
|
1279
|
-
<state relative-caret-position="544">
|
1280
|
-
<caret line="32" column="65" selection-start-line="32" selection-start-column="65" selection-end-line="32" selection-end-column="65" />
|
1281
|
-
</state>
|
1282
|
-
</provider>
|
1283
|
-
</entry>
|
1284
1391
|
<entry file="file://$PROJECT_DIR$/exe/surikat">
|
1285
1392
|
<provider selected="true" editor-type-id="text-editor">
|
1286
1393
|
<state relative-caret-position="605">
|
@@ -1309,24 +1416,48 @@
|
|
1309
1416
|
</state>
|
1310
1417
|
</provider>
|
1311
1418
|
</entry>
|
1419
|
+
<entry file="file://$PROJECT_DIR$/.gitignore">
|
1420
|
+
<provider selected="true" editor-type-id="text-editor">
|
1421
|
+
<state relative-caret-position="238">
|
1422
|
+
<caret line="14" column="4" selection-start-line="14" selection-start-column="4" selection-end-line="14" selection-end-column="4" />
|
1423
|
+
</state>
|
1424
|
+
</provider>
|
1425
|
+
</entry>
|
1312
1426
|
<entry file="file://$PROJECT_DIR$/lib/surikat/templates/config.ru.tmpl">
|
1313
1427
|
<provider selected="true" editor-type-id="text-editor">
|
1314
|
-
<state relative-caret-position="
|
1315
|
-
<caret line="
|
1428
|
+
<state relative-caret-position="121">
|
1429
|
+
<caret line="12" column="5" selection-start-line="12" selection-start-column="5" selection-end-line="12" selection-end-column="5" />
|
1316
1430
|
</state>
|
1317
1431
|
</provider>
|
1318
1432
|
</entry>
|
1319
|
-
<entry file="file://$PROJECT_DIR$/
|
1433
|
+
<entry file="file://$PROJECT_DIR$/TODO">
|
1320
1434
|
<provider selected="true" editor-type-id="text-editor">
|
1321
|
-
<state relative-caret-position="
|
1322
|
-
<caret line="
|
1435
|
+
<state relative-caret-position="544">
|
1436
|
+
<caret line="32" column="65" selection-start-line="32" selection-start-column="65" selection-end-line="32" selection-end-column="65" />
|
1323
1437
|
</state>
|
1324
1438
|
</provider>
|
1325
1439
|
</entry>
|
1326
|
-
<entry file="file://$PROJECT_DIR
|
1440
|
+
<entry file="file://$PROJECT_DIR$/surikat.gemspec">
|
1327
1441
|
<provider selected="true" editor-type-id="text-editor">
|
1328
|
-
<state relative-caret-position="
|
1329
|
-
<caret line="
|
1442
|
+
<state relative-caret-position="679">
|
1443
|
+
<caret line="50" column="50" selection-start-line="50" selection-start-column="50" selection-end-line="50" selection-end-column="50" />
|
1444
|
+
</state>
|
1445
|
+
</provider>
|
1446
|
+
</entry>
|
1447
|
+
<entry file="file://$PROJECT_DIR$/README.md">
|
1448
|
+
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
|
1449
|
+
<state split_layout="SPLIT">
|
1450
|
+
<first_editor relative-caret-position="-296">
|
1451
|
+
<caret line="470" column="6" selection-start-line="470" selection-start-column="6" selection-end-line="470" selection-end-column="6" />
|
1452
|
+
</first_editor>
|
1453
|
+
<second_editor />
|
1454
|
+
</state>
|
1455
|
+
</provider>
|
1456
|
+
</entry>
|
1457
|
+
<entry file="file://$PROJECT_DIR$/lib/surikat/version.rb">
|
1458
|
+
<provider selected="true" editor-type-id="text-editor">
|
1459
|
+
<state relative-caret-position="17">
|
1460
|
+
<caret line="1" column="18" selection-start-line="1" selection-start-column="18" selection-end-line="1" selection-end-column="18" />
|
1330
1461
|
</state>
|
1331
1462
|
</provider>
|
1332
1463
|
</entry>
|
data/README.md
CHANGED
@@ -2,33 +2,38 @@
|
|
2
2
|
|
3
3
|
![Surikat](https://i.imgur.com/OlCUw38.png)
|
4
4
|
|
5
|
-
## A backend web framework centred
|
5
|
+
## A backend web framework centred on GraphQL.
|
6
6
|
|
7
|
-
Many frontend apps require little more than a simple backend that does a few
|
8
|
-
and handles user authentication, authorisation and access
|
7
|
+
Many frontend apps require little more than a simple backend that does a few
|
8
|
+
CRUD operations and handles user authentication, authorisation and access
|
9
|
+
(AAA).
|
9
10
|
|
10
|
-
For even the simplest backends, frontend developers must invest time and
|
11
|
-
into some unfamiliar framework, and then code the app -- often in
|
12
|
-
comfortable in.
|
11
|
+
For even the simplest backends, frontend developers must invest time and
|
12
|
+
knowledge into some unfamiliar framework, and then code the app -- often in
|
13
|
+
a language that they're not very comfortable in.
|
13
14
|
|
14
15
|
Surikat solves much of that.
|
15
16
|
|
16
|
-
With Surikat, you can have a backend app up and running in under a minute, that
|
17
|
-
and AAA, with no code at all.
|
17
|
+
With Surikat, you can have a backend app up and running in under a minute, that
|
18
|
+
does CRUD and AAA, with no code at all.
|
18
19
|
|
19
|
-
Sure, Rails has scaffolding -- but not for AAA, and not for GraphQL. Sure,
|
20
|
-
they have significant learning curves.
|
20
|
+
Sure, Rails has scaffolding -- but not for AAA, and not for GraphQL. Sure,
|
21
|
+
there are gems for that -- but they have significant learning curves.
|
21
22
|
|
22
|
-
Sure, Rails can make API-only apps -- but only REST API apps.
|
23
|
-
|
24
|
-
|
23
|
+
Sure, Rails can make API-only apps -- but only REST API apps.
|
24
|
+
[GraphQL](http://graphql.org), a standard created by Facebook and made
|
25
|
+
open-source since then, is far more efficient than REST. There's only one
|
26
|
+
endpoint, and you get exactly the data that you ask for -- nothing else.
|
25
27
|
|
26
|
-
Sure, Rails can also be taught GraphQL. But that's an add-on to everything else
|
27
|
-
does; by contrast, Surikat was built, from the ground up, around
|
28
|
+
Sure, Rails can also be taught GraphQL. But that's an add-on to everything else
|
29
|
+
that Rails does; by contrast, Surikat was built, from the ground up, around
|
30
|
+
GraphQL.
|
28
31
|
|
29
|
-
Writing the backend for GraphQL queries, in most existing frameworks, can be
|
30
|
-
Surikat organises, simplifies and exemplifies all
|
31
|
-
|
32
|
+
Writing the backend for GraphQL queries, in most existing frameworks, can be
|
33
|
+
tedious and complicated. Surikat organises, simplifies and exemplifies all
|
34
|
+
queries, and it even helps a lot with testing them. You always know how to call
|
35
|
+
a query, even without introspection; Surikat is intuitive, and will always have
|
36
|
+
an example handy.
|
32
37
|
|
33
38
|
### Quick Start
|
34
39
|
|
@@ -37,9 +42,9 @@ $ gem install surikat
|
|
37
42
|
$ surikat new library
|
38
43
|
```
|
39
44
|
|
40
|
-
Once the Surikat app is created, follow the instructions; `cd` into the app
|
41
|
-
run `rspec` for tests, `passenger start` to start a web server,
|
42
|
-
stuff out, etc.
|
45
|
+
Once the Surikat app is created, follow the instructions; `cd` into the app
|
46
|
+
directory, run `rspec` for tests, `passenger start` to start a web server,
|
47
|
+
`bin/console` to try stuff out, etc.
|
43
48
|
|
44
49
|
Just type `surikat` to see what the command line tool can do.
|
45
50
|
|
@@ -48,18 +53,21 @@ Just type `surikat` to see what the command line tool can do.
|
|
48
53
|
Surikat operates with four concepts: *Routes*, *Types*, *Queries* and *Models*.
|
49
54
|
|
50
55
|
#### Models
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
|
57
|
+
Surikat is not an MVC framework; it lacks the V and the C. But it does use
|
58
|
+
models, and in particular, the ActiveRecord library that Ruby on Rails was
|
59
|
+
initially based on. If you're familiar with modern MVC frameworks, then you'll
|
60
|
+
feel right at home with Surikat models.
|
55
61
|
|
56
62
|
#### Queries
|
57
|
-
With Surikat, Queries are simple Ruby code; you don't have to learn any complicated DSL
|
58
|
-
or try to adapt to someone else's idea of what a GraphQL query definition should look like.
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
64
|
+
With Surikat, Queries are simple Ruby code; you don't have to learn any
|
65
|
+
complicated DSL or try to adapt to someone else's idea of what a GraphQL query
|
66
|
+
definition should look like.
|
67
|
+
|
68
|
+
Each model file has a companion queries file, but you can also write your own
|
69
|
+
queries. By using some simple conventions, and routes (see below), queries can
|
70
|
+
easily be represented as simple methods:
|
63
71
|
|
64
72
|
```ruby
|
65
73
|
class AuthorQueries < Surikat::BaseQueries
|
@@ -70,10 +78,11 @@ end
|
|
70
78
|
```
|
71
79
|
|
72
80
|
#### Routes
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
the
|
81
|
+
|
82
|
+
Models and Queries are the only components of Surikat which require
|
83
|
+
a programming language (Ruby). The other half are simple YAML files, which can
|
84
|
+
be edited manually or programmatically. Routes describe the links between
|
85
|
+
GraphQL queries (or mutations), and the queries method.
|
77
86
|
|
78
87
|
For example, the query method above might be routed thus:
|
79
88
|
|
@@ -87,12 +96,15 @@ Author:
|
|
87
96
|
```
|
88
97
|
|
89
98
|
#### Types
|
90
|
-
You'll notice in the route above that it mentions an output_type named `Author`. Just
|
91
|
-
like routes, types live also in YAML files, and they are used to describe the data
|
92
|
-
that goes in the app (input types), and the data that comes out (output types).
|
93
99
|
|
94
|
-
|
95
|
-
|
100
|
+
You'll notice in the route above that it mentions an output_type named
|
101
|
+
`Author`. Just like routes, types live also in YAML files, and they are used to
|
102
|
+
describe the data that goes in the app (input types), and the data that comes
|
103
|
+
out (output types).
|
104
|
+
|
105
|
+
In the example above, the `Author` route calls the `get` method of the
|
106
|
+
`AuthorQueries` class, and it formats its return (an `Author` database record)
|
107
|
+
to match a given type. Case in point:
|
96
108
|
|
97
109
|
```yaml
|
98
110
|
Author:
|
@@ -105,9 +117,10 @@ Author:
|
|
105
117
|
books: "[Book]"
|
106
118
|
```
|
107
119
|
|
108
|
-
These are all the fields that the frontend would have access to; a `name` of
|
109
|
-
two timestamps which are also automatically cast as
|
110
|
-
and an array of books (which are, in turn,
|
120
|
+
These are all the fields that the frontend would have access to; a `name` of
|
121
|
+
the type `String`, two timestamps which are also automatically cast as
|
122
|
+
`String`, the record database id, and an array of books (which are, in turn,
|
123
|
+
rendered in accordance to their own `Book` output type).
|
111
124
|
|
112
125
|
### Examplifying Queries
|
113
126
|
|
@@ -138,9 +151,9 @@ curl 0:3000 -X POST -d 'query=%7B%0A++Author%28id%3A+1%29+%7B%0A++++name%0A++++c
|
|
138
151
|
|
139
152
|
### Scaffolding
|
140
153
|
|
141
|
-
Surikat comes with a convenient scaffolding tool, which creates a model (with
|
142
|
-
a set of queries for it (to Create, Retrieve, Update and
|
143
|
-
types, routes and tests.
|
154
|
+
Surikat comes with a convenient scaffolding tool, which creates a model (with
|
155
|
+
a database migration), a set of queries for it (to Create, Retrieve, Update and
|
156
|
+
Delete), as well as the necessary types, routes and tests.
|
144
157
|
|
145
158
|
Example:
|
146
159
|
|
@@ -150,8 +163,9 @@ surikat generate model Book title:string
|
|
150
163
|
|
151
164
|
#### A Note About Ransack
|
152
165
|
|
153
|
-
Surikat comes with Ransack, so that when you retrieve a collection of
|
154
|
-
already filter and sort them using
|
166
|
+
Surikat comes with Ransack, so that when you retrieve a collection of
|
167
|
+
ActiveRecord objects, you can already filter and sort them using
|
168
|
+
[Ransack search matchers](https://github.com/activerecord-hackery/ransack#search-matchers).
|
155
169
|
|
156
170
|
Example query:
|
157
171
|
|
@@ -169,11 +183,12 @@ Example query:
|
|
169
183
|
|
170
184
|
### Custom Data
|
171
185
|
|
172
|
-
Sometimes you need to supply
|
173
|
-
In fact, you can send anything you want; here are a few
|
186
|
+
Sometimes you need to supply things to the frontend that don't come directly
|
187
|
+
from the database. In fact, you can send anything you want; here are a few
|
188
|
+
simple recipes:
|
174
189
|
|
175
|
-
1. To add an additional field to the ones already provided by the database,
|
176
|
-
is to define a method in the model.
|
190
|
+
1. To add an additional field to the ones already provided by the database,
|
191
|
+
the easiest way is to define a method in the model.
|
177
192
|
|
178
193
|
```ruby
|
179
194
|
class Person < Surikat::BaseModel
|
@@ -205,9 +220,9 @@ is to define a method in the model.
|
|
205
220
|
}
|
206
221
|
```
|
207
222
|
|
208
|
-
3. Returning custom types is also easy. If you have an output type that
|
209
|
-
`favourite_food` and `favourite_drink`, all your query
|
210
|
-
that has those two keys.
|
223
|
+
3. Returning custom types is also easy. If you have an output type that
|
224
|
+
defines the fields `favourite_food` and `favourite_drink`, all your query
|
225
|
+
needs to do is to return a Ruby `Hash` that has those two keys.
|
211
226
|
|
212
227
|
```ruby
|
213
228
|
class MyQueries < Surikat::BaseQueries
|
@@ -225,11 +240,14 @@ that has those two keys.
|
|
225
240
|
|
226
241
|
#### Errors
|
227
242
|
|
228
|
-
As per [GraphQL specs](http://facebook.github.io/graphql/June2018/#sec-Errors),
|
243
|
+
As per [GraphQL specs](http://facebook.github.io/graphql/June2018/#sec-Errors),
|
244
|
+
application errors, type errors or model validation errors are returned inside
|
245
|
+
a field named `errors` which is an array.
|
229
246
|
|
230
247
|
#### Arguments
|
231
248
|
|
232
|
-
In the queries, you always have access to the query arguments via the
|
249
|
+
In the queries, you always have access to the query arguments via the
|
250
|
+
`arguments` helper:
|
233
251
|
|
234
252
|
```ruby
|
235
253
|
class AuthorQueries < Surikat::BaseQueries
|
@@ -241,9 +259,11 @@ end
|
|
241
259
|
|
242
260
|
### Session
|
243
261
|
|
244
|
-
Session management is easy with Surikat. Simply carry around an HTTP header
|
245
|
-
as randomly unique as possible. You
|
246
|
-
|
262
|
+
Session management is easy with Surikat. Simply carry around an HTTP header
|
263
|
+
named 'Surikat' with a value that's as randomly unique as possible. You
|
264
|
+
probably want to generate this value when your frontend app loads, then use it
|
265
|
+
for all Surikat queries. As long as you send the same Surikat header, you'll
|
266
|
+
maintain a session.
|
247
267
|
|
248
268
|
With curl:
|
249
269
|
|
@@ -251,7 +271,8 @@ With curl:
|
|
251
271
|
curl 0:3000 -X POST -d 'query=%7B%0AHello%0A%7D' -H 'Surikat: 1234'
|
252
272
|
```
|
253
273
|
|
254
|
-
In the queries, you always have access to the session object via the `session`
|
274
|
+
In the queries, you always have access to the session object via the `session`
|
275
|
+
helper:
|
255
276
|
|
256
277
|
```ruby
|
257
278
|
class AuthorQueries < Surikat::BaseQueries
|
@@ -269,25 +290,31 @@ end
|
|
269
290
|
|
270
291
|
#### Session Stores
|
271
292
|
|
272
|
-
The session store is configured in `config/application.yml` and it can either
|
293
|
+
The session store is configured in `config/application.yml` and it can either
|
294
|
+
be a file, or Redis.
|
273
295
|
|
274
|
-
The file method is slower, and
|
275
|
-
|
296
|
+
The file method is slower, and it gets slower as the file (which lives in
|
297
|
+
`tmp/`) gets bigger. Needless to say, it also doesn't work to scale up the app
|
298
|
+
across several machines.
|
276
299
|
|
277
|
-
Redis is much preferred especially in production; remember to add the `redis`
|
278
|
-
use the `url` field in the same configuration
|
300
|
+
Redis is much preferred especially in production; remember to add the `redis`
|
301
|
+
gem to Gemfile. To configure it, use the `url` field in the same configuration
|
302
|
+
file; that will be passed to the Redis initialisation method.
|
279
303
|
|
280
304
|
### Authentication, Authorisation and Access
|
281
305
|
|
282
|
-
Surikat comes with triple-A, but it's not enabled by default. Rather, the files
|
306
|
+
Surikat comes with triple-A, but it's not enabled by default. Rather, the files
|
307
|
+
must be generated:
|
283
308
|
|
284
309
|
```bash
|
285
310
|
surikat generate aaa
|
286
311
|
```
|
287
312
|
|
288
|
-
This will create a `User` model (plus migration), a class called `AAAQueries`
|
313
|
+
This will create a `User` model (plus migration), a class called `AAAQueries`
|
314
|
+
and a suite of tests.
|
289
315
|
|
290
|
-
The model will, by default, have three columns: `email`, `hashed_password` and
|
316
|
+
The model will, by default, have three columns: `email`, `hashed_password` and
|
317
|
+
`roleids`.
|
291
318
|
|
292
319
|
To create a user, use the `password` accessor.
|
293
320
|
|
@@ -299,37 +326,48 @@ User.create email:'a@b.com', password:'abc'
|
|
299
326
|
|
300
327
|
Surikat will save a SHA256 digest for that password in the database.
|
301
328
|
|
302
|
-
To restrict a query to logged in users, add `permitted_roles: any` to its
|
329
|
+
To restrict a query to logged in users, add `permitted_roles: any` to its
|
330
|
+
route.
|
303
331
|
|
304
|
-
To restrict a query to particular user roles (more about roles below), add for
|
332
|
+
To restrict a query to particular user roles (more about roles below), add for
|
333
|
+
example `permitted_roles: admin,superadmin` to its route.
|
305
334
|
|
306
|
-
The AAA queries available to you are described in `app/queries/aaa_queries.rb`,
|
307
|
-
In short, they are:
|
335
|
+
The AAA queries available to you are described in `app/queries/aaa_queries.rb`,
|
336
|
+
including even query examples. In short, they are:
|
308
337
|
|
309
|
-
* `Authenticate` - you pass the email and password, and you get a boolean value;
|
310
|
-
succeeds, then a `user_id` will be stored in the session
|
338
|
+
* `Authenticate` - you pass the email and password, and you get a boolean value;
|
339
|
+
if the authentication succeeds, then a `user_id` will be stored in the session
|
340
|
+
object, giving you access to the current user.
|
311
341
|
|
312
342
|
* `Logout` - self-explanatory.
|
313
343
|
|
314
344
|
* `CurrentUser` - returns the current user based on what's in `session[:user_id]`.
|
315
345
|
|
316
|
-
* `LoginAs` - allows a superadmin to login as another user (more about superadmins
|
317
|
-
During this time, the session will also contain
|
346
|
+
* `LoginAs` - allows a superadmin to login as another user (more about superadmins
|
347
|
+
in the Roles section below). During this time, the session will also contain
|
348
|
+
`:superadmin_id`.
|
318
349
|
|
319
|
-
* `BackFrom LoginAs` - having logged in as someone else, return as the initial
|
350
|
+
* `BackFrom LoginAs` - having logged in as someone else, return as the initial
|
351
|
+
superadmin.
|
320
352
|
|
321
|
-
* `DemoOne`, `DemoTwo` and `DemoThree` - used by the rspec tests. If you delete
|
353
|
+
* `DemoOne`, `DemoTwo` and `DemoThree` - used by the rspec tests. If you delete
|
354
|
+
them, please also delete the corresponding tests in `spec/aaa_spec.rb`.
|
322
355
|
|
323
356
|
#### Roles
|
324
357
|
|
325
|
-
Roles are simply identifiers stored, for a user, inside the `roleids`
|
358
|
+
Roles are simply identifiers stored, for a user, inside the `roleids`
|
359
|
+
attribute, and comma-separated.
|
326
360
|
|
327
|
-
Before a query is executed, the
|
328
|
-
If it's `any` then a user of any role is allowed
|
329
|
-
|
361
|
+
Before a query is executed, the content of its `permitted_roles` field (from
|
362
|
+
its route) is evaluated. If it's `any` then a user of any role is allowed
|
363
|
+
access. If it's a comma separated array of role identifiers, then access will
|
364
|
+
only be granted if there's an intersection between those roles and the current
|
365
|
+
user's.
|
330
366
|
|
331
367
|
### Application Structure
|
368
|
+
|
332
369
|
A Surikat app has the following directory structure:
|
370
|
+
|
333
371
|
```bash
|
334
372
|
├── Gemfile
|
335
373
|
├── Rakefile
|
@@ -362,29 +400,101 @@ A Surikat app has the following directory structure:
|
|
362
400
|
|
363
401
|
### Testing
|
364
402
|
|
365
|
-
All the scaffolds come with running tests; just run `rspec` or, if you'd rather
|
366
|
-
some details, `rspec -f d`.
|
403
|
+
All the scaffolds come with running tests; just run `rspec` or, if you'd rather
|
404
|
+
see some details, `rspec -f d`.
|
367
405
|
|
368
406
|
If you change the scaffolding, you need to change the tests, too.
|
369
407
|
|
370
|
-
*Note:* The intention was (and still is) to make autotests fully independent,
|
371
|
-
|
372
|
-
|
408
|
+
*Note:* The intention was (and still is) to make autotests fully independent,
|
409
|
+
so that they still test the scaffolded code even after you change it. However,
|
410
|
+
because of field arguments, that's not exactly trivial. Hopefully a later
|
411
|
+
release will come with a solution to this issue. Until then, you have to adapt
|
412
|
+
the tests to your code changes "by hand".
|
373
413
|
|
374
414
|
### Web Server
|
375
415
|
|
376
|
-
Surikat uses [Phusion Passenger](https://www.phusionpassenger.com/) as a web
|
416
|
+
Surikat uses [Phusion Passenger](https://www.phusionpassenger.com/) as a web
|
417
|
+
server. Simply type
|
377
418
|
|
378
419
|
```bash
|
379
|
-
passenger
|
420
|
+
passenger start
|
380
421
|
```
|
381
422
|
|
382
|
-
to start a server on port 3000. Then you can use GraphiQL, curl or your actual
|
383
|
-
querying the backend.
|
423
|
+
to start a server on port 3000. Then you can use GraphiQL, curl or your actual
|
424
|
+
frontend app to start querying the backend.
|
425
|
+
|
426
|
+
To start in production mode:
|
427
|
+
|
428
|
+
```bash
|
429
|
+
passenger start -e production
|
430
|
+
```
|
431
|
+
|
432
|
+
## Demo
|
433
|
+
|
434
|
+
There's a small front-end "app" which may be used as a demo, in the
|
435
|
+
`frontend-demo` directory, and it has its own README.
|
436
|
+
|
437
|
+
## Benchmarking
|
438
|
+
|
439
|
+
To benchmark a Surikat app, you can use Apache Benchmark. For that, first save
|
440
|
+
a query inside a file, for example:
|
441
|
+
|
442
|
+
```bash
|
443
|
+
$ cat surikat.query ‹ruby-2.4.1›
|
444
|
+
query={Authors(q: "id_lt=10") {first_name}}
|
445
|
+
```
|
446
|
+
|
447
|
+
Then, start Passenger (see above) and invoke Apache Benchmark for example like this:
|
448
|
+
|
449
|
+
```bash
|
450
|
+
ab -k -c 10 -n 100 -T 'application/x-www-form-urlencoded' -p surikat.query http://0:3000/
|
451
|
+
```
|
452
|
+
|
453
|
+
This runs 10 concurrent requests, to a maximum of 100 requests.
|
454
|
+
|
455
|
+
## Benchmarking Results
|
456
|
+
|
457
|
+
Benchmarking tests were performed in the following conditions:
|
458
|
+
|
459
|
+
Machine: iMac 3.1 GHz Intel Core i7, 16 GB RAM (running macOS Mojave, 10.14)
|
460
|
+
Database Server: MySQL 5.7.10
|
461
|
+
Database: 20,000 authors who together have 141,224 books
|
462
|
+
Ruby: 2.4.1-p111
|
463
|
+
|
464
|
+
Surikat 0.3.1 versus Rails 5.2.1 with graphql 1.8.11 (latest at the time)
|
465
|
+
|
466
|
+
Surikat app: two auto-generated scaffolds (one for authors, one for books).
|
467
|
+
Rails app: two models (`Author` and `Book` and minimal queries.)
|
468
|
+
|
469
|
+
Both apps use Ransack 2.1.0 in exactly the same way.
|
470
|
+
|
471
|
+
Both apps connected to the same database.
|
472
|
+
|
473
|
+
Only default values used everywhere else (no optimisations etc.)
|
474
|
+
|
475
|
+
### Test 1.
|
476
|
+
Query:
|
477
|
+
```graphql
|
478
|
+
{Authors(q: "id_lt=10") {first_name, books{title}}}
|
479
|
+
```
|
480
|
+
|
481
|
+
* Rails: 6.67 requests per second.
|
482
|
+
* __Surikat: 9.70 requests per second.__
|
483
|
+
|
484
|
+
### Test 2.
|
485
|
+
Query:
|
486
|
+
```graphql
|
487
|
+
{Authors(q: "id_lt=10") {first_name}}
|
488
|
+
```
|
489
|
+
|
490
|
+
* Rails: 164.86 requests per second.
|
491
|
+
* __Surikat: 1,332.52 requests per second.__
|
492
|
+
|
384
493
|
|
385
494
|
## System Dependencies
|
386
495
|
|
387
|
-
For improved performance, Surikat uses a C++ library to parse GraplQL queries,
|
496
|
+
For improved performance, Surikat uses a C++ library to parse GraplQL queries,
|
497
|
+
[libgraphqlparser](https://github.com/graphql/libgraphqlparser).
|
388
498
|
|
389
499
|
On Mac OS X, install with Homebrew:
|
390
500
|
|
@@ -394,23 +504,31 @@ brew install libgraphqlparser
|
|
394
504
|
|
395
505
|
## Development
|
396
506
|
|
397
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
507
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
508
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
509
|
+
prompt that will allow you to experiment.
|
398
510
|
|
399
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To
|
511
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
512
|
+
release a new version, update the version number in `version.rb`, and then run
|
513
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
514
|
+
git commits and tags, and push the `.gem` file to
|
515
|
+
[rubygems.org](https://rubygems.org).
|
400
516
|
|
401
517
|
To install the gem locally:
|
402
518
|
`gem uninstall -x surikat && gem build surikat.gemspec && gem install surikat --no-ri --no-rdoc && ruby bin/postinstall`
|
403
519
|
|
404
520
|
## Contributing
|
405
521
|
|
406
|
-
Bug reports and pull requests are welcome on GitHub at
|
522
|
+
Bug reports and pull requests are welcome on GitHub at
|
523
|
+
https://github.com/alxx/surikat.
|
407
524
|
|
408
525
|
## Version
|
409
526
|
|
410
|
-
This code reflects version 0.3.
|
527
|
+
This code reflects version 0.3.1.
|
411
528
|
|
412
529
|
## License
|
413
530
|
|
414
531
|
Author: Alex Deva (me@alxx.se)
|
415
532
|
|
416
|
-
The gem is available as open source under the terms of the
|
533
|
+
The gem is available as open source under the terms of the
|
534
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
data/lib/surikat/version.rb
CHANGED
data/surikat.gemspec
CHANGED
@@ -48,7 +48,7 @@ Gem::Specification.new do |spec|
|
|
48
48
|
spec.add_runtime_dependency "sqlite3", "~> 1.3", '>= 1.3.13'
|
49
49
|
spec.add_runtime_dependency "rspec", "~> 3.7", '>= 3.7.0'
|
50
50
|
spec.add_runtime_dependency "graphql-libgraphqlparser", "~> 1.2", ">= 1.2.0"
|
51
|
-
spec.add_runtime_dependency "ransack", "~>
|
51
|
+
spec.add_runtime_dependency "ransack", "~> 2.0"#, ">= 1.8.2"
|
52
52
|
spec.add_runtime_dependency "bundler", "~> 1.15"
|
53
53
|
spec.add_runtime_dependency "rake", "~> 10.0"
|
54
54
|
spec.add_runtime_dependency "rack-app", "~> 7.5"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surikat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Deva
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -124,20 +124,14 @@ dependencies:
|
|
124
124
|
requirements:
|
125
125
|
- - "~>"
|
126
126
|
- !ruby/object:Gem::Version
|
127
|
-
version: '
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: 1.8.2
|
127
|
+
version: '2.0'
|
131
128
|
type: :runtime
|
132
129
|
prerelease: false
|
133
130
|
version_requirements: !ruby/object:Gem::Requirement
|
134
131
|
requirements:
|
135
132
|
- - "~>"
|
136
133
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
138
|
-
- - ">="
|
139
|
-
- !ruby/object:Gem::Version
|
140
|
-
version: 1.8.2
|
134
|
+
version: '2.0'
|
141
135
|
- !ruby/object:Gem::Dependency
|
142
136
|
name: bundler
|
143
137
|
requirement: !ruby/object:Gem::Requirement
|