typekit-client 0.0.5 → 0.0.6

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -3
  3. data/.travis.yml +4 -0
  4. data/.yardopts +6 -0
  5. data/CHANGELOG.md +12 -0
  6. data/Guardfile +21 -3
  7. data/README.md +253 -248
  8. data/bin/typekit-client +16 -16
  9. data/bin/typekit-publisher +6 -5
  10. data/lib/typekit.rb +6 -2
  11. data/lib/typekit/client.rb +66 -24
  12. data/lib/typekit/collection.rb +6 -11
  13. data/lib/typekit/collection/base.rb +40 -0
  14. data/lib/typekit/collection/serialization.rb +17 -0
  15. data/lib/typekit/converter.rb +26 -0
  16. data/lib/typekit/converter/boolean.rb +12 -0
  17. data/lib/typekit/converter/collection.rb +13 -0
  18. data/lib/typekit/converter/datetime.rb +12 -0
  19. data/lib/typekit/converter/element.rb +13 -0
  20. data/lib/typekit/converter/errors.rb +12 -0
  21. data/lib/typekit/converter/unknown.rb +13 -0
  22. data/lib/typekit/core.rb +8 -10
  23. data/lib/typekit/element.rb +27 -0
  24. data/lib/typekit/element/association.rb +63 -0
  25. data/lib/typekit/element/base.rb +61 -0
  26. data/lib/typekit/element/persistence.rb +61 -0
  27. data/lib/typekit/element/query.rb +25 -0
  28. data/lib/typekit/element/serialization.rb +17 -0
  29. data/lib/typekit/error.rb +23 -0
  30. data/lib/typekit/helper.rb +59 -10
  31. data/lib/typekit/record.rb +18 -22
  32. data/lib/typekit/record/family.rb +24 -1
  33. data/lib/typekit/record/kit.rb +29 -1
  34. data/lib/typekit/record/library.rb +4 -1
  35. data/lib/typekit/record/variation.rb +13 -1
  36. data/lib/typekit/version.rb +1 -1
  37. data/spec/feature/create_kit_spec.rb +52 -0
  38. data/spec/feature/delete_kit_spec.rb +33 -0
  39. data/spec/feature/index_kits_spec.rb +55 -0
  40. data/spec/feature/publish_kit_spec.rb +15 -0
  41. data/spec/feature/show_family_spec.rb +75 -0
  42. data/spec/feature/show_kit_spec.rb +56 -0
  43. data/spec/feature/show_library_spec.rb +29 -0
  44. data/spec/feature/show_variation_spec.rb +18 -0
  45. data/spec/feature/update_kit_spec.rb +88 -0
  46. data/spec/fixture/cassette/create_kits_bad.yml +16 -0
  47. data/spec/fixture/cassette/create_kits_ok.yml +16 -0
  48. data/spec/fixture/cassette/delete_kits_xxx_not_found.yml +13 -0
  49. data/spec/{cassettes → fixture/cassette}/delete_kits_xxx_ok.yml +0 -3
  50. data/spec/fixture/cassette/index_kits_show_kit_xxx_ok.yml +25 -0
  51. data/spec/{cassettes → fixture/cassette}/index_kits_unauthorized.yml +0 -3
  52. data/spec/{cassettes → fixture/cassette}/show_families_xxx_found.yml +0 -3
  53. data/spec/{cassettes → fixture/cassette}/show_families_xxx_ok.yml +0 -3
  54. data/spec/{cassettes → fixture/cassette}/show_families_xxx_yyy_ok.yml +0 -3
  55. data/spec/fixture/cassette/show_families_yyy_update_kits_xxx_families_ok.yml +35 -0
  56. data/spec/fixture/cassette/show_kits_xxx_families_yyy_show_family_yyy_ok.yml +45 -0
  57. data/spec/fixture/cassette/show_kits_xxx_not_found.yml +13 -0
  58. data/spec/fixture/cassette/show_kits_xxx_show_family_yyy_ok.yml +46 -0
  59. data/spec/{cassettes → fixture/cassette}/show_libraries_xxx_ok.yml +0 -3
  60. data/spec/fixture/cassette/update_kits_xxx_empty_families_ok.yml +16 -0
  61. data/spec/fixture/cassette/update_kits_xxx_families_ok.yml +18 -0
  62. data/spec/fixture/cassette/update_kits_xxx_families_variations_ok.yml +18 -0
  63. data/spec/fixture/cassette/update_kits_xxx_name_ok.yml +17 -0
  64. data/spec/fixture/cassette/update_kits_xxx_publish_ok.yml +16 -0
  65. data/spec/fixture/record/article.rb +11 -0
  66. data/spec/fixture/record/section.rb +10 -0
  67. data/spec/lib/typekit/collection_spec.rb +22 -0
  68. data/spec/{typekit/processing → lib/typekit}/converter_spec.rb +13 -13
  69. data/spec/lib/typekit/element/association_spec.rb +96 -0
  70. data/spec/lib/typekit/element/base_spec.rb +70 -0
  71. data/spec/lib/typekit/element/persistence_spec.rb +97 -0
  72. data/spec/lib/typekit/element/serialization_spec.rb +28 -0
  73. data/spec/lib/typekit/element_spec.rb +58 -0
  74. data/spec/{typekit → lib/typekit}/helper_spec.rb +6 -8
  75. data/spec/lib/typekit/record_spec.rb +57 -0
  76. data/spec/spec_helper.rb +10 -3
  77. data/spec/support/common_helper.rb +5 -0
  78. data/spec/support/record_helper.rb +38 -0
  79. data/typekit-client.gemspec +11 -4
  80. metadata +164 -58
  81. data/lib/typekit/processing.rb +0 -8
  82. data/lib/typekit/processing/converter.rb +0 -28
  83. data/lib/typekit/processing/converter/boolean.rb +0 -14
  84. data/lib/typekit/processing/converter/collection.rb +0 -18
  85. data/lib/typekit/processing/converter/datetime.rb +0 -14
  86. data/lib/typekit/processing/converter/errors.rb +0 -24
  87. data/lib/typekit/processing/converter/record.rb +0 -16
  88. data/lib/typekit/processing/converter/unknown.rb +0 -15
  89. data/lib/typekit/processing/translator.rb +0 -13
  90. data/lib/typekit/record/base.rb +0 -52
  91. data/spec/cassettes/index_kits_ok.yml +0 -16
  92. data/spec/cassettes/show_kits_xxx_families_yyy_ok.yml +0 -16
  93. data/spec/cassettes/show_kits_xxx_ok.yml +0 -17
  94. data/spec/features/client/delete_kit_spec.rb +0 -13
  95. data/spec/features/client/index_kits_spec.rb +0 -25
  96. data/spec/features/client/show_family_spec.rb +0 -47
  97. data/spec/features/client/show_kit_spec.rb +0 -18
  98. data/spec/features/client/show_library_spec.rb +0 -18
  99. data/spec/features/client/show_variation_spec.rb +0 -22
  100. data/spec/support/resource_helper.rb +0 -34
  101. data/spec/typekit/record/base_spec.rb +0 -85
  102. data/spec/typekit/record_spec.rb +0 -80
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2d0603ce4ff30ecb04ccf846ba94cf71b0e8d54
4
- data.tar.gz: a85ce05a15a5aa3b0cea5b1e0122ccd0b8db6eb8
3
+ metadata.gz: 4e6cca3a1c8d723d09a5e4e08c7c2f6826a7d820
4
+ data.tar.gz: be86c255f7b3e9009e51c2e90a14174763d93827
5
5
  SHA512:
6
- metadata.gz: a661e632bae645066c291a078fdd60ce727d137e3bd5edf4778dbe5dad1554f18e1f88d99c4dbbea0bc92e09d042c7486c64c30fa77e3984ac3b0145e40d6f38
7
- data.tar.gz: 60bfc3980c3128be77545fb6be4e8d88edd436b773f30a09cc930868f666b001ea1227e2c6e5bcbb17e7790273fa48f0df0e3c644b8426b8f140ca469e890404
6
+ metadata.gz: 5fcecc1eb0c187932be93338cae4a888e5eb099ec4963fa4a7df99bcd7c1dad8dcde686d3a8bd25f4809f1cc4716784b1b982642c09e6d30e5cc2a801b2a9335
7
+ data.tar.gz: 6216034d76d6480dc17b5d1849e9a2f0ae28f035a33e5fac2e4e1b657189a03e793b179587c64c1b2883e0925527f41273dbd58a00d0d984baebc4b937cfbc43
data/.gitignore CHANGED
@@ -1,5 +1,7 @@
1
- *.swp
2
1
  .DS_Store
3
- Gemfile.lock
4
- *.gem
2
+ *.swp
5
3
  *.swo
4
+ *.gem
5
+ Gemfile.lock
6
+ doc
7
+ .yardoc
@@ -1,6 +1,10 @@
1
1
  language: ruby
2
+
2
3
  rvm:
4
+ - 1.9.3
5
+ - 2.0.0
3
6
  - 2.1.0
7
+
4
8
  branches:
5
9
  only:
6
10
  - master
@@ -0,0 +1,6 @@
1
+ --markup-provider=redcarpet
2
+ --markup=markdown
3
+ lib/**/*.rb
4
+ -
5
+ CHANGELOG.md
6
+ LICENSE.txt
@@ -1,19 +1,31 @@
1
+ ## Typekit Client 0.0.6 (July 29, 2014)
2
+
3
+ * Implementation of an Active-Record-like architecture: each Typekit resource
4
+ (kits, families, libraries, and variations) is ascribed a Ruby class that
5
+ provides various methods for manipulating the corresponding data (`Kit.all`,
6
+ `Kit.find`, `kit.save`, `kit.delete`, etc.).
7
+ * Support for Ruby >= 1.9.3 instead of Ruby >= 2.1.
8
+
1
9
  ## Typekit Client 0.0.5 (June 10, 2014)
10
+
2
11
  * New name for the general CLI: `typekit-client` instead of `typekit`.
3
12
  * New CLI for the sole purpose of publishing kits: `typekit-publisher`.
4
13
  * Relations between resources (a kit has families, a family has variations,
5
14
  a variation belongs to a family, etc.).
6
15
 
7
16
  ## Typekit Client 0.0.4 (June 1, 2014)
17
+
8
18
  * Extraction of the RESTful API logic into a separate gem called
9
19
  [Apitizer](https://github.com/IvanUkhov/apitizer).
10
20
  * Elimination of the `--version` and `--format` options of the CLI.
11
21
 
12
22
  ## Typekit Client 0.0.3 (May 31, 2014)
23
+
13
24
  * Object-restful mapping (families, kits, etc. got proper classes).
14
25
  * Command history and tab completion in the CLI.
15
26
 
16
27
  ## Typekit Client 0.0.2 (May 28, 2014)
28
+
17
29
  * New name for the gem (still `require 'typekit'`).
18
30
  * Basic DSL for describing RESTful resources.
19
31
  * Client-side verification of user requests.
data/Guardfile CHANGED
@@ -1,8 +1,8 @@
1
- guard :rspec do
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^spec/.+_helper\.rb$}) { 'spec' }
4
4
  watch(%r{^lib/(.+)\.rb$}) do |match|
5
- result = "spec/#{ match[1] }_spec.rb"
5
+ result = "spec/lib/#{match[1]}_spec.rb"
6
6
  begin
7
7
  break if File.exist?(result)
8
8
  result = File.dirname(result)
@@ -10,7 +10,7 @@ guard :rspec do
10
10
  result
11
11
  end
12
12
  watch(%r{^lib/[^/]+/(.+)\.rb$}) do |match|
13
- result = "spec/features/#{ match[1] }"
13
+ result = "spec/features/#{match[1]}"
14
14
  begin
15
15
  break if File.exist?(result)
16
16
  result = File.dirname(result)
@@ -18,4 +18,22 @@ guard :rspec do
18
18
  result
19
19
  end
20
20
  end
21
+
22
+ require 'guard/plugin'
23
+
24
+ module ::Guard
25
+ class Whatever < ::Guard::Plugin
26
+ def run_all; end
27
+ def run_on_changes(*); end
28
+ end
29
+ end
30
+
31
+ guard :whatever do
32
+ watch(%r{^lib/.*\.rb$})
33
+ watch(%r{^.*\.md$})
34
+
35
+ callback(:run_all_end) { system 'yardoc' }
36
+ callback(:run_on_changes_end) { system 'yardoc' }
37
+ end
38
+
21
39
  # vim: ft=ruby
data/README.md CHANGED
@@ -1,300 +1,303 @@
1
- # Typekit Client [![Gem Version](https://badge.fury.io/rb/typekit-client.svg)](http://badge.fury.io/rb/typekit-client) [![Build Status](https://travis-ci.org/IvanUkhov/typekit-client.svg?branch=master)](https://travis-ci.org/IvanUkhov/typekit-client)
1
+ # Typekit Client [![Gem Version](https://badge.fury.io/rb/typekit-client.svg)](http://badge.fury.io/rb/typekit-client) [![Dependency Status](https://gemnasium.com/IvanUkhov/typekit-client.svg)](https://gemnasium.com/IvanUkhov/typekit-client) [![Build Status](https://travis-ci.org/IvanUkhov/typekit-client.svg?branch=master)](https://travis-ci.org/IvanUkhov/typekit-client)
2
+
2
3
  A Ruby library for accessing the [Typekit API](https://typekit.com/docs/api).
3
4
 
4
5
  ## Installation
5
- The minimal supported version of Ruby is `2.1`. The simplest way to install
6
- Ruby is via [rvm](https://rvm.io/):
7
- ```bash
8
- $ curl -sSL https://get.rvm.io | bash -s stable --ruby=2.1
9
- ```
10
6
 
11
- Now you can install the library itself:
12
- ```bash
13
- $ gem install typekit-client
14
- ```
7
+ In your `Gemfile`:
15
8
 
16
- If you are planning to use the gem as a part of your project, add the
17
- following line into your `Gemfile`:
18
9
  ```ruby
19
10
  gem 'typekit-client', require: 'typekit'
20
11
  ```
21
12
 
22
- Then execute:
13
+ In your terminal:
14
+
23
15
  ```bash
24
16
  $ bundle
25
17
  ```
26
18
 
27
- In order to interact with the Typekit API, one should have a valid API token.
28
- You can generate such a token [here](https://typekit.com/account/tokens).
29
- For convenience, let us create a shortcut for it:
30
- ```bash
31
- $ export tk_token=YOUR_TOKEN_GOES_HERE
32
- ```
19
+ ## TL;DR
20
+
21
+ Here are some typical use cases of the gem:
33
22
 
34
- ## Usage
35
- Here is the basic setup in a Ruby script:
36
23
  ```ruby
37
24
  require 'typekit'
38
25
 
39
26
  client = Typekit::Client.new(token: ENV['tk_token'])
27
+
28
+ # List all kits
29
+ kits = client::Kit.all
30
+
31
+ # Find a kit by id
32
+ kit = client::Kit.find('bas4cfe')
33
+
34
+ # Create a kit
35
+ kit = client::Kit.create(name: 'Megakit', domains: ['localhost'],
36
+ families: [{ id: 'vcsm', subset: 'all', variations: ['n4'] }])
37
+
38
+ # Update a kit
39
+ kit.update(name: 'Ultrakit', families: [{ id: 'vybr' }])
40
+
41
+ # Publish a kit
42
+ kit.publish
43
+
44
+ # Delete a kit
45
+ kit.delete
46
+
47
+ # Find a font family by id
48
+ family = client::Family.find('vybr')
49
+
50
+ # Find a font family by slug
51
+ family = client::Family.find('calluna')
52
+
53
+ # List all font libraries
54
+ libraries = client::Library.all
55
+
56
+ # Find a library by id and retrieve its first ten font families
57
+ library = client::Library.find('trial', page: 1, per_page: 10)
40
58
  ```
41
59
 
42
- `client` has five methods: `index`, `show`, `create`, `update`, and `delete`.
43
- The signature of each method is `action(*path, parameters = {})`. The
44
- arguments are as follows:
45
- * `*path` refers to an arbitrary number of arguments needed to identify
46
- the endpoint of interest (a plenty of examples are given below);
47
- * `parameters` is a hash of parameters (optional).
60
+ ## Preliminaries
48
61
 
49
- Before sending the actual request to the Typekit API, the library checks
50
- whether the endpoint given by `*path` exists and, if it does, whether
51
- the desired action (`index`, `show`, _etc._) is permitted. So, if you
52
- receive an exception, check the [API reference](https://typekit.com/docs/api/).
62
+ The Typekit API provides four major resources: kits, font families, font
63
+ variations, and font libraries. The operations concerning kits require
64
+ authentication. To this end, one has to have a valid API token. Such a token
65
+ can be generated on [Your API Tokens](https://typekit.com/account/tokens) on
66
+ Typekit. For convenience, the examples on this page assume that a valid API
67
+ token is stored in an environment variable called `tk_token`.
68
+
69
+ The four resources are mapped to the following Ruby classes, respectively:
70
+
71
+ * `Typekit::Record::Kit`,
72
+ * `Typekit::Record::Family`,
73
+ * `Typekit::Record::Variation`, and
74
+ * `Typekit::Record::Library`.
75
+
76
+ Each resource has its own set of permitted operations. The entire routing map
77
+ is as follows:
53
78
 
54
- Now, let us have a look at some typical use cases. For clarity, the code
55
- below makes use of the following auxiliary function:
56
79
  ```ruby
57
- def p(data)
58
- puts JSON.pretty_generate(data)
59
- rescue JSON::GeneratorError
60
- puts data.inspect
80
+ resources :kits do
81
+ resources :families, only: [:show, :update, :delete]
82
+ show :published, on: :member
83
+ update :publish, on: :member
61
84
  end
85
+
86
+ resources :families, only: :show do
87
+ show ':variation', on: :member
88
+ end
89
+
90
+ resources :libraries, only: [:index, :show]
62
91
  ```
63
92
 
64
- ### List all kits
65
- Code:
93
+ Here, the DSL of [Apitizer](https://github.com/IvanUkhov/apitizer) is utilized,
94
+ which is similar to the one of
95
+ [Rails](http://guides.rubyonrails.org/routing.html).
96
+
97
+ Refer to the [official documentation](https://typekit.com/docs/api) of the
98
+ Typekit API to get a complete description of each endpoint.
99
+
100
+ ## High-Level Programming Interface
101
+
102
+ The preferable way to work with the four Ruby classes given earlier is via
103
+ an instance of `Typekit::Client` as a module:
104
+
105
+ * `client::Kit`,
106
+ * `client::Family`,
107
+ * `client::Variation`, and
108
+ * `client::Library`.
109
+
110
+ The kits that are available under your account can be listed as follows:
111
+
66
112
  ```ruby
67
- p kits = client.index(:kits)
68
- p kits.map(&:class)
69
- p kits.first.attributes
70
- p kits.first.link
113
+ kits = client::Kit.all
71
114
  ```
72
115
 
73
- Output:
74
- ```json
75
- [
76
- {
77
- "id": "bas4cfe",
78
- "link": "/api/v1/json/kits/bas4cfe"
79
- },
80
- {
81
- "id": "sfh6bkj",
82
- "link": "/api/v1/json/kits/sfh6bkj"
83
- },
84
- {
85
- "id": "kof8zcn",
86
- "link": "/api/v1/json/kits/kof8zcn"
87
- }
88
- ]
89
- [
90
- "Typekit::Record::Kit",
91
- "Typekit::Record::Kit",
92
- "Typekit::Record::Kit"
93
- ]
94
- {
95
- "id": "bas4cfe",
96
- "link": "/api/v1/json/kits/bas4cfe"
97
- }
98
- "/api/v1/json/kits/bas4cfe"
99
- ```
116
+ Each kit is an instance of `Typekit::Record::Kit`, and it contains all
117
+ attributes that the Typekit API returns in response to the corresponding
118
+ API call. In the case of `all`, the Typekit API provides only two attribute,
119
+ namely, `id` and `link`; such kits will be referred to as incomplete.
120
+ Here is an example:
100
121
 
101
- ### Show the description of a variation of a font family
102
- Code:
103
122
  ```ruby
104
- p client.show(:families, 'vcsm', 'i9')
105
- ```
123
+ kit.complete?
124
+ # => false
106
125
 
107
- Output:
108
- ```json
109
- {
110
- "id": "vcsm:i9",
111
- "name": "Proxima Nova Black Italic",
112
- "family": {
113
- "id": "vcsm",
114
- "link": "/api/v1/json/families/vcsm",
115
- "name": "Proxima Nova"
116
- },
117
- "font_style": "italic",
118
- "font_variant": "normal",
119
- "font_weight": "900",
120
- ...
121
- }
126
+ kit.attributes
127
+ # =>
128
+ # {
129
+ # "id": "bas4cfe",
130
+ # "link": "/api/v1/json/kits/bas4cfe"
131
+ # }
132
+
133
+ kit.id
134
+ # => "bas4cfe"
135
+
136
+ kit.link
137
+ # => "/api/v1/json/kits/bas4cfe"
122
138
  ```
123
139
 
124
- ### Show the font families in the trial library with pagination
125
- Code:
140
+ A particular kit can be fetched using its `id`:
141
+
126
142
  ```ruby
127
- p client.show(:libraries, 'trial', page: 10, per_page: 5)
143
+ kit = client::Kit.find('bas4cfe') # or find! to raise an exception if failed
128
144
  ```
129
145
 
130
- Output:
131
- ```json
132
- {
133
- "id": "trial",
134
- "link": "/api/v1/json/libraries/trial",
135
- "name": "Trial Library",
136
- "families": [
137
- {
138
- "id": "qnhl",
139
- "link": "/api/v1/json/families/qnhl",
140
- "name": "Caliban Std"
141
- },
142
- {
143
- "id": "vybr",
144
- "link": "/api/v1/json/families/vybr",
145
- "name": "Calluna"
146
- },
147
- ...
148
- ],
149
- "pagination": {
150
- "count": 261,
151
- "on": "families",
152
- "page": 10,
153
- "page_count": 53,
154
- "per_page": 5
155
- }
156
- }
157
- ```
146
+ In the case of `find`, you get all information about the kit:
158
147
 
159
- ### Create a new kit
160
- Code:
161
148
  ```ruby
162
- p kit = client.create(:kits, name: 'Megakit', domains: 'localhost')
163
- ```
149
+ kit.complete?
150
+ # => true
151
+
152
+ kit.attributes
153
+ # =>
154
+ # {
155
+ # "id": "bas4cfe",
156
+ # "name": "Megakit",
157
+ # "analytics": false,
158
+ # "domains": [
159
+ # "localhost"
160
+ # ],
161
+ # "families": [
162
+ # ...
163
+ # ]
164
+ # }
164
165
 
165
- Output:
166
- ```json
167
- {
168
- "id": "izw0qiq",
169
- "name": "Megakit",
170
- "analytics": false,
171
- "badge": true,
172
- "domains": [
173
- "localhost"
174
- ],
175
- "families": [
176
-
177
- ]
178
- }
166
+ kit.name
167
+ # => "Megakit"
179
168
  ```
180
169
 
181
- ### Disable the badge of a kit
182
- Code:
170
+ In order to reload a kit and/or retrieve missing data, call `load`:
171
+
183
172
  ```ruby
184
- p client.update(:kits, kit.id, badge: false)
185
- ```
173
+ kit.complete?
174
+ # => false
186
175
 
187
- Output:
188
- ```json
189
- {
190
- "id": "izw0qiq",
191
- "name": "Megakit",
192
- "analytics": false,
193
- "badge": false,
194
- "domains": [
195
- "localhost"
196
- ],
197
- "families": [
198
-
199
- ]
200
- }
176
+ kit.load # or load! to raise an exception if failed
177
+
178
+ kit.complete?
179
+ # => true
201
180
  ```
202
181
 
203
- ### Look up the id of a font family by its slug
204
- Code:
182
+ In order to change an attribute of a kit, assign a new value to that
183
+ attribute and call `save`:
184
+
205
185
  ```ruby
206
- p family = client.show(:families, 'proxima-nova')
186
+ kit.name = 'Ultrakit'
187
+ kit.save # or save! to raise an exception if failed
207
188
  ```
208
189
 
209
- Output:
210
- ```json
211
- {
212
- "id": "vcsm",
213
- "link": "/api/v1/json/families/vcsm"
214
- }
215
- ```
190
+ Similarly, the `families` attribute, containing the font families included in
191
+ the kit, can be changed as desired:
216
192
 
217
- ### Add a font family into a kit
218
- Code:
219
193
  ```ruby
220
- p client.update(:kits, kit.id, families: { "0" => { id: family.id } })
221
- ```
194
+ # Push a new instance of Typekit::Record::Family
195
+ kit.families << Typekit::Record::Family.new(id: 'vybr')
196
+
197
+ # Push a hash of attributes
198
+ kit.families << { id: 'vcsm', subset: 'all' }
199
+
200
+ # Replace with an font family found via client
201
+ kit.families = [client::Family.find('droid-sans')]
222
202
 
223
- Output:
224
- ```json
225
- {
226
- "id": "nys8sny",
227
- "name": "Megakit",
228
- "analytics": false,
229
- "badge": false,
230
- "domains": [
231
- "localhost"
232
- ],
233
- "families": [
234
- {
235
- "id": "vcsm",
236
- "name": "Proxima Nova",
237
- "slug": "proxima-nova",
238
- "css_names": [
239
- "proxima-nova-1",
240
- "proxima-nova-2"
241
- ],
242
- ...
243
- }
244
- ]
245
- }
203
+ # Remove all font families
204
+ kit.families = []
205
+
206
+ kit.save
246
207
  ```
247
208
 
248
- ### Publish a kit
249
- Code:
209
+ If you want to browse the font families hosted on Typekit, you can do so via
210
+ libraries. All libraries can be listed as follows:
211
+
250
212
  ```ruby
251
- p client.update(:kits, kit.id, :publish)
213
+ libraries = client::Library.all
252
214
  ```
253
215
 
254
- Output:
255
- ```
256
- #<DateTime: 2014-05-31T06:45:29+00:00 ((2456809j,24329s,0n),+0s,2299161j)>
257
- ```
216
+ A particular library can be fetched using:
258
217
 
259
- ### Show the description of a published kit
260
- Code:
261
218
  ```ruby
262
- p client.show(:kits, kit.id, :published)
219
+ library = client::Library.find('trial')
263
220
  ```
264
221
 
265
- Output:
266
- ```json
267
- {
268
- "id": "vzt4lrg",
269
- "name": "Megakit",
270
- "analytics": false,
271
- "badge": false,
272
- "domains": [
273
- "localhost"
274
- ],
275
- "families": [
276
- ...
277
- ],
278
- "published": "2014-05-31T06:45:29Z"
279
- }
280
- ```
222
+ In this case, along with some general information about the library itself, the
223
+ Typekit API will return a subset of the font families included in the library
224
+ according to its default pagination. The desired pagination can be specified as
225
+ follows:
281
226
 
282
- ### Delete a kit
283
- Command:
284
227
  ```ruby
285
- p client.delete(:kits, kit.id)
228
+ library = client::Library.find('trial', page: 1, per_page: 10)
286
229
  ```
287
230
 
288
- Output:
289
- ```
290
- true
231
+ The font families are stored in the `families` attribute of the library.
232
+
233
+ ## Low-Level Programming Interface
234
+
235
+ An instance of `Typekit::Client` has a method called `process` that can be
236
+ used to perform arbitrary API calls. The signature of the method is
237
+ `process(action, *enpoint, parameters = {})`, and the arguments are as follows:
238
+
239
+ * `action` is one of `:index`, `:show`, `:create`, `:update`, and `:delete`;
240
+ * `*endpoint` refers to an arbitrary number of arguments needed to identify
241
+ the endpoint of interest;
242
+ * `parameters` is a optional hash of parameters.
243
+
244
+ Each of the five actions has a shortcut: instead of calling
245
+ `client.process(action, *endpoint, parameters)`, you can just call
246
+ `client.action(*endpoint, parameters)` replacing `action` with `index`, `show`,
247
+ `create`, `update`, or `delete`.
248
+
249
+ Here are some examples:
250
+
251
+ ```ruby
252
+ require 'typekit'
253
+
254
+ client = Typekit::Client.new(token: ENV['tk_token'])
255
+
256
+ # List all kits
257
+ kits = client.index(:kits)
258
+
259
+ # Find a kit by id
260
+ kit = client.show(:kits, 'bas4cfe')
261
+
262
+ # Create a kit
263
+ kit = client.create(:kits, name: 'Megakit', domains: ['localhost'],
264
+ families: [{ id: 'vcsm', subset: 'all', variations: ['n4'] }])
265
+
266
+ # Update a kit
267
+ client.update(:kits, 'bas4cfe', name: 'Ultrakit', families: [{ id: 'vybr' }])
268
+
269
+ # Publish a kit
270
+ client.update(:kits, 'bas4cfe', :publish)
271
+
272
+ # Delete a kit
273
+ client.delete(:kits, 'bas4cfe')
274
+
275
+ # Find a font family by id
276
+ family = client.show(:families, 'vybr')
277
+
278
+ # Find a font family by slug
279
+ family = client.show(:families, 'calluna')
280
+
281
+ # Show a font family in a kit by id
282
+ family = client.show(:kits, 'bas4cfe', :families, 'vcsm')
283
+
284
+ # Show a variation of a font family by id
285
+ variation = client.show(:families, 'vybr', 'i4')
286
+
287
+ # List all font libraries
288
+ libraries = client.index(:libraries)
289
+
290
+ # Find a library by id and retrieve its first ten font families
291
+ library = client.show(:libraries, 'trial', page: 1, per_page: 10)
291
292
  ```
292
293
 
293
- ## General Command-line Interface
294
- There is a simple tool provided in order to demonstrate the usage of the
295
- library and to give the ability to perform basic operations without writing
296
- any code. The tool is called `typekit-client`, and it should get installed
297
- along with the gem. Try running:
294
+ ## Low-Level Command-Line Interface
295
+
296
+ There is a command-line tool provided in order to interact with the Typekit
297
+ API without writing any code. The tool is called `typekit-client`, and
298
+ its capabilities directly reflect the low-level programming interface describe
299
+ earlier:
300
+
298
301
  ```
299
302
  $ typekit-client -h
300
303
  Usage: typekit-client [options] [command]
@@ -306,14 +309,9 @@ Other options:
306
309
  -h, --help Show this message
307
310
  ```
308
311
 
309
- Alternatively, you can install `typekit-client` in the `bin` directory of
310
- your project using the following command:
311
- ```bash
312
- $ bundle binstubs typekit-client
313
- ```
314
-
315
312
  The tool has two modes: normal and interactive. If `command` is provided,
316
313
  the tool executes only that particular command and terminates:
314
+
317
315
  ```
318
316
  $ typekit-client -t $tk_token index kits
319
317
  [
@@ -328,6 +326,7 @@ $
328
326
 
329
327
  If `command` is not provided, the tool gives a command prompt wherein one
330
328
  can enter multiple commands:
329
+
331
330
  ```
332
331
  $ typekit-client -t $tk_token
333
332
  Type 'help' for help and 'exit' to exit.
@@ -335,17 +334,18 @@ Type 'help' for help and 'exit' to exit.
335
334
  Usage: <action> <resource> [parameters]
336
335
 
337
336
  <action> index, show, create, update, or delete
338
- <resource> a list separated by whitespaces
337
+ <endpoint> a list separated by whitespaces
339
338
  [parameters] a JSON-encoded hash (optional)
340
339
 
341
340
  Examples:
342
341
  index kits
343
- show kits bas4cfe families vcsm
344
- show families vcsm i9
345
- show libraries trial { "page": 10, "per_page": 5 }
346
- create kits { "name": "Megakit", "domains": "localhost" }
347
- update kits bas4cfe { "name": "Ultrakit" }
342
+ create kits { "name": "Megakit", domains: ["localhost"] }
343
+ show kits bas4cfe
344
+ update kits bas4cfe { families: [{ "id": "vybr" }] }
345
+ update kits bas4cfe publish
348
346
  delete kits bas4cfe
347
+ show families vybr i4
348
+ show libraries trial { "page": 10, "per_page": 5 }
349
349
  > index kits
350
350
  [
351
351
  {
@@ -359,7 +359,8 @@ Bye.
359
359
  $
360
360
  ```
361
361
 
362
- ## Publishing Command-line Interface
362
+ ## Publishing Command-Line Interface
363
+
363
364
  There is another utility with the sole purpose of publishing kits. The tool
364
365
  is called `typekit-publisher`:
365
366
 
@@ -389,11 +390,15 @@ Publishing bas4cfe... Done.
389
390
  Publishing sfh6bkj... Done.
390
391
  Publishing kof8zcn... Done.
391
392
  Bye.
393
+ $
392
394
  ```
393
395
 
394
396
  ## Contributing
395
- 1. Fork it ( https://github.com/IvanUkhov/typekit-client/fork )
396
- 2. Create your feature branch (`git checkout -b my-new-feature`)
397
- 3. Commit your changes (`git commit -am 'Add some feature'`)
398
- 4. Push to the branch (`git push origin my-new-feature`)
399
- 5. Create a new Pull Request
397
+
398
+ 1. [Fork](https://help.github.com/articles/fork-a-repo) the project.
399
+ 2. Create a branch for your feature (`git checkout -b awesome-feature`).
400
+ 3. Implement your feature (`vim`).
401
+ 4. Commit your changes (`git commit -am 'Implemented an awesome feature'`).
402
+ 5. Push to the branch (`git push origin awesome-feature`).
403
+ 6. [Create](https://help.github.com/articles/creating-a-pull-request)
404
+ a new Pull Request.