parse-stack-next 4.5.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 (178) hide show
  1. checksums.yaml +7 -0
  2. data/.bundle/config +2 -0
  3. data/.env.sample +112 -0
  4. data/.env.test +10 -0
  5. data/.github/workflows/ruby.yml +36 -0
  6. data/.gitignore +49 -0
  7. data/.ruby-version +1 -0
  8. data/.solargraph.yml +22 -0
  9. data/CHANGELOG.md +5816 -0
  10. data/Gemfile +30 -0
  11. data/Gemfile.lock +175 -0
  12. data/LICENSE.txt +23 -0
  13. data/Makefile +63 -0
  14. data/README.md +5655 -0
  15. data/Rakefile +573 -0
  16. data/bin/console +38 -0
  17. data/bin/parse-console +136 -0
  18. data/bin/server +17 -0
  19. data/bin/setup +7 -0
  20. data/config/parse-config.json +12 -0
  21. data/docs/TEST_SERVER.md +271 -0
  22. data/docs/_config.yml +1 -0
  23. data/docs/mcp_guide.md +3484 -0
  24. data/docs/mongodb_direct_guide.md +1348 -0
  25. data/docs/mongodb_index_optimization_guide.md +631 -0
  26. data/examples/transaction_example.rb +219 -0
  27. data/lib/parse/acl_scope.rb +728 -0
  28. data/lib/parse/agent/cancellation_token.rb +80 -0
  29. data/lib/parse/agent/constraint_translator.rb +480 -0
  30. data/lib/parse/agent/describe.rb +420 -0
  31. data/lib/parse/agent/errors.rb +133 -0
  32. data/lib/parse/agent/mcp_client.rb +557 -0
  33. data/lib/parse/agent/mcp_dispatcher.rb +1023 -0
  34. data/lib/parse/agent/mcp_rack_app.rb +1143 -0
  35. data/lib/parse/agent/mcp_server.rb +376 -0
  36. data/lib/parse/agent/metadata_audit.rb +259 -0
  37. data/lib/parse/agent/metadata_dsl.rb +733 -0
  38. data/lib/parse/agent/metadata_registry.rb +794 -0
  39. data/lib/parse/agent/pipeline_validator.rb +82 -0
  40. data/lib/parse/agent/prompts.rb +351 -0
  41. data/lib/parse/agent/rate_limiter.rb +158 -0
  42. data/lib/parse/agent/relation_graph.rb +162 -0
  43. data/lib/parse/agent/result_formatter.rb +453 -0
  44. data/lib/parse/agent/tools.rb +5489 -0
  45. data/lib/parse/agent.rb +3249 -0
  46. data/lib/parse/api/aggregate.rb +79 -0
  47. data/lib/parse/api/all.rb +26 -0
  48. data/lib/parse/api/analytics.rb +18 -0
  49. data/lib/parse/api/batch.rb +33 -0
  50. data/lib/parse/api/cloud_functions.rb +58 -0
  51. data/lib/parse/api/config.rb +125 -0
  52. data/lib/parse/api/files.rb +29 -0
  53. data/lib/parse/api/hooks.rb +117 -0
  54. data/lib/parse/api/objects.rb +146 -0
  55. data/lib/parse/api/path_segment.rb +75 -0
  56. data/lib/parse/api/push.rb +20 -0
  57. data/lib/parse/api/schema.rb +49 -0
  58. data/lib/parse/api/server.rb +50 -0
  59. data/lib/parse/api/sessions.rb +24 -0
  60. data/lib/parse/api/users.rb +250 -0
  61. data/lib/parse/atlas_search/index_manager.rb +353 -0
  62. data/lib/parse/atlas_search/result.rb +204 -0
  63. data/lib/parse/atlas_search/search_builder.rb +604 -0
  64. data/lib/parse/atlas_search/session.rb +253 -0
  65. data/lib/parse/atlas_search.rb +995 -0
  66. data/lib/parse/client/authentication.rb +97 -0
  67. data/lib/parse/client/batch.rb +234 -0
  68. data/lib/parse/client/body_builder.rb +240 -0
  69. data/lib/parse/client/caching.rb +203 -0
  70. data/lib/parse/client/logging.rb +293 -0
  71. data/lib/parse/client/profiling.rb +181 -0
  72. data/lib/parse/client/protocol.rb +91 -0
  73. data/lib/parse/client/request.rb +233 -0
  74. data/lib/parse/client/response.rb +208 -0
  75. data/lib/parse/client.rb +1104 -0
  76. data/lib/parse/clp_scope.rb +361 -0
  77. data/lib/parse/live_query/circuit_breaker.rb +256 -0
  78. data/lib/parse/live_query/client.rb +1001 -0
  79. data/lib/parse/live_query/configuration.rb +224 -0
  80. data/lib/parse/live_query/event.rb +115 -0
  81. data/lib/parse/live_query/event_queue.rb +272 -0
  82. data/lib/parse/live_query/health_monitor.rb +214 -0
  83. data/lib/parse/live_query/logging.rb +149 -0
  84. data/lib/parse/live_query/subscription.rb +294 -0
  85. data/lib/parse/live_query.rb +163 -0
  86. data/lib/parse/lookup_rewriter.rb +445 -0
  87. data/lib/parse/model/acl.rb +968 -0
  88. data/lib/parse/model/associations/belongs_to.rb +275 -0
  89. data/lib/parse/model/associations/collection_proxy.rb +435 -0
  90. data/lib/parse/model/associations/has_many.rb +597 -0
  91. data/lib/parse/model/associations/has_one.rb +158 -0
  92. data/lib/parse/model/associations/pointer_collection_proxy.rb +134 -0
  93. data/lib/parse/model/associations/relation_collection_proxy.rb +177 -0
  94. data/lib/parse/model/bytes.rb +62 -0
  95. data/lib/parse/model/classes/audience.rb +262 -0
  96. data/lib/parse/model/classes/installation.rb +363 -0
  97. data/lib/parse/model/classes/job_schedule.rb +153 -0
  98. data/lib/parse/model/classes/job_status.rb +264 -0
  99. data/lib/parse/model/classes/product.rb +75 -0
  100. data/lib/parse/model/classes/push_status.rb +263 -0
  101. data/lib/parse/model/classes/role.rb +751 -0
  102. data/lib/parse/model/classes/session.rb +201 -0
  103. data/lib/parse/model/classes/user.rb +943 -0
  104. data/lib/parse/model/clp.rb +544 -0
  105. data/lib/parse/model/core/actions.rb +1268 -0
  106. data/lib/parse/model/core/builder.rb +139 -0
  107. data/lib/parse/model/core/create_lock.rb +386 -0
  108. data/lib/parse/model/core/describe.rb +382 -0
  109. data/lib/parse/model/core/enhanced_change_tracking.rb +159 -0
  110. data/lib/parse/model/core/errors.rb +38 -0
  111. data/lib/parse/model/core/fetching.rb +566 -0
  112. data/lib/parse/model/core/field_guards.rb +220 -0
  113. data/lib/parse/model/core/indexing.rb +382 -0
  114. data/lib/parse/model/core/parse_reference.rb +407 -0
  115. data/lib/parse/model/core/properties.rb +809 -0
  116. data/lib/parse/model/core/querying.rb +491 -0
  117. data/lib/parse/model/core/schema.rb +202 -0
  118. data/lib/parse/model/core/search_indexing.rb +174 -0
  119. data/lib/parse/model/date.rb +88 -0
  120. data/lib/parse/model/email.rb +213 -0
  121. data/lib/parse/model/file.rb +527 -0
  122. data/lib/parse/model/geojson.rb +271 -0
  123. data/lib/parse/model/geopoint.rb +261 -0
  124. data/lib/parse/model/model.rb +260 -0
  125. data/lib/parse/model/object.rb +2068 -0
  126. data/lib/parse/model/phone.rb +520 -0
  127. data/lib/parse/model/pointer.rb +443 -0
  128. data/lib/parse/model/polygon.rb +406 -0
  129. data/lib/parse/model/push.rb +975 -0
  130. data/lib/parse/model/shortnames.rb +8 -0
  131. data/lib/parse/model/time_zone.rb +141 -0
  132. data/lib/parse/model/validations/uniqueness_validator.rb +97 -0
  133. data/lib/parse/model/validations.rb +96 -0
  134. data/lib/parse/mongodb.rb +2300 -0
  135. data/lib/parse/pipeline_security.rb +554 -0
  136. data/lib/parse/query/constraint.rb +198 -0
  137. data/lib/parse/query/constraints.rb +3279 -0
  138. data/lib/parse/query/cursor.rb +434 -0
  139. data/lib/parse/query/n_plus_one_detector.rb +445 -0
  140. data/lib/parse/query/operation.rb +104 -0
  141. data/lib/parse/query/ordering.rb +66 -0
  142. data/lib/parse/query.rb +7028 -0
  143. data/lib/parse/schema/index_migrator.rb +291 -0
  144. data/lib/parse/schema/search_index_migrator.rb +289 -0
  145. data/lib/parse/schema.rb +494 -0
  146. data/lib/parse/stack/generators/rails.rb +40 -0
  147. data/lib/parse/stack/generators/templates/model.erb +51 -0
  148. data/lib/parse/stack/generators/templates/model_installation.rb +4 -0
  149. data/lib/parse/stack/generators/templates/model_role.rb +4 -0
  150. data/lib/parse/stack/generators/templates/model_session.rb +4 -0
  151. data/lib/parse/stack/generators/templates/model_user.rb +11 -0
  152. data/lib/parse/stack/generators/templates/parse.rb +12 -0
  153. data/lib/parse/stack/generators/templates/webhooks.rb +10 -0
  154. data/lib/parse/stack/railtie.rb +18 -0
  155. data/lib/parse/stack/tasks.rb +563 -0
  156. data/lib/parse/stack/version.rb +11 -0
  157. data/lib/parse/stack.rb +455 -0
  158. data/lib/parse/two_factor_auth/user_extension.rb +449 -0
  159. data/lib/parse/two_factor_auth.rb +310 -0
  160. data/lib/parse/webhooks/payload.rb +360 -0
  161. data/lib/parse/webhooks/registration.rb +199 -0
  162. data/lib/parse/webhooks/replay_protection.rb +189 -0
  163. data/lib/parse/webhooks.rb +510 -0
  164. data/lib/parse-stack-next.rb +5 -0
  165. data/lib/parse-stack.rb +5 -0
  166. data/parse-stack-next.gemspec +82 -0
  167. data/parse-stack.png +0 -0
  168. data/scripts/debug-ips.js +35 -0
  169. data/scripts/docker/Dockerfile.parse +13 -0
  170. data/scripts/docker/atlas-init.js +284 -0
  171. data/scripts/docker/docker-compose.atlas.yml +76 -0
  172. data/scripts/docker/docker-compose.test.yml +106 -0
  173. data/scripts/docker/mongo-init.js +21 -0
  174. data/scripts/eval_mcp_with_lm_studio.rb +274 -0
  175. data/scripts/start-parse.sh +90 -0
  176. data/scripts/start_mcp_server.rb +78 -0
  177. data/scripts/test_server_connection.rb +82 -0
  178. metadata +377 -0
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env ruby
2
+ # Transaction Example for Parse-Stack
3
+ #
4
+ # This example demonstrates how to use transactions to ensure atomic operations
5
+ # across multiple Parse objects.
6
+
7
+ require 'parse/stack'
8
+
9
+ # Configure your Parse application
10
+ Parse.setup(
11
+ app_id: ENV['PARSE_APP_ID'] || 'your-app-id',
12
+ api_key: ENV['PARSE_API_KEY'] || 'your-api-key',
13
+ server_url: ENV['PARSE_SERVER_URL'] || 'http://localhost:1337/parse'
14
+ )
15
+
16
+ # Define example models
17
+ class Team < Parse::Object
18
+ property :name
19
+ property :owner, :pointer, class_name: 'User'
20
+ property :member_count, :integer, default: 0
21
+ end
22
+
23
+ class Membership < Parse::Object
24
+ property :user, :pointer, class_name: 'User'
25
+ property :team, :pointer, class_name: 'Team'
26
+ property :access_level, :string
27
+ property :grant, :string
28
+ end
29
+
30
+ class Project < Parse::Object
31
+ property :name
32
+ property :team, :pointer, class_name: 'Team'
33
+ property :owner, :pointer, class_name: 'User'
34
+ end
35
+
36
+ # Example 1: Basic transaction with explicit batch operations
37
+ def transfer_project_ownership_basic(project, new_owner)
38
+ Parse::Object.transaction do |batch|
39
+ # Get old owner
40
+ old_owner = project.owner
41
+
42
+ # Find or create new owner membership
43
+ new_owner_membership = Membership.first(
44
+ project: project,
45
+ user: new_owner
46
+ )
47
+
48
+ if new_owner_membership.nil?
49
+ new_owner_membership = Membership.new(
50
+ project: project,
51
+ team: project.team,
52
+ user: new_owner,
53
+ grant: 'project',
54
+ access_level: 'owner'
55
+ )
56
+ batch.add(new_owner_membership)
57
+ else
58
+ new_owner_membership.access_level = 'owner'
59
+ batch.add(new_owner_membership)
60
+ end
61
+
62
+ # Demote old owner if they have a membership
63
+ if old_owner.present?
64
+ old_owner_membership = Membership.first(
65
+ project: project,
66
+ user: old_owner
67
+ )
68
+
69
+ if old_owner_membership.present?
70
+ old_owner_membership.access_level = 'admin'
71
+ batch.add(old_owner_membership)
72
+ end
73
+ end
74
+
75
+ # Update project owner
76
+ project.owner = new_owner
77
+ batch.add(project)
78
+ end
79
+
80
+ puts "Successfully transferred ownership"
81
+ rescue Parse::Error => e
82
+ puts "Transaction failed: #{e.message}"
83
+ false
84
+ end
85
+
86
+ # Example 2: Transaction with automatic batching via return value
87
+ def transfer_project_ownership_auto(project, new_owner)
88
+ results = Parse::Object.transaction do
89
+ old_owner = project.owner
90
+ objects_to_save = []
91
+
92
+ # Find or create new owner membership
93
+ new_owner_membership = Membership.first(
94
+ project: project,
95
+ user: new_owner
96
+ ) || Membership.new(
97
+ project: project,
98
+ team: project.team,
99
+ user: new_owner,
100
+ grant: 'project'
101
+ )
102
+
103
+ new_owner_membership.access_level = 'owner'
104
+ objects_to_save << new_owner_membership
105
+
106
+ # Demote old owner
107
+ if old_owner.present?
108
+ old_owner_membership = Membership.first(
109
+ project: project,
110
+ user: old_owner
111
+ )
112
+
113
+ if old_owner_membership.present?
114
+ old_owner_membership.access_level = 'admin'
115
+ objects_to_save << old_owner_membership
116
+ end
117
+ end
118
+
119
+ # Update project
120
+ project.owner = new_owner
121
+ objects_to_save << project
122
+
123
+ # Return array of objects to be saved in transaction
124
+ objects_to_save
125
+ end
126
+
127
+ puts "Transaction completed with #{results.count} operations"
128
+ true
129
+ rescue Parse::Error => e
130
+ puts "Transaction failed: #{e.message}"
131
+ false
132
+ end
133
+
134
+ # Example 3: Complex transaction with validation
135
+ def complex_team_operation(team, new_members, new_owner)
136
+ Parse::Object.transaction(retries: 3) do |batch|
137
+ # Validate new owner is in new members list
138
+ unless new_members.include?(new_owner)
139
+ raise Parse::Error, "New owner must be in members list"
140
+ end
141
+
142
+ # Update team
143
+ team.owner = new_owner
144
+ team.member_count = new_members.count
145
+ batch.add(team)
146
+
147
+ # Create memberships for all new members
148
+ new_members.each do |member|
149
+ membership = Membership.new(
150
+ team: team,
151
+ user: member,
152
+ grant: 'team',
153
+ access_level: member == new_owner ? 'owner' : 'member'
154
+ )
155
+ batch.add(membership)
156
+ end
157
+
158
+ # Create a project for the team
159
+ project = Project.new(
160
+ name: "#{team.name} Project",
161
+ team: team,
162
+ owner: new_owner
163
+ )
164
+ batch.add(project)
165
+ end
166
+
167
+ puts "Complex operation completed successfully"
168
+ rescue Parse::Error => e
169
+ puts "Complex operation failed: #{e.message}"
170
+ raise # Re-raise to propagate error
171
+ end
172
+
173
+ # Example 4: Transaction with conflict retry
174
+ def increment_counters_with_retry(objects)
175
+ Parse::Object.transaction(retries: 10) do
176
+ objects.each do |obj|
177
+ obj.increment(:counter)
178
+ end
179
+ objects # Return objects to be saved
180
+ end
181
+ rescue Parse::Error => e
182
+ if e.message.include?("251")
183
+ puts "Transaction conflict after all retries"
184
+ else
185
+ puts "Transaction error: #{e.message}"
186
+ end
187
+ raise
188
+ end
189
+
190
+ # Main execution examples
191
+ if __FILE__ == $0
192
+ puts "Parse Transaction Examples"
193
+ puts "========================="
194
+
195
+ begin
196
+ # Example usage (requires actual Parse server and data)
197
+ # project = Project.first
198
+ # new_owner = Parse::User.first(username: "new_owner")
199
+ #
200
+ # if project && new_owner
201
+ # transfer_project_ownership_basic(project, new_owner)
202
+ # end
203
+
204
+ puts "\nTransaction support has been added to parse-stack!"
205
+ puts "\nKey features:"
206
+ puts "1. Atomic operations - all succeed or all fail"
207
+ puts "2. Automatic retry on transaction conflicts (error 251)"
208
+ puts "3. Two styles: explicit batch.add() or return array"
209
+ puts "4. Works with any Parse::Object subclass"
210
+ puts "\nUsage:"
211
+ puts " Parse::Object.transaction do |batch|"
212
+ puts " # Add operations to batch"
213
+ puts " end"
214
+
215
+ rescue => e
216
+ puts "Error: #{e.message}"
217
+ puts e.backtrace
218
+ end
219
+ end