parse-stack-next 5.0.1 → 5.1.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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.yml +105 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yml +67 -0
- data/.github/dependabot.yml +13 -0
- data/.github/workflows/codeql.yml +1 -1
- data/.github/workflows/docs.yml +3 -3
- data/.github/workflows/release.yml +14 -3
- data/.github/workflows/ruby.yml +1 -1
- data/.gitignore +1 -0
- data/.yardopts +19 -0
- data/CHANGELOG.md +792 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +8 -5
- data/README.md +15 -0
- data/Rakefile +5 -1
- data/docs/acl_clp_guide.md +553 -0
- data/docs/atlas_vector_search_guide.md +123 -22
- data/docs/client_sdk_guide.md +201 -5
- data/docs/usage_guide.md +21 -0
- data/docs/yard-template/default/fulldoc/html/css/common.css +1222 -0
- data/docs/yard-template/default/fulldoc/html/css/full_list.css +387 -0
- data/lib/parse/agent/tools.rb +153 -1
- data/lib/parse/cache/redis.rb +53 -0
- data/lib/parse/client/caching.rb +18 -1
- data/lib/parse/client.rb +79 -12
- data/lib/parse/embeddings/cohere.rb +143 -6
- data/lib/parse/embeddings/provider.rb +20 -2
- data/lib/parse/embeddings/voyage.rb +102 -0
- data/lib/parse/embeddings.rb +332 -1
- data/lib/parse/live_query/client.rb +167 -4
- data/lib/parse/live_query/configuration.rb +12 -0
- data/lib/parse/live_query/subscription.rb +55 -2
- data/lib/parse/live_query.rb +123 -1
- data/lib/parse/lock.rb +342 -0
- data/lib/parse/lock_backend.rb +308 -0
- data/lib/parse/model/classes/audience.rb +5 -0
- data/lib/parse/model/classes/installation.rb +122 -0
- data/lib/parse/model/classes/job_schedule.rb +3 -1
- data/lib/parse/model/classes/job_status.rb +4 -1
- data/lib/parse/model/classes/push_status.rb +4 -1
- data/lib/parse/model/classes/session.rb +7 -0
- data/lib/parse/model/classes/user.rb +204 -0
- data/lib/parse/model/core/create_lock.rb +28 -146
- data/lib/parse/model/core/embed_managed.rb +162 -13
- data/lib/parse/model/core/parse_reference.rb +17 -1
- data/lib/parse/model/core/querying.rb +26 -2
- data/lib/parse/model/file.rb +523 -18
- data/lib/parse/query.rb +31 -1
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/stack.rb +98 -1
- data/parse-stack-next.gemspec +2 -2
- metadata +17 -7
data/lib/parse/query.rb
CHANGED
|
@@ -2966,9 +2966,26 @@ module Parse
|
|
|
2966
2966
|
# @param fields [Array<String>] specific fields to watch for changes (nil = all fields)
|
|
2967
2967
|
# @param session_token [String] session token for ACL-aware subscriptions
|
|
2968
2968
|
# @param client [Parse::LiveQuery::Client] custom LiveQuery client (optional)
|
|
2969
|
+
# @param use_master_key [Boolean] an intent assertion, NOT a
|
|
2970
|
+
# per-subscription elevation. Parse Server resolves `masterKey`
|
|
2971
|
+
# once, at connect time, from the LiveQuery connect frame; the
|
|
2972
|
+
# subscribe frame never carries it. This flag therefore only has
|
|
2973
|
+
# effect when the underlying client is itself an admin connection
|
|
2974
|
+
# (`Parse::LiveQuery::Client.new(use_master_key: true)` with a
|
|
2975
|
+
# master key), in which case the entire socket is already elevated
|
|
2976
|
+
# and ALL its subscriptions bypass ACL/CLP. On a non-admin
|
|
2977
|
+
# connection `use_master_key: true` does not elevate the
|
|
2978
|
+
# subscription and emits a security warning. A single socket cannot
|
|
2979
|
+
# mix scoped and admin subscriptions — use separate connections for
|
|
2980
|
+
# end-user (session-token-scoped) versus administrative
|
|
2981
|
+
# (master-key-scoped) work.
|
|
2982
|
+
# @yield [subscription] runs the block with the freshly-constructed
|
|
2983
|
+
# {Parse::LiveQuery::Subscription} BEFORE the subscribe frame is
|
|
2984
|
+
# sent so caller-registered callbacks are wired before any server
|
|
2985
|
+
# events can arrive. Optional.
|
|
2969
2986
|
# @return [Parse::LiveQuery::Subscription] the subscription object
|
|
2970
2987
|
# @see Parse::LiveQuery::Subscription
|
|
2971
|
-
def subscribe(fields: nil, session_token: nil, client: nil)
|
|
2988
|
+
def subscribe(fields: nil, session_token: nil, client: nil, use_master_key: false, &block)
|
|
2972
2989
|
require_relative "live_query"
|
|
2973
2990
|
|
|
2974
2991
|
lq_client = client || Parse::LiveQuery.client
|
|
@@ -2977,6 +2994,8 @@ module Parse
|
|
|
2977
2994
|
where: compile_where,
|
|
2978
2995
|
fields: fields,
|
|
2979
2996
|
session_token: session_token || @session_token,
|
|
2997
|
+
use_master_key: use_master_key,
|
|
2998
|
+
&block
|
|
2980
2999
|
)
|
|
2981
3000
|
end
|
|
2982
3001
|
|
|
@@ -5420,6 +5439,17 @@ module Parse
|
|
|
5420
5439
|
# Helper class for executing arbitrary MongoDB aggregation pipelines.
|
|
5421
5440
|
# Provides a consistent interface with results, raw, and result_pointers methods.
|
|
5422
5441
|
class Aggregation
|
|
5442
|
+
# @return [Array<Hash>] the MongoDB aggregation pipeline stages this
|
|
5443
|
+
# Aggregation will execute. Useful for previewing the routed pipeline
|
|
5444
|
+
# before {#execute!}, for snapshot-based regression tests, and for
|
|
5445
|
+
# debugging the REST-vs-mongo-direct translation.
|
|
5446
|
+
attr_reader :pipeline
|
|
5447
|
+
|
|
5448
|
+
# @return [Boolean] whether {#execute!} will route through
|
|
5449
|
+
# {Parse::MongoDB.aggregate} instead of Parse Server's REST
|
|
5450
|
+
# `/aggregate` endpoint.
|
|
5451
|
+
attr_reader :mongo_direct
|
|
5452
|
+
|
|
5423
5453
|
# @param query [Parse::Query] the base query object
|
|
5424
5454
|
# @param pipeline [Array<Hash>] the MongoDB aggregation pipeline stages
|
|
5425
5455
|
# @param verbose [Boolean, nil] whether to print verbose output (nil means use query's setting)
|
data/lib/parse/stack/version.rb
CHANGED
data/lib/parse/stack.rb
CHANGED
|
@@ -154,6 +154,81 @@ module Parse
|
|
|
154
154
|
Fiber[SESSION_TOKEN_STATE_KEY]
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
+
# @!visibility private
|
|
158
|
+
CACHE_TENANT_STATE_KEY = :__parse_cache_tenant__
|
|
159
|
+
|
|
160
|
+
# Set an ambient cache-tenant scope for the duration of the block.
|
|
161
|
+
# When set, the {Parse::Middleware::Caching} middleware composes the
|
|
162
|
+
# tenant into the cache key as `<base-namespace>:T:<tenant>:…` so a
|
|
163
|
+
# multi-tenant Parse application can share one Redis (or any Moneta-
|
|
164
|
+
# backed cache) without per-tenant configuration plumbing through
|
|
165
|
+
# every `Parse::Client.new` site. Tenants do not see each other's
|
|
166
|
+
# cached responses; a SCAN-delete over `<base-namespace>:T:<tenant>:*`
|
|
167
|
+
# evicts exactly one tenant cleanly.
|
|
168
|
+
#
|
|
169
|
+
# This is purely a key namespacing mechanism — it does NOT enforce
|
|
170
|
+
# any access-control semantics. Tenant isolation at the data layer
|
|
171
|
+
# is the job of `agent_tenant_scope` (per-class scoping) and ACL/CLP.
|
|
172
|
+
# The tenant cache scope's role is to keep tenant A's session-token-
|
|
173
|
+
# keyed cache entry from being served on tenant B's request even
|
|
174
|
+
# when the URL and session token happen to collide.
|
|
175
|
+
#
|
|
176
|
+
# Fiber-local — composes safely with `async` and concurrent web
|
|
177
|
+
# frameworks. The scope is per-fiber, not per-thread, and is
|
|
178
|
+
# restored on block exit even if the block raises.
|
|
179
|
+
#
|
|
180
|
+
# @example wrap an agent invocation under a tenant
|
|
181
|
+
# Parse.with_cache_tenant("tenant_abc") do
|
|
182
|
+
# agent.run(prompt) # every Parse request issued inside the
|
|
183
|
+
# # block writes/reads tenant-scoped cache
|
|
184
|
+
# # entries
|
|
185
|
+
# end
|
|
186
|
+
#
|
|
187
|
+
# @example compose with `with_session`
|
|
188
|
+
# Parse.with_cache_tenant(tenant_id) do
|
|
189
|
+
# Parse.with_session(user) do
|
|
190
|
+
# Post.all
|
|
191
|
+
# end
|
|
192
|
+
# end
|
|
193
|
+
#
|
|
194
|
+
# @param scope [String, Symbol, nil] tenant identifier. `nil` clears
|
|
195
|
+
# the ambient scope for the duration of the block (useful to opt
|
|
196
|
+
# out within a larger tenant-scoped section). Must be ASCII
|
|
197
|
+
# `[A-Za-z0-9_-]+` — colon and other key-segment-delimiter chars
|
|
198
|
+
# are refused with `ArgumentError`, since the middleware composes
|
|
199
|
+
# the tenant into the cache key as `T:<tenant>:…` and a tenant
|
|
200
|
+
# containing `:` would collapse the segmentation (e.g.
|
|
201
|
+
# `with_cache_tenant("a:T:b")` would produce keys
|
|
202
|
+
# indistinguishable from `with_cache_tenant("a")` nested under
|
|
203
|
+
# `with_cache_tenant("b")`, breaking SCAN-delete isolation).
|
|
204
|
+
# @yield runs the block with the ambient tenant scope in place
|
|
205
|
+
# @return [Object] the block's return value
|
|
206
|
+
# @raise [ArgumentError] when `scope` contains characters outside
|
|
207
|
+
# `[A-Za-z0-9_-]` or exceeds 256 bytes.
|
|
208
|
+
CACHE_TENANT_PATTERN = /\A[A-Za-z0-9_\-]{1,256}\z/.freeze
|
|
209
|
+
def self.with_cache_tenant(scope)
|
|
210
|
+
resolved = scope.nil? ? nil : scope.to_s
|
|
211
|
+
resolved = nil if resolved&.empty?
|
|
212
|
+
if resolved && !CACHE_TENANT_PATTERN.match?(resolved)
|
|
213
|
+
raise ArgumentError,
|
|
214
|
+
"Parse.with_cache_tenant scope must match #{CACHE_TENANT_PATTERN.source} " \
|
|
215
|
+
"(got #{scope.inspect}). Colon and other key-segment-delimiter characters " \
|
|
216
|
+
"are refused — they would collapse the cache-key namespace boundary."
|
|
217
|
+
end
|
|
218
|
+
previous = Fiber[CACHE_TENANT_STATE_KEY]
|
|
219
|
+
Fiber[CACHE_TENANT_STATE_KEY] = resolved
|
|
220
|
+
yield
|
|
221
|
+
ensure
|
|
222
|
+
Fiber[CACHE_TENANT_STATE_KEY] = previous
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# The ambient cache-tenant scope set by {.with_cache_tenant} for the
|
|
226
|
+
# current fiber, or `nil` when not inside such a block.
|
|
227
|
+
# @return [String, nil]
|
|
228
|
+
def self.current_cache_tenant
|
|
229
|
+
Fiber[CACHE_TENANT_STATE_KEY]
|
|
230
|
+
end
|
|
231
|
+
|
|
157
232
|
# The {Parse::User} cached alongside the ambient session set by
|
|
158
233
|
# {.login}, or `nil` when no imperative login is active. Block-scoped
|
|
159
234
|
# `{Parse.with_session}` does NOT populate this — only {.login} does.
|
|
@@ -336,9 +411,31 @@ module Parse
|
|
|
336
411
|
# so the network-egress surface (an outbound WebSocket to the LiveQuery
|
|
337
412
|
# server) is opened only when the operator explicitly turns it on, not
|
|
338
413
|
# as a side effect of requiring the file.
|
|
414
|
+
#
|
|
415
|
+
# The LiveQuery module is autoloaded — `Parse::LiveQuery.configure { … }`
|
|
416
|
+
# works without an explicit `require 'parse/live_query'`. The autoload
|
|
417
|
+
# is purely a file-loading convenience; it does NOT open a network
|
|
418
|
+
# connection. A connection only opens when `Parse.live_query_enabled = true`
|
|
419
|
+
# AND a `Parse::LiveQuery::Client` is instantiated (typically via
|
|
420
|
+
# `Klass.subscribe { … }` or `Parse::Client.new(live_query_url: …)`).
|
|
421
|
+
#
|
|
339
422
|
# @example Enable LiveQuery
|
|
340
423
|
# Parse.live_query_enabled = true
|
|
341
|
-
# require
|
|
424
|
+
# # Parse::LiveQuery is autoloaded — no explicit require needed
|
|
425
|
+
# Parse::LiveQuery.configure do |c|
|
|
426
|
+
# c.url = "wss://parse.example.com"
|
|
427
|
+
# end
|
|
428
|
+
autoload :LiveQuery, "parse/live_query"
|
|
429
|
+
|
|
430
|
+
# Public mutual-exclusion primitive (TTL-bounded, Redis-backed with
|
|
431
|
+
# in-process Mutex fallback). See {Parse::Lock}.
|
|
432
|
+
autoload :Lock, "parse/lock"
|
|
433
|
+
|
|
434
|
+
# Shared low-level lock primitives consumed by both {Parse::Lock}
|
|
435
|
+
# and {Parse::CreateLock}. `@api private` — application code should
|
|
436
|
+
# use {Parse::Lock.acquire}.
|
|
437
|
+
autoload :LockBackend, "parse/lock_backend"
|
|
438
|
+
|
|
342
439
|
@live_query_enabled = false
|
|
343
440
|
|
|
344
441
|
# Configuration for cache write-through on fetch operations.
|
data/parse-stack-next.gemspec
CHANGED
|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.authors = ["Anthony Persaud", "Henry Spindell", "Adrian Curtin"]
|
|
10
10
|
spec.email = ["adrian+parse-stack@neurosynq.net"]
|
|
11
11
|
|
|
12
|
-
spec.summary = %q{Parse Server Ruby
|
|
13
|
-
spec.description = %q{
|
|
12
|
+
spec.summary = %q{Parse Server SDK for Ruby — ORM, queries, auth, and MongoDB-direct access}
|
|
13
|
+
spec.description = %q{Production-grade Ruby client for Parse Server. Map Parse classes to Ruby models with typed properties, associations, and validations; build queries with a chainable DataMapper-style DSL; handle auth, sessions, MFA, cloud code webhooks, and push; introspect and migrate schemas; manage role hierarchies; scope access with per-agent ACL/CLP; generate GraphQL types; run Atlas Search and vector search; and bypass REST for high-throughput reads via the MongoDB-direct pipeline.}
|
|
14
14
|
spec.homepage = "https://github.com/neurosynq/parse-stack-next"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: parse-stack-next
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.0
|
|
4
|
+
version: 5.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anthony Persaud
|
|
@@ -195,11 +195,12 @@ dependencies:
|
|
|
195
195
|
- - "~>"
|
|
196
196
|
- !ruby/object:Gem::Version
|
|
197
197
|
version: '2.0'
|
|
198
|
-
description:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
description: Production-grade Ruby client for Parse Server. Map Parse classes to Ruby
|
|
199
|
+
models with typed properties, associations, and validations; build queries with
|
|
200
|
+
a chainable DataMapper-style DSL; handle auth, sessions, MFA, cloud code webhooks,
|
|
201
|
+
and push; introspect and migrate schemas; manage role hierarchies; scope access
|
|
202
|
+
with per-agent ACL/CLP; generate GraphQL types; run Atlas Search and vector search;
|
|
203
|
+
and bypass REST for high-throughput reads via the MongoDB-direct pipeline.
|
|
203
204
|
email:
|
|
204
205
|
- adrian+parse-stack@neurosynq.net
|
|
205
206
|
executables:
|
|
@@ -210,6 +211,9 @@ files:
|
|
|
210
211
|
- ".bundle/config"
|
|
211
212
|
- ".env.sample"
|
|
212
213
|
- ".env.test"
|
|
214
|
+
- ".github/ISSUE_TEMPLATE/bug_report.yml"
|
|
215
|
+
- ".github/ISSUE_TEMPLATE/feature_request.yml"
|
|
216
|
+
- ".github/dependabot.yml"
|
|
213
217
|
- ".github/workflows/codeql.yml"
|
|
214
218
|
- ".github/workflows/docs.yml"
|
|
215
219
|
- ".github/workflows/release.yml"
|
|
@@ -218,6 +222,7 @@ files:
|
|
|
218
222
|
- ".ruby-version"
|
|
219
223
|
- ".solargraph.yml"
|
|
220
224
|
- ".vscode/settings.json"
|
|
225
|
+
- ".yardopts"
|
|
221
226
|
- CHANGELOG.md
|
|
222
227
|
- Gemfile
|
|
223
228
|
- Gemfile.lock
|
|
@@ -238,12 +243,15 @@ files:
|
|
|
238
243
|
- config/parse-config.json
|
|
239
244
|
- docs/TEST_SERVER.md
|
|
240
245
|
- docs/_config.yml
|
|
246
|
+
- docs/acl_clp_guide.md
|
|
241
247
|
- docs/atlas_vector_search_guide.md
|
|
242
248
|
- docs/client_sdk_guide.md
|
|
243
249
|
- docs/mcp_guide.md
|
|
244
250
|
- docs/mongodb_direct_guide.md
|
|
245
251
|
- docs/mongodb_index_optimization_guide.md
|
|
246
252
|
- docs/usage_guide.md
|
|
253
|
+
- docs/yard-template/default/fulldoc/html/css/common.css
|
|
254
|
+
- docs/yard-template/default/fulldoc/html/css/full_list.css
|
|
247
255
|
- examples/transaction_example.rb
|
|
248
256
|
- lib/parse-stack-next.rb
|
|
249
257
|
- lib/parse-stack.rb
|
|
@@ -321,6 +329,8 @@ files:
|
|
|
321
329
|
- lib/parse/live_query/health_monitor.rb
|
|
322
330
|
- lib/parse/live_query/logging.rb
|
|
323
331
|
- lib/parse/live_query/subscription.rb
|
|
332
|
+
- lib/parse/lock.rb
|
|
333
|
+
- lib/parse/lock_backend.rb
|
|
324
334
|
- lib/parse/lookup_rewriter.rb
|
|
325
335
|
- lib/parse/model/acl.rb
|
|
326
336
|
- lib/parse/model/associations/belongs_to.rb
|
|
@@ -445,5 +455,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
445
455
|
requirements: []
|
|
446
456
|
rubygems_version: 3.6.9
|
|
447
457
|
specification_version: 4
|
|
448
|
-
summary: Parse Server Ruby
|
|
458
|
+
summary: Parse Server SDK for Ruby — ORM, queries, auth, and MongoDB-direct access
|
|
449
459
|
test_files: []
|