pakyow-core 0.11.3 → 1.0.0.rc1

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 (156) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +0 -0
  3. data/LICENSE +4 -0
  4. data/{pakyow-core/README.md → README.md} +3 -4
  5. data/commands/pakyow +13 -0
  6. data/lib/pakyow/app/connection/behavior/session.rb +33 -0
  7. data/lib/pakyow/app/connection/behavior/values.rb +42 -0
  8. data/lib/pakyow/app/connection/behavior/verifier.rb +34 -0
  9. data/lib/pakyow/app/connection/session/abstract.rb +24 -0
  10. data/lib/pakyow/app/connection/session/cookie.rb +56 -0
  11. data/lib/pakyow/app/connection.rb +57 -0
  12. data/lib/pakyow/app.rb +219 -0
  13. data/lib/pakyow/behavior/aspects.rb +45 -0
  14. data/lib/pakyow/behavior/config.rb +72 -0
  15. data/lib/pakyow/behavior/endpoints.rb +41 -0
  16. data/lib/pakyow/behavior/frameworks.rb +45 -0
  17. data/lib/pakyow/behavior/helpers.rb +107 -0
  18. data/lib/pakyow/behavior/initializers.rb +19 -0
  19. data/lib/pakyow/behavior/isolating.rb +69 -0
  20. data/lib/pakyow/behavior/operations.rb +46 -0
  21. data/lib/pakyow/behavior/pipeline.rb +58 -0
  22. data/lib/pakyow/behavior/plugins.rb +148 -0
  23. data/lib/pakyow/behavior/rescuing.rb +51 -0
  24. data/lib/pakyow/behavior/restarting.rb +68 -0
  25. data/lib/pakyow/behavior/sessions.rb +34 -0
  26. data/lib/pakyow/behavior/verification.rb +47 -0
  27. data/lib/pakyow/cli.rb +199 -0
  28. data/lib/pakyow/connection/multipart_input.rb +24 -0
  29. data/lib/pakyow/connection/multipart_parser.rb +112 -0
  30. data/lib/pakyow/connection/params.rb +29 -0
  31. data/lib/pakyow/connection/query_parser.rb +174 -0
  32. data/lib/pakyow/connection/statuses.rb +119 -0
  33. data/lib/pakyow/connection.rb +568 -0
  34. data/lib/pakyow/endpoints.rb +94 -0
  35. data/lib/pakyow/environment/actions/dispatch.rb +37 -0
  36. data/lib/pakyow/environment/actions/input_parser.rb +21 -0
  37. data/lib/pakyow/environment/actions/logger.rb +33 -0
  38. data/lib/pakyow/environment/actions/normalizer.rb +73 -0
  39. data/lib/pakyow/environment/behavior/config.rb +166 -0
  40. data/lib/pakyow/environment/behavior/initializers.rb +21 -0
  41. data/lib/pakyow/environment/behavior/input_parsing.rb +54 -0
  42. data/lib/pakyow/environment/behavior/plugins.rb +23 -0
  43. data/lib/pakyow/environment/behavior/restarting.rb +54 -0
  44. data/lib/pakyow/environment/behavior/running.rb +129 -0
  45. data/lib/pakyow/environment/behavior/silencing.rb +23 -0
  46. data/lib/pakyow/environment/behavior/timezone.rb +21 -0
  47. data/lib/pakyow/environment/behavior/watching.rb +75 -0
  48. data/lib/pakyow/environment.rb +381 -0
  49. data/lib/pakyow/error.rb +273 -0
  50. data/lib/pakyow/errors.rb +97 -0
  51. data/lib/pakyow/framework.rb +39 -0
  52. data/lib/pakyow/generator.rb +138 -0
  53. data/lib/pakyow/generators/project/default/%dot%env.erb +1 -0
  54. data/lib/pakyow/generators/project/default/%dot%gitignore +11 -0
  55. data/lib/pakyow/generators/project/default/%dot%ruby-version.erb +1 -0
  56. data/lib/pakyow/generators/project/default/Gemfile.erb +28 -0
  57. data/lib/pakyow/generators/project/default/README.md +14 -0
  58. data/lib/pakyow/generators/project/default/config/application.rb.erb +17 -0
  59. data/lib/pakyow/generators/project/default/config/environment.rb +11 -0
  60. data/lib/pakyow/generators/project/default/config/initializers/application/keep +0 -0
  61. data/lib/pakyow/generators/project/default/config/initializers/environment/keep +0 -0
  62. data/lib/pakyow/generators/project/default/database/keep +0 -0
  63. data/lib/pakyow/generators/project/default/frontend/assets/images/keep +0 -0
  64. data/lib/pakyow/generators/project/default/frontend/assets/packs/keep +0 -0
  65. data/lib/pakyow/generators/project/default/frontend/assets/styles/keep +0 -0
  66. data/lib/pakyow/generators/project/default/frontend/includes/keep +0 -0
  67. data/lib/pakyow/generators/project/default/frontend/layouts/default.html.erb +19 -0
  68. data/lib/pakyow/generators/project/default/frontend/pages/keep +0 -0
  69. data/lib/pakyow/generators/project/default/public/favicon.ico +0 -0
  70. data/lib/pakyow/generators/project/default/public/robots.txt +1 -0
  71. data/lib/pakyow/generators/project.rb +29 -0
  72. data/lib/pakyow/helpers/app.rb +28 -0
  73. data/lib/pakyow/helpers/connection.rb +45 -0
  74. data/lib/pakyow/info.rb +26 -0
  75. data/lib/pakyow/integrations/bootsnap.rb +18 -0
  76. data/lib/pakyow/integrations/bundler/require.rb +7 -0
  77. data/lib/pakyow/integrations/bundler/setup.rb +7 -0
  78. data/lib/pakyow/integrations/dotenv.rb +9 -0
  79. data/lib/pakyow/loader.rb +31 -0
  80. data/lib/pakyow/logger/colorizer.rb +38 -0
  81. data/lib/pakyow/logger/destination.rb +17 -0
  82. data/lib/pakyow/logger/formatter.rb +22 -0
  83. data/lib/pakyow/logger/formatters/human.rb +101 -0
  84. data/lib/pakyow/logger/formatters/json.rb +99 -0
  85. data/lib/pakyow/logger/formatters/logfmt.rb +50 -0
  86. data/lib/pakyow/logger/multiplexed.rb +19 -0
  87. data/lib/pakyow/logger/thread_local.rb +29 -0
  88. data/lib/pakyow/logger/timekeeper.rb +64 -0
  89. data/lib/pakyow/logger.rb +125 -0
  90. data/lib/pakyow/operation.rb +71 -0
  91. data/lib/pakyow/plugin/helper_caller.rb +20 -0
  92. data/lib/pakyow/plugin/lookup.rb +33 -0
  93. data/lib/pakyow/plugin/state.rb +68 -0
  94. data/lib/pakyow/plugin.rb +367 -0
  95. data/lib/pakyow/process_manager.rb +53 -0
  96. data/lib/pakyow/processes/proxy.rb +67 -0
  97. data/lib/pakyow/processes/server.rb +32 -0
  98. data/lib/pakyow/rack/compatibility.rb +68 -0
  99. data/lib/pakyow/task.rb +315 -0
  100. data/lib/pakyow/tasks/boot.rake +21 -0
  101. data/lib/pakyow/tasks/create.rake +32 -0
  102. data/lib/pakyow/tasks/help.rake +17 -0
  103. data/lib/pakyow/tasks/info/endpoints.rake +72 -0
  104. data/lib/pakyow/tasks/info.rake +31 -0
  105. data/lib/pakyow/tasks/irb.rake +11 -0
  106. data/lib/pakyow/tasks/prelaunch.rake +37 -0
  107. data/lib/pakyow/types.rb +32 -0
  108. data/lib/pakyow/validations/acceptance.rb +37 -0
  109. data/lib/pakyow/validations/email.rb +28 -0
  110. data/lib/pakyow/validations/inline.rb +32 -0
  111. data/lib/pakyow/validations/length.rb +44 -0
  112. data/lib/pakyow/validations/presence.rb +41 -0
  113. data/lib/pakyow/validations.rb +8 -0
  114. data/lib/pakyow/validator.rb +81 -0
  115. data/lib/pakyow/verifier.rb +177 -0
  116. data/lib/pakyow.rb +5 -0
  117. metadata +267 -65
  118. data/pakyow-core/CHANGELOG.md +0 -128
  119. data/pakyow-core/LICENSE +0 -20
  120. data/pakyow-core/lib/pakyow/core/app.rb +0 -82
  121. data/pakyow-core/lib/pakyow/core/app_context.rb +0 -10
  122. data/pakyow-core/lib/pakyow/core/base.rb +0 -61
  123. data/pakyow-core/lib/pakyow/core/call_context.rb +0 -171
  124. data/pakyow-core/lib/pakyow/core/config/app.rb +0 -49
  125. data/pakyow-core/lib/pakyow/core/config/cookies.rb +0 -4
  126. data/pakyow-core/lib/pakyow/core/config/logger.rb +0 -34
  127. data/pakyow-core/lib/pakyow/core/config/reloader.rb +0 -10
  128. data/pakyow-core/lib/pakyow/core/config/server.rb +0 -10
  129. data/pakyow-core/lib/pakyow/core/config/session.rb +0 -41
  130. data/pakyow-core/lib/pakyow/core/config.rb +0 -95
  131. data/pakyow-core/lib/pakyow/core/errors.rb +0 -16
  132. data/pakyow-core/lib/pakyow/core/helpers/configuring.rb +0 -142
  133. data/pakyow-core/lib/pakyow/core/helpers/hooks.rb +0 -106
  134. data/pakyow-core/lib/pakyow/core/helpers/running.rb +0 -124
  135. data/pakyow-core/lib/pakyow/core/helpers.rb +0 -61
  136. data/pakyow-core/lib/pakyow/core/loader.rb +0 -32
  137. data/pakyow-core/lib/pakyow/core/middleware/logger.rb +0 -146
  138. data/pakyow-core/lib/pakyow/core/middleware/override.rb +0 -3
  139. data/pakyow-core/lib/pakyow/core/middleware/reloader.rb +0 -23
  140. data/pakyow-core/lib/pakyow/core/middleware/req_path_normalizer.rb +0 -49
  141. data/pakyow-core/lib/pakyow/core/middleware/session.rb +0 -5
  142. data/pakyow-core/lib/pakyow/core/middleware/static.rb +0 -76
  143. data/pakyow-core/lib/pakyow/core/multilog.rb +0 -19
  144. data/pakyow-core/lib/pakyow/core/request.rb +0 -119
  145. data/pakyow-core/lib/pakyow/core/response.rb +0 -135
  146. data/pakyow-core/lib/pakyow/core/route_eval.rb +0 -254
  147. data/pakyow-core/lib/pakyow/core/route_expansion_eval.rb +0 -115
  148. data/pakyow-core/lib/pakyow/core/route_lookup.rb +0 -41
  149. data/pakyow-core/lib/pakyow/core/route_merger.rb +0 -76
  150. data/pakyow-core/lib/pakyow/core/route_module.rb +0 -21
  151. data/pakyow-core/lib/pakyow/core/route_set.rb +0 -74
  152. data/pakyow-core/lib/pakyow/core/route_template_defaults.rb +0 -43
  153. data/pakyow-core/lib/pakyow/core/route_template_eval.rb +0 -72
  154. data/pakyow-core/lib/pakyow/core/router.rb +0 -181
  155. data/pakyow-core/lib/pakyow/core.rb +0 -8
  156. data/pakyow-core/lib/pakyow-core.rb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 21965299064896d7f6a0fe9754be19d816af9015
4
- data.tar.gz: c43ff75f0e740c9d7c68150d45cfcd386a451728
2
+ SHA256:
3
+ metadata.gz: 6652c3a490f4119178a05144e2bb48e035748d5511453d30c645d8ef8ca2e648
4
+ data.tar.gz: 6bcc4365fcb0dff053a82dfdd9284ed016c406a4106da652db8e878a57edbc17
5
5
  SHA512:
6
- metadata.gz: 4fb95b27d158e2bbf7a14d91a3aa3a80e3fc095b26be99b9500d81ffb8f99f551c9e5431fe52b81d11636f04260eb284f65ef8ba3ae899309dc217fa32f3a07a
7
- data.tar.gz: f26f87083735c00dd4fe4635a850b9ad1ed4a2a0c73253655c0c73d8404b64f6cdf45fd352bc86bdb02ec2fb53026c8c423f00aad2a759bc048bd2d5a13a933d
6
+ metadata.gz: 89dfd288361faac6ccb96b94f48ba464208f609271b4e032279bb4450a42c45c4a6a946962627b0672b85fbd19f05bfba20cf3ec4d95eede722d2ffff40f871a
7
+ data.tar.gz: bd861c99ce96392a1ed9f0870f53206f9a05e0842f8a6500746fac459dfb01ba18ee6690d6008ee633e0938ed3cac7e4a03d45c904591421f671ef9215ca08c1
data/CHANGELOG.md ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ Copyright (c) Metabahn, LLC
2
+
3
+ Pakyow Core is an open-source project licensed under the terms of the LGPLv3 license.
4
+ See <https://choosealicense.com/licenses/lgpl-3.0/> for license text.
@@ -1,6 +1,6 @@
1
1
  # pakyow-core
2
2
 
3
- Core routing for Pakyow.
3
+ Core functionality for Pakyow.
4
4
 
5
5
  # Download
6
6
 
@@ -16,14 +16,13 @@ Source code can be downloaded as part of the Pakyow project on Github:
16
16
 
17
17
  # License
18
18
 
19
- Pakyow Core is released free and open-source under the [MIT
20
- License](http://opensource.org/licenses/MIT).
19
+ Pakyow Routing is free and open-source under the [LGPLv3 license](https://choosealicense.com/licenses/lgpl-3.0/).
21
20
 
22
21
  # Support
23
22
 
24
23
  Documentation is available here:
25
24
 
26
- - http://pakyow.org/docs/routing
25
+ - http://pakyow.org/docs/
27
26
 
28
27
  Found a bug? Tell us about it here:
29
28
 
data/commands/pakyow ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Automatically run with bundler.
5
+ #
6
+ current_path = File.expand_path(".")
7
+ binstub_path = File.join(current_path, "bin/pakyow")
8
+ if !defined?(Bundler) && File.exist?(binstub_path)
9
+ exec "#{binstub_path} #{ARGV.join(" ")}"
10
+ else
11
+ require "pakyow/cli"
12
+ Pakyow::CLI.new
13
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ class App
7
+ class Connection
8
+ module Behavior
9
+ module Session
10
+ extend Support::Extension
11
+
12
+ def session
13
+ unless instance_variable_defined?(:@session)
14
+ @session = build_session
15
+ end
16
+
17
+ @session
18
+ end
19
+
20
+ private
21
+
22
+ def build_session
23
+ if @app.config.session.enabled
24
+ @app.session_object.new(self, @app.session_options)
25
+ else
26
+ nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/deep_dup"
4
+ require "pakyow/support/extension"
5
+
6
+ module Pakyow
7
+ class App
8
+ class Connection
9
+ module Behavior
10
+ module Values
11
+ extend Support::Extension
12
+ using Support::DeepDup
13
+
14
+ # @api private
15
+ attr_reader :values
16
+
17
+ apply_extension do
18
+ after "initialize" do
19
+ @values = {}
20
+ end
21
+
22
+ after "dup" do
23
+ @values = @values.deep_dup
24
+ end
25
+ end
26
+
27
+ def set?(key)
28
+ @values.key?(key.to_sym)
29
+ end
30
+
31
+ def set(key, value)
32
+ @values[key.to_sym] = value
33
+ end
34
+
35
+ def get(key)
36
+ @values[key.to_sym]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+ require "pakyow/support/message_verifier"
5
+
6
+ module Pakyow
7
+ class App
8
+ class Connection
9
+ module Behavior
10
+ module Verifier
11
+ extend Support::Extension
12
+
13
+ apply_extension do
14
+ after "initialize" do
15
+ session[:verifier_key] ||= Support::MessageVerifier.key
16
+ end
17
+ end
18
+
19
+ def verifier
20
+ unless instance_variable_defined?(:@verifier)
21
+ @verifier = Support::MessageVerifier.new(verifier_key)
22
+ end
23
+
24
+ @verifier
25
+ end
26
+
27
+ def verifier_key
28
+ session[:verifier_key]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/indifferentize"
4
+
5
+ module Pakyow
6
+ class App
7
+ class Connection
8
+ module Session
9
+ class Abstract < DelegateClass(Support::IndifferentHash)
10
+ def initialize(connection, options, values = Support::IndifferentHash.new)
11
+ @connection, @options = connection, options
12
+ super(values)
13
+ end
14
+
15
+ # Fixes an issue using pp inside a delegator.
16
+ #
17
+ def pp(*args)
18
+ Kernel.pp(*args)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+
5
+ require "pakyow/support/indifferentize"
6
+
7
+ require "pakyow/app/connection/session/abstract"
8
+
9
+ module Pakyow
10
+ class App
11
+ class Connection
12
+ module Session
13
+ class Cookie < Abstract
14
+ def initialize(connection, options)
15
+ if (cookie = connection.cookies[options.name]) && !cookie.is_a?(String)
16
+ super(connection, options, Support::IndifferentHash.new(cookie[:value].to_h))
17
+ connection.cookies[options.name][:value] = self
18
+ else
19
+ super(connection, options, deserialize(connection, options))
20
+ connection.cookies[options.name] = Support::IndifferentHash.new(
21
+ domain: options.domain,
22
+ path: options.path,
23
+ max_age: options.max_age,
24
+ expires: options.expires,
25
+ secure: options.secure,
26
+ http_only: options.http_only,
27
+ same_site: options.same_site,
28
+ value: self
29
+ )
30
+
31
+ # Update the original cookie value so we can compare for changes.
32
+ #
33
+ connection.update_request_cookie(options.name, self.dup)
34
+ end
35
+ end
36
+
37
+ def to_s
38
+ Base64.urlsafe_encode64(Marshal.dump(to_h))
39
+ end
40
+
41
+ private
42
+
43
+ def deserialize(connection, options)
44
+ if value = connection.cookies[options.name]
45
+ Support::IndifferentHash.deep(Marshal.load(Base64.urlsafe_decode64(value)))
46
+ else
47
+ Support::IndifferentHash.new
48
+ end
49
+ rescue StandardError
50
+ Support::IndifferentHash.new
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ require "pakyow/support/hookable"
6
+
7
+ module Pakyow
8
+ class App
9
+ class Connection < SimpleDelegator
10
+ attr_reader :app
11
+
12
+ include Support::Hookable
13
+ events :initialize, :dup
14
+
15
+ require "pakyow/app/connection/behavior/session"
16
+ require "pakyow/app/connection/behavior/verifier"
17
+ require "pakyow/app/connection/behavior/values"
18
+
19
+ include Behavior::Session
20
+ include Behavior::Verifier
21
+ include Behavior::Values
22
+
23
+ def initialize(app, connection)
24
+ performing :initialize do
25
+ @app = app; __setobj__(connection)
26
+ end
27
+ end
28
+
29
+ def initialize_dup(_)
30
+ performing :dup do
31
+ super
32
+ end
33
+ end
34
+
35
+ def method
36
+ __getobj__.method
37
+ end
38
+
39
+ # Fixes an issue using pp inside a delegator.
40
+ #
41
+ def pp(*args)
42
+ Kernel.pp(*args)
43
+ end
44
+
45
+ # @api private
46
+ def self.from_connection(connection, **overrides)
47
+ instance = allocate
48
+
49
+ connection.instance_variables.each do |ivar|
50
+ instance.instance_variable_set(ivar, overrides[ivar] || connection.instance_variable_get(ivar))
51
+ end
52
+
53
+ instance
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/pakyow/app.rb ADDED
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/definable"
4
+ require "pakyow/support/deep_freeze"
5
+ require "pakyow/support/class_state"
6
+ require "pakyow/support/inspectable"
7
+ require "pakyow/support/hookable"
8
+ require "pakyow/support/configurable"
9
+ require "pakyow/support/pipeline"
10
+
11
+ require "pakyow/behavior/config"
12
+ require "pakyow/behavior/sessions"
13
+ require "pakyow/behavior/endpoints"
14
+ require "pakyow/behavior/pipeline"
15
+ require "pakyow/behavior/frameworks"
16
+ require "pakyow/behavior/aspects"
17
+ require "pakyow/behavior/helpers"
18
+ require "pakyow/behavior/rescuing"
19
+ require "pakyow/behavior/restarting"
20
+ require "pakyow/behavior/isolating"
21
+ require "pakyow/behavior/initializers"
22
+ require "pakyow/behavior/plugins"
23
+ require "pakyow/behavior/operations"
24
+
25
+ require "pakyow/connection"
26
+
27
+ module Pakyow
28
+ # Pakyow's main application object. Can be defined directly or subclassed to
29
+ # create multiple application objects, each containing its own state. These
30
+ # applications can then be mounted as an endpoint within the environment.
31
+ #
32
+ # Pakyow::App.define do
33
+ # # state shared between all apps goes here
34
+ # end
35
+ #
36
+ # class API < Pakyow::App
37
+ # # state for this app goes here
38
+ # end
39
+ #
40
+ # Pakyow.configure do
41
+ # mount API, at: "/api"
42
+ # end
43
+ #
44
+ # = Pipeline
45
+ #
46
+ # Requests are received by {App#call}, creating a {Connection} object that
47
+ # provides an interface to the underlying request state. The connection is
48
+ # pushed through a pipeline. Each pipeline action can modify the connection
49
+ # and then either 1) allow the connection to hit the next action 2) halt
50
+ # pipeline execution completely.
51
+ #
52
+ # Once the connection exits the pipeline a response is returned. If an action
53
+ # halted, the connection is finalized and returned, otherwise app assumes
54
+ # that the connection was unhandled and returns a canned 404 response.
55
+ #
56
+ # App also catches any unhandled errors that occur in the pipeline by simply
57
+ # logging the error and returning a canned 500 response.
58
+ #
59
+ # @see Support::Pipeline
60
+ #
61
+ # = Configuration
62
+ #
63
+ # App objects can be configured.
64
+ #
65
+ # Pakyow::App.configure do
66
+ # config.name = "my-app"
67
+ # end
68
+ #
69
+ # It's possible to configure for certain environments.
70
+ #
71
+ # Pakyow::App.configure :development do
72
+ # config.name = "my-dev-app"
73
+ # end
74
+ #
75
+ # The +app+ config namespace can be extended with your own custom options.
76
+ #
77
+ # Pakyow::App.configure do
78
+ # config.foo = "bar"
79
+ # end
80
+ #
81
+ # @see Support::Configurable
82
+ #
83
+ # = Hooks
84
+ #
85
+ # Hooks can be defined for the following events:
86
+ #
87
+ # - initialize
88
+ # - configure
89
+ # - load
90
+ # - finalize
91
+ # - boot
92
+ # - rescue
93
+ # - shutdown
94
+ #
95
+ # Here's how to log a message after initialize:
96
+ #
97
+ # Pakyow::App.after "initialize" do
98
+ # logger.info "initialized #{self}"
99
+ # end
100
+ #
101
+ # @see Support::Hookable
102
+ #
103
+ class App
104
+ require "pakyow/app/connection"
105
+
106
+ class << self
107
+ def inherited(subclass)
108
+ super
109
+
110
+ # Creates a connection subclass that other frameworks can safely extend.
111
+ #
112
+ subclass.isolate Connection
113
+ end
114
+ end
115
+
116
+ # Environment the app is booted in, e.g. +:development+.
117
+ #
118
+ attr_reader :environment
119
+
120
+ # App mount path.
121
+ #
122
+ attr_reader :mount_path
123
+
124
+ include Support::Inspectable
125
+ inspectable :@environment
126
+
127
+ include Support::Hookable
128
+ events :initialize, :configure, :load, :finalize, :boot, :rescue, :shutdown
129
+
130
+ include Support::Configurable
131
+ include Support::Definable
132
+ include Support::Pipeline
133
+
134
+ include Behavior::Config
135
+ include Behavior::Sessions
136
+ include Behavior::Endpoints
137
+ include Behavior::Pipeline
138
+ include Behavior::Frameworks
139
+ include Behavior::Aspects
140
+ include Behavior::Helpers
141
+ include Behavior::Rescuing
142
+ include Behavior::Restarting
143
+ include Behavior::Isolating
144
+ include Behavior::Initializers
145
+ include Behavior::Plugins
146
+ include Behavior::Operations
147
+
148
+ def initialize(environment, mount_path: "/", &block)
149
+ super()
150
+
151
+ @environment, @mount_path, @rescued = environment, mount_path, false
152
+
153
+ performing :initialize do
154
+ performing :configure do
155
+ configure!(environment)
156
+ end
157
+
158
+ performing :load do
159
+ $LOAD_PATH.unshift(config.lib)
160
+ end
161
+
162
+ config.version = Support::PathVersion.build(config.src)
163
+
164
+ # Call the Pakyow::Definable initializer.
165
+ #
166
+ # This ensures that any state registered in the passed block
167
+ # has the proper priority against instance and global state.
168
+ #
169
+ defined!(&block)
170
+ end
171
+ rescue ScriptError, StandardError => error
172
+ rescue!(error)
173
+ end
174
+
175
+ # Called by the environment after it boots the app.
176
+ #
177
+ def booted
178
+ unless rescued?
179
+ call_hooks :after, :boot
180
+ end
181
+ rescue ScriptError, StandardError => error
182
+ rescue!(error)
183
+ end
184
+
185
+ # Calls the app pipeline with a connection created from the rack env.
186
+ #
187
+ def call(connection)
188
+ app_connection = isolated(:Connection).new(self, connection)
189
+ super(app_connection)
190
+ rescue => error
191
+ if respond_to?(:controller_for_connection)
192
+ controller_for_connection(app_connection).handle_error(error)
193
+ else
194
+ raise error
195
+ end
196
+ end
197
+
198
+ def shutdown
199
+ performing :shutdown do; end
200
+ end
201
+
202
+ def _dump(_)
203
+ Marshal.dump(
204
+ {
205
+ name: config.name
206
+ }
207
+ )
208
+ end
209
+
210
+ def self._load(state)
211
+ Pakyow.app(Marshal.load(state)[:name])
212
+ end
213
+
214
+ # @api private
215
+ def perform(app_connection)
216
+ @__pipeline.call(app_connection)
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ require "pakyow/loader"
6
+
7
+ module Pakyow
8
+ module Behavior
9
+ # Maintains known aspects and loads them.
10
+ #
11
+ module Aspects
12
+ extend Support::Extension
13
+
14
+ apply_extension do
15
+ setting :aspects, []
16
+
17
+ after "load" do
18
+ config.aspects.each do |aspect|
19
+ load_aspect(aspect)
20
+ end
21
+ end
22
+ end
23
+
24
+ class_methods do
25
+ # Registers an app aspect by name.
26
+ #
27
+ def aspect(name)
28
+ (config.aspects << name.to_sym).uniq!
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def load_aspect(aspect, path: File.join(config.src, aspect.to_s), target: self.class)
35
+ Dir.glob(File.join(path, "*.rb")) do |file_path|
36
+ Loader.new(file_path).call(target)
37
+ end
38
+
39
+ Dir.glob(File.join(path, "*")).select { |sub_path| File.directory?(sub_path) }.each do |directory|
40
+ load_aspect(aspect, path: directory, target: target)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+ require "pakyow/support/path_version"
5
+
6
+ module Pakyow
7
+ module Behavior
8
+ module Config
9
+ extend Support::Extension
10
+
11
+ apply_extension do
12
+ setting :name, :pakyow
13
+ setting :version
14
+
15
+ setting :root do
16
+ Pakyow.config.root
17
+ end
18
+
19
+ setting :src do
20
+ File.join(config.root, "backend")
21
+ end
22
+
23
+ setting :lib do
24
+ File.join(config.src, "lib")
25
+ end
26
+
27
+ configurable :tasks do
28
+ setting :prelaunch, []
29
+ end
30
+
31
+ configurable :session do
32
+ setting :enabled, true
33
+ setting :object, :cookie
34
+
35
+ configurable :cookie do
36
+ setting :name do
37
+ "#{config.name}.session"
38
+ end
39
+
40
+ setting :domain do
41
+ Pakyow.config.cookies.domain
42
+ end
43
+
44
+ setting :path do
45
+ Pakyow.config.cookies.path
46
+ end
47
+
48
+ setting :max_age do
49
+ Pakyow.config.cookies.max_age
50
+ end
51
+
52
+ setting :expires do
53
+ Pakyow.config.cookies.expires
54
+ end
55
+
56
+ setting :secure do
57
+ Pakyow.config.cookies.secure
58
+ end
59
+
60
+ setting :http_only do
61
+ Pakyow.config.cookies.http_only
62
+ end
63
+
64
+ setting :same_site do
65
+ Pakyow.config.cookies.same_site
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ require "pakyow/endpoints"
6
+
7
+ module Pakyow
8
+ module Behavior
9
+ module Endpoints
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ after "initialize" do
14
+ load_endpoints
15
+ end
16
+ end
17
+
18
+ prepend_methods do
19
+ def initialize(*)
20
+ @endpoints = ::Pakyow::Endpoints.new
21
+
22
+ super
23
+ end
24
+ end
25
+
26
+ # Instance of {Endpoints} for path building.
27
+ #
28
+ attr_reader :endpoints
29
+
30
+ private
31
+
32
+ def load_endpoints
33
+ state.values.each do |state_object|
34
+ state_object.instances.each do |state_instance|
35
+ @endpoints.load(state_instance)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end