ghost-ruby 1.0.0

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 (36) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ghost/admin_api.rb +35 -0
  3. data/lib/ghost/authentication/content_key.rb +15 -0
  4. data/lib/ghost/authentication/jwt_token.rb +46 -0
  5. data/lib/ghost/client.rb +104 -0
  6. data/lib/ghost/config.rb +49 -0
  7. data/lib/ghost/content_api.rb +29 -0
  8. data/lib/ghost/errors.rb +47 -0
  9. data/lib/ghost/resources/admin/files.rb +11 -0
  10. data/lib/ghost/resources/admin/images.rb +11 -0
  11. data/lib/ghost/resources/admin/media.rb +15 -0
  12. data/lib/ghost/resources/admin/members.rb +11 -0
  13. data/lib/ghost/resources/admin/newsletters.rb +11 -0
  14. data/lib/ghost/resources/admin/offers.rb +11 -0
  15. data/lib/ghost/resources/admin/pages.rb +11 -0
  16. data/lib/ghost/resources/admin/posts.rb +11 -0
  17. data/lib/ghost/resources/admin/site.rb +15 -0
  18. data/lib/ghost/resources/admin/tags.rb +11 -0
  19. data/lib/ghost/resources/admin/themes.rb +11 -0
  20. data/lib/ghost/resources/admin/tiers.rb +11 -0
  21. data/lib/ghost/resources/admin/users.rb +11 -0
  22. data/lib/ghost/resources/admin/webhooks.rb +11 -0
  23. data/lib/ghost/resources/base.rb +106 -0
  24. data/lib/ghost/resources/content/authors.rb +11 -0
  25. data/lib/ghost/resources/content/newsletters.rb +11 -0
  26. data/lib/ghost/resources/content/offers.rb +11 -0
  27. data/lib/ghost/resources/content/pages.rb +11 -0
  28. data/lib/ghost/resources/content/posts.rb +11 -0
  29. data/lib/ghost/resources/content/settings.rb +15 -0
  30. data/lib/ghost/resources/content/tags.rb +11 -0
  31. data/lib/ghost/resources/content/tiers.rb +11 -0
  32. data/lib/ghost/response.rb +43 -0
  33. data/lib/ghost/version.rb +5 -0
  34. data/lib/ghost-ruby.rb +3 -0
  35. data/lib/ghost.rb +41 -0
  36. metadata +115 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 495fa5a9501b26adf92d1cf3d991efa0a2cc858decb7252bc9ae2770d2755f33
4
+ data.tar.gz: fa4bad46264a87413b5ed656419980e8f71e542313777ec61221f6dd802c6731
5
+ SHA512:
6
+ metadata.gz: d996d642d2f74ae4250d74f4f7e998743b86487a3f3c9e5b62019f06f7e334103fb8ef9a52bfcb4070e3c22e763e07aa4526356d686d9c5020b3b29ce69050d4
7
+ data.tar.gz: c6bf693d41f9cdd10fed9eb400fbd7d2ec6a706e0196e0e23a996b73ebb7d0b9c448505f7869edb32413111ac0f4a8395bd49bf3f810e873d9859b35c8450a1f
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ class AdminAPI
5
+ RESOURCES = {
6
+ posts: Resources::Admin::Posts,
7
+ pages: Resources::Admin::Pages,
8
+ tags: Resources::Admin::Tags,
9
+ members: Resources::Admin::Members,
10
+ users: Resources::Admin::Users,
11
+ newsletters: Resources::Admin::Newsletters,
12
+ tiers: Resources::Admin::Tiers,
13
+ offers: Resources::Admin::Offers,
14
+ webhooks: Resources::Admin::Webhooks,
15
+ site: Resources::Admin::Site,
16
+ images: Resources::Admin::Images,
17
+ media: Resources::Admin::Media,
18
+ files: Resources::Admin::Files,
19
+ themes: Resources::Admin::Themes
20
+ }.freeze
21
+
22
+ def initialize(url:, key:, version: "v5.0")
23
+ @config = Config.new(url: url, version: version, api_type: "admin", key: key)
24
+ authenticator = Authentication::JwtToken.new(key)
25
+ @client = Client.new(config: @config, authenticator: authenticator)
26
+ @resources = {}
27
+ end
28
+
29
+ RESOURCES.each do |name, klass|
30
+ define_method(name) do
31
+ @resources[name] ||= klass.new(client: @client, config: @config)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Authentication
5
+ class ContentKey
6
+ def initialize(key)
7
+ @key = key
8
+ end
9
+
10
+ def apply(request)
11
+ request.params["key"] = @key
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jwt"
4
+
5
+ module Ghost
6
+ module Authentication
7
+ class JwtToken
8
+ TOKEN_EXPIRY = 300 # 5 minutes
9
+ REFRESH_BUFFER = 60 # refresh 1 minute before expiry
10
+
11
+ def initialize(key)
12
+ parts = key.to_s.split(":")
13
+ raise Ghost::Error, "Admin API key must be in format {id}:{secret}" unless parts.length == 2
14
+
15
+ @id = parts[0]
16
+ @secret = [parts[1]].pack("H*")
17
+ @token = nil
18
+ @expires_at = nil
19
+ end
20
+
21
+ def apply(request)
22
+ request.headers["Authorization"] = "Ghost #{token}"
23
+ end
24
+
25
+ private
26
+
27
+ def token
28
+ if @token.nil? || Time.now.to_i >= (@expires_at - REFRESH_BUFFER)
29
+ generate_token
30
+ end
31
+ @token
32
+ end
33
+
34
+ def generate_token
35
+ now = Time.now.to_i
36
+ payload = {
37
+ iat: now,
38
+ exp: now + TOKEN_EXPIRY,
39
+ aud: "/admin/"
40
+ }
41
+ @expires_at = now + TOKEN_EXPIRY
42
+ @token = JWT.encode(payload, @secret, "HS256", { kid: @id })
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/multipart"
5
+ require "json"
6
+
7
+ module Ghost
8
+ class Client
9
+ def initialize(config:, authenticator:)
10
+ @config = config
11
+ @authenticator = authenticator
12
+ @connection = build_connection
13
+ end
14
+
15
+ def get(url, params = {})
16
+ request(:get, url, params)
17
+ end
18
+
19
+ def post(url, body = {})
20
+ request(:post, url, body)
21
+ end
22
+
23
+ def put(url, body = {})
24
+ request(:put, url, body)
25
+ end
26
+
27
+ def delete(url)
28
+ request(:delete, url)
29
+ end
30
+
31
+ def upload(url, file_path, ref: nil)
32
+ mime = detect_mime(file_path)
33
+ payload = {
34
+ file: Faraday::Multipart::FilePart.new(file_path, mime)
35
+ }
36
+ payload[:ref] = ref if ref
37
+
38
+ response = @connection.post(url) do |req|
39
+ @authenticator.apply(req)
40
+ req.headers["Accept-Version"] = @config.version
41
+ req.body = payload
42
+ end
43
+
44
+ handle_response(response)
45
+ end
46
+
47
+ private
48
+
49
+ def build_connection
50
+ Faraday.new do |f|
51
+ f.request :multipart
52
+ f.request :url_encoded
53
+ f.adapter Faraday.default_adapter
54
+ end
55
+ end
56
+
57
+ def request(method, url, params_or_body = nil)
58
+ response = @connection.send(method, url) do |req|
59
+ @authenticator.apply(req)
60
+ req.headers["Accept-Version"] = @config.version
61
+ req.headers["Content-Type"] = "application/json" if %i[post put].include?(method)
62
+
63
+ case method
64
+ when :get
65
+ req.params.merge!(params_or_body) if params_or_body&.any?
66
+ when :post, :put
67
+ req.body = JSON.generate(params_or_body) if params_or_body
68
+ end
69
+ end
70
+
71
+ handle_response(response)
72
+ end
73
+
74
+ def handle_response(response)
75
+ body = response.body.is_a?(String) && !response.body.empty? ? JSON.parse(response.body) : {}
76
+
77
+ unless response.success?
78
+ raise Ghost::Error.from_response(response.status, body)
79
+ end
80
+
81
+ body
82
+ end
83
+
84
+ def detect_mime(file_path)
85
+ ext = File.extname(file_path).downcase
86
+ {
87
+ ".png" => "image/png",
88
+ ".jpg" => "image/jpeg",
89
+ ".jpeg" => "image/jpeg",
90
+ ".gif" => "image/gif",
91
+ ".svg" => "image/svg+xml",
92
+ ".webp" => "image/webp",
93
+ ".mp4" => "video/mp4",
94
+ ".webm" => "video/webm",
95
+ ".ogv" => "video/ogg",
96
+ ".mp3" => "audio/mpeg",
97
+ ".zip" => "application/zip",
98
+ ".pdf" => "application/pdf",
99
+ ".json" => "application/json",
100
+ ".css" => "text/css"
101
+ }.fetch(ext, "application/octet-stream")
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ class Config
5
+ attr_reader :url, :version, :api_type
6
+
7
+ def initialize(url:, version:, api_type:, key:)
8
+ @url = url.to_s.chomp("/")
9
+ @version = version
10
+ @api_type = api_type
11
+ @key = key
12
+
13
+ validate!
14
+ end
15
+
16
+ def base_url
17
+ "#{@url}/ghost/api/#{@api_type}"
18
+ end
19
+
20
+ def resource_url(resource)
21
+ "#{base_url}/#{resource}/"
22
+ end
23
+
24
+ def resource_id_url(resource, id)
25
+ "#{base_url}/#{resource}/#{id}/"
26
+ end
27
+
28
+ def resource_slug_url(resource, slug)
29
+ "#{base_url}/#{resource}/slug/#{slug}/"
30
+ end
31
+
32
+ def resource_email_url(resource, email)
33
+ "#{base_url}/#{resource}/email/#{email}/"
34
+ end
35
+
36
+ private
37
+
38
+ def validate!
39
+ raise Ghost::Error, "URL is required" if @url.nil? || @url.empty?
40
+ raise Ghost::Error, "Version is required" if @version.nil? || @version.empty?
41
+ raise Ghost::Error, "API key is required" if @key.nil? || @key.empty?
42
+
43
+ uri = URI.parse(@url)
44
+ raise Ghost::Error, "URL must include a protocol (https://)" unless uri.is_a?(URI::HTTP)
45
+ rescue URI::InvalidURIError
46
+ raise Ghost::Error, "Invalid URL: #{@url}"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ class ContentAPI
5
+ RESOURCES = {
6
+ posts: Resources::Content::Posts,
7
+ pages: Resources::Content::Pages,
8
+ authors: Resources::Content::Authors,
9
+ tags: Resources::Content::Tags,
10
+ settings: Resources::Content::Settings,
11
+ tiers: Resources::Content::Tiers,
12
+ newsletters: Resources::Content::Newsletters,
13
+ offers: Resources::Content::Offers
14
+ }.freeze
15
+
16
+ def initialize(url:, key:, version: "v5.0")
17
+ @config = Config.new(url: url, version: version, api_type: "content", key: key)
18
+ authenticator = Authentication::ContentKey.new(key)
19
+ @client = Client.new(config: @config, authenticator: authenticator)
20
+ @resources = {}
21
+ end
22
+
23
+ RESOURCES.each do |name, klass|
24
+ define_method(name) do
25
+ @resources[name] ||= klass.new(client: @client, config: @config)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ class Error < StandardError
5
+ attr_reader :error_type, :context, :status_code
6
+
7
+ def initialize(message = nil, error_type: nil, context: nil, status_code: nil)
8
+ @error_type = error_type
9
+ @context = context
10
+ @status_code = status_code
11
+ super(message)
12
+ end
13
+
14
+ def self.from_response(status, body)
15
+ error_class = ERROR_MAP[status] || Error
16
+ errors = body.is_a?(Hash) && body["errors"] ? body["errors"] : []
17
+
18
+ if errors.any?
19
+ err = errors.first
20
+ error_class.new(
21
+ err["message"],
22
+ error_type: err["type"],
23
+ context: err["context"],
24
+ status_code: status
25
+ )
26
+ else
27
+ error_class.new("Unknown error", status_code: status)
28
+ end
29
+ end
30
+ end
31
+
32
+ class BadRequestError < Error; end
33
+ class AuthenticationError < Error; end
34
+ class ForbiddenError < Error; end
35
+ class NotFoundError < Error; end
36
+ class UnprocessableError < Error; end
37
+ class ServerError < Error; end
38
+
39
+ ERROR_MAP = {
40
+ 400 => BadRequestError,
41
+ 401 => AuthenticationError,
42
+ 403 => ForbiddenError,
43
+ 404 => NotFoundError,
44
+ 422 => UnprocessableError,
45
+ 500 => ServerError
46
+ }.freeze
47
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Files < Base
7
+ actions :upload
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Images < Base
7
+ actions :upload
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Media < Base
7
+ actions :upload
8
+
9
+ def resource_name
10
+ "media"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Members < Base
7
+ actions :browse, :read, :add, :edit, :delete
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Newsletters < Base
7
+ actions :browse, :read, :add, :edit
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Offers < Base
7
+ actions :browse, :read, :add, :edit
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Pages < Base
7
+ actions :browse, :read, :add, :edit, :delete
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Posts < Base
7
+ actions :browse, :read, :add, :edit, :delete
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Site < Base
7
+ actions :read
8
+
9
+ def resource_name
10
+ "site"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Tags < Base
7
+ actions :browse, :read, :add, :edit, :delete
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Themes < Base
7
+ actions :upload
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Tiers < Base
7
+ actions :browse, :read, :add, :edit
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Users < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Admin
6
+ class Webhooks < Base
7
+ actions :add, :edit, :delete
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ class Base
6
+ class << self
7
+ def actions(*action_names)
8
+ @defined_actions = action_names
9
+
10
+ action_names.each do |action|
11
+ case action
12
+ when :browse then define_browse
13
+ when :read then define_read
14
+ when :add then define_add
15
+ when :edit then define_edit
16
+ when :delete then define_delete
17
+ when :upload then define_upload
18
+ end
19
+ end
20
+ end
21
+
22
+ def defined_actions
23
+ @defined_actions || []
24
+ end
25
+
26
+ def resource_name
27
+ name.split("::").last.downcase
28
+ end
29
+
30
+ private
31
+
32
+ def define_browse
33
+ define_method(:browse) do |**params|
34
+ url = @config.resource_url(resource_name)
35
+ body = @client.get(url, params)
36
+ Ghost::Response.new(body)
37
+ end
38
+ end
39
+
40
+ def define_read
41
+ define_method(:read) do |**params|
42
+ url = if params[:id]
43
+ @config.resource_id_url(resource_name, params.delete(:id))
44
+ elsif params[:slug]
45
+ @config.resource_slug_url(resource_name, params.delete(:slug))
46
+ elsif params[:email]
47
+ @config.resource_email_url(resource_name, params.delete(:email))
48
+ else
49
+ raise Ghost::Error, "read requires an id, slug, or email"
50
+ end
51
+
52
+ body = @client.get(url, params)
53
+ Ghost::Response.new(body)
54
+ end
55
+ end
56
+
57
+ def define_add
58
+ define_method(:add) do |**params|
59
+ url = @config.resource_url(resource_name)
60
+ payload = { resource_name => [params] }
61
+ body = @client.post(url, payload)
62
+ Ghost::Response.new(body)
63
+ end
64
+ end
65
+
66
+ def define_edit
67
+ define_method(:edit) do |**params|
68
+ id = params.delete(:id) || raise(Ghost::Error, "edit requires an id")
69
+ url = @config.resource_id_url(resource_name, id)
70
+ payload = { resource_name => [params] }
71
+ body = @client.put(url, payload)
72
+ Ghost::Response.new(body)
73
+ end
74
+ end
75
+
76
+ def define_delete
77
+ define_method(:delete) do |**params|
78
+ id = params.delete(:id) || raise(Ghost::Error, "delete requires an id")
79
+ url = @config.resource_id_url(resource_name, id)
80
+ @client.delete(url)
81
+ true
82
+ end
83
+ end
84
+
85
+ def define_upload
86
+ define_method(:upload) do |file:, ref: nil|
87
+ url = @config.resource_url(resource_name) + "upload/"
88
+ body = @client.upload(url, file, ref: ref)
89
+ Ghost::Response.new(body)
90
+ end
91
+ end
92
+ end
93
+
94
+ def initialize(client:, config:)
95
+ @client = client
96
+ @config = config
97
+ end
98
+
99
+ private
100
+
101
+ def resource_name
102
+ self.class.resource_name
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Authors < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Newsletters < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Offers < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Pages < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Posts < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Settings < Base
7
+ actions :browse
8
+
9
+ def resource_name
10
+ "settings"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Tags < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ module Resources
5
+ module Content
6
+ class Tiers < Base
7
+ actions :browse, :read
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ class Response
5
+ include Enumerable
6
+
7
+ attr_reader :raw
8
+
9
+ def initialize(raw)
10
+ @raw = raw
11
+ end
12
+
13
+ def data
14
+ @data ||= raw[resource_key] || []
15
+ end
16
+
17
+ def first
18
+ data.first
19
+ end
20
+
21
+ def meta
22
+ raw["meta"]
23
+ end
24
+
25
+ def pagination
26
+ meta&.dig("pagination")
27
+ end
28
+
29
+ def each(&block)
30
+ data.each(&block)
31
+ end
32
+
33
+ def to_a
34
+ data
35
+ end
36
+
37
+ private
38
+
39
+ def resource_key
40
+ @resource_key ||= raw.keys.find { |k| k != "meta" }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ghost
4
+ VERSION = "1.0.0"
5
+ end
data/lib/ghost-ruby.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ghost"
data/lib/ghost.rb ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ghost/version"
4
+ require_relative "ghost/errors"
5
+ require_relative "ghost/config"
6
+ require_relative "ghost/response"
7
+ require_relative "ghost/client"
8
+
9
+ require_relative "ghost/authentication/jwt_token"
10
+ require_relative "ghost/authentication/content_key"
11
+
12
+ require_relative "ghost/resources/base"
13
+
14
+ # Admin resources
15
+ require_relative "ghost/resources/admin/posts"
16
+ require_relative "ghost/resources/admin/pages"
17
+ require_relative "ghost/resources/admin/tags"
18
+ require_relative "ghost/resources/admin/members"
19
+ require_relative "ghost/resources/admin/users"
20
+ require_relative "ghost/resources/admin/newsletters"
21
+ require_relative "ghost/resources/admin/tiers"
22
+ require_relative "ghost/resources/admin/offers"
23
+ require_relative "ghost/resources/admin/webhooks"
24
+ require_relative "ghost/resources/admin/site"
25
+ require_relative "ghost/resources/admin/images"
26
+ require_relative "ghost/resources/admin/media"
27
+ require_relative "ghost/resources/admin/files"
28
+ require_relative "ghost/resources/admin/themes"
29
+
30
+ # Content resources
31
+ require_relative "ghost/resources/content/posts"
32
+ require_relative "ghost/resources/content/pages"
33
+ require_relative "ghost/resources/content/authors"
34
+ require_relative "ghost/resources/content/tags"
35
+ require_relative "ghost/resources/content/settings"
36
+ require_relative "ghost/resources/content/tiers"
37
+ require_relative "ghost/resources/content/newsletters"
38
+ require_relative "ghost/resources/content/offers"
39
+
40
+ require_relative "ghost/admin_api"
41
+ require_relative "ghost/content_api"
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghost-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ronald Langeveld
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.7'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.7'
26
+ - !ruby/object:Gem::Dependency
27
+ name: faraday-multipart
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: jwt
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.7'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.7'
54
+ description: Ruby client for the Ghost Content API and Admin API. Supports browsing,
55
+ reading, creating, editing, deleting resources and file uploads.
56
+ executables: []
57
+ extensions: []
58
+ extra_rdoc_files: []
59
+ files:
60
+ - lib/ghost-ruby.rb
61
+ - lib/ghost.rb
62
+ - lib/ghost/admin_api.rb
63
+ - lib/ghost/authentication/content_key.rb
64
+ - lib/ghost/authentication/jwt_token.rb
65
+ - lib/ghost/client.rb
66
+ - lib/ghost/config.rb
67
+ - lib/ghost/content_api.rb
68
+ - lib/ghost/errors.rb
69
+ - lib/ghost/resources/admin/files.rb
70
+ - lib/ghost/resources/admin/images.rb
71
+ - lib/ghost/resources/admin/media.rb
72
+ - lib/ghost/resources/admin/members.rb
73
+ - lib/ghost/resources/admin/newsletters.rb
74
+ - lib/ghost/resources/admin/offers.rb
75
+ - lib/ghost/resources/admin/pages.rb
76
+ - lib/ghost/resources/admin/posts.rb
77
+ - lib/ghost/resources/admin/site.rb
78
+ - lib/ghost/resources/admin/tags.rb
79
+ - lib/ghost/resources/admin/themes.rb
80
+ - lib/ghost/resources/admin/tiers.rb
81
+ - lib/ghost/resources/admin/users.rb
82
+ - lib/ghost/resources/admin/webhooks.rb
83
+ - lib/ghost/resources/base.rb
84
+ - lib/ghost/resources/content/authors.rb
85
+ - lib/ghost/resources/content/newsletters.rb
86
+ - lib/ghost/resources/content/offers.rb
87
+ - lib/ghost/resources/content/pages.rb
88
+ - lib/ghost/resources/content/posts.rb
89
+ - lib/ghost/resources/content/settings.rb
90
+ - lib/ghost/resources/content/tags.rb
91
+ - lib/ghost/resources/content/tiers.rb
92
+ - lib/ghost/response.rb
93
+ - lib/ghost/version.rb
94
+ homepage: https://github.com/ronaldlangeveld/ghost-ruby
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '3.0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubygems_version: 3.6.9
113
+ specification_version: 4
114
+ summary: Ruby SDK for the Ghost CMS API
115
+ test_files: []