wefunder 0.1.0.beta3 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3ac10a62a698ee6cb163f3ec6e100248d461dc6c55bf97caeb1bac349b44af6
4
- data.tar.gz: 26d0e08433a88d288942da627f8d509ffa196e6e2ed3cc347bae43beadaf84bf
3
+ metadata.gz: f82d3280df8bafaa7518ab69f7af96d3bdfb1a2e253b6b6fb22794f65d40c701
4
+ data.tar.gz: ff14e7f509d6868ed74b89beefd709cc7b9f30d84a5fdb54a7490193babfa8e5
5
5
  SHA512:
6
- metadata.gz: 4ee97ef8052e3e7a9476a8b0243b52a706bfd2c6a5911e1b9362c07e5d5d6290529615ed6daace3d953769d126a492440692ebef5191cd7846c418a70f6a54b5
7
- data.tar.gz: 535800baceafa25b8fcb744d2a1fc16a0596e14d80db5fba6f0c83772ee371c16a361335f82819b5a5e664bf016d17b008d3ff46a3f07f527eab491d8aa36bdd
6
+ metadata.gz: 669cdc32cae0a4218a827efdc5418d8060fc6667b6c7b7c1ecef0405c232eaa37935e32ec6970b233ccc8e43e4638d447fcc7fec2eb61e9d8e53d9732972a941
7
+ data.tar.gz: 708b4b330bf19f2ab9af55369576ac2a30e7ca7a1a9a7d989a5ee353869f46ca0162c2f7271e801650c601d64a0a2d2b21d85a8eeb76c8798c840d06e2755eba
data/README.md CHANGED
@@ -17,12 +17,12 @@ Requires Ruby 3.2+.
17
17
  ## Install
18
18
 
19
19
  ```bash
20
- gem install wefunder --pre
20
+ gem install wefunder
21
21
  # or in a Gemfile:
22
- gem "wefunder", "~> 0.1.0.beta"
22
+ gem "wefunder", "~> 1.0"
23
23
  ```
24
24
 
25
- `--pre` is needed while the SDK is in beta (pre-release gems are not selected by default).
25
+ The SDK follows semantic versioning from `1.0.0`: breaking changes only in a new major version, announced in the changelog.
26
26
 
27
27
  ## Authentication
28
28
 
@@ -103,8 +103,12 @@ portfolio = wf.portfolio.get
103
103
  ```
104
104
 
105
105
  Namespaces: `users`, `offerings`, `investments`, `portfolio`, `campaigns`, `syndicates`, `intents`,
106
- `attribution`, and `webhook_endpoints`. Query parameters are keyword arguments; enum-typed ones take
107
- plain strings, and `Time` / `DateTime` / `Date` values are sent as ISO 8601.
106
+ `attribution`, `installations`, and `webhook_endpoints`. Query parameters are keyword arguments;
107
+ enum-typed ones take plain strings, and `Time` / `DateTime` / `Date` values are sent as ISO 8601.
108
+
109
+ `wf.installations` lets your app act as a company or syndicate: `eligible_targets`, `create`,
110
+ `mint_token`, `list`, `get`, `revoke`, and `install_or_mint_token`, which handles the API's 409
111
+ `already_installed` answer by minting a token for the existing install with the same scopes.
108
112
 
109
113
  `wf.investments` is the Investment Delta API. `list` without a cursor bootstraps; pass `updated_since:`
110
114
  or the `meta.next_cursor` you saved from your last page to receive only records that changed since then.
@@ -26,7 +26,7 @@ module Wefunder
26
26
  # typed-error unwrapping, and lazy auto-pagination. +raw+ exposes every generated API.
27
27
  class Client
28
28
  attr_reader :mode, :users, :offerings, :investments, :portfolio, :campaigns, :syndicates, :intents,
29
- :attribution, :webhook_endpoints
29
+ :attribution, :installations, :webhook_endpoints
30
30
 
31
31
  def initialize(access_token: nil, tokens: nil, client_id: nil, client_secret: nil, client_credentials: nil,
32
32
  api_version: DEFAULT_API_VERSION, base_url: DEFAULT_API_BASE_URL, authorize_base_url: nil,
@@ -53,6 +53,7 @@ module Wefunder
53
53
  @syndicates = Syndicates.new(self)
54
54
  @intents = Intents.new(self)
55
55
  @attribution = Attribution.new(self)
56
+ @installations = Installations.new(self)
56
57
  @webhook_endpoints = WebhookEndpoints.new(self)
57
58
  end
58
59
 
@@ -275,6 +276,58 @@ module Wefunder
275
276
  def me = data_of(wrap { raw.attribution_partners.get_attribution_me })
276
277
  end
277
278
 
279
+ # /installations (read:installations / write:installations; write does not imply read). An
280
+ # install lets your app act AS a company or syndicate: +create+ and +mint_token+ return the
281
+ # envelope whose +token.access_token+ is a company-owned token (shown once, no expiry, no
282
+ # refresh) — build a second client with it. Installing is also what makes a company or
283
+ # syndicate an audience for your webhooks.
284
+ class Installations < Namespace
285
+ # Companies / syndicates the token's user may install your app on (empty for an investor).
286
+ def eligible_targets(target_type: nil)
287
+ opts = target_type ? { target_type: target_type } : {}
288
+ data_of(wrap { raw.installations.list_eligible_install_targets(opts) }) || []
289
+ end
290
+
291
+ # Every install of your app; the envelope (+meta.count+).
292
+ def list = wrap { raw.installations.list_installations }
293
+ def get(installation_id) = data_of(wrap { raw.installations.get_installation(installation_id) })
294
+
295
+ # Install on a target (+target_type:+, +target_id:+, optional +scopes:+ / +tier:+). Returns the
296
+ # envelope: +data+ is the install, +token.access_token+ the one-time token. If the app is
297
+ # already installed there the API answers 409 +already_installed+ with
298
+ # +details["installation"]+ = the existing id; see +install_or_mint_token+.
299
+ def create(**attrs)
300
+ attrs = attrs.transform_keys(&:to_sym)
301
+ wrap { raw.installations.create_installation(WefunderGenerated::CreateInstallationRequest.new(attrs)) }
302
+ end
303
+
304
+ # A fresh company-owned token for an existing install. +scopes+ narrows within the install's
305
+ # ceiling; omit for the ceiling. An explicit +[]+ grants nothing, so only nil omits the body.
306
+ def mint_token(installation_id, scopes = nil)
307
+ opts = {}
308
+ opts[:create_installation_token_request] = WefunderGenerated::CreateInstallationTokenRequest.new(scopes: scopes) if scopes
309
+ wrap { raw.installations.create_installation_token(installation_id, opts) }
310
+ end
311
+
312
+ # +create+, falling back to +mint_token+ for the existing install on 409 +already_installed+.
313
+ # The mint re-requests +scopes+ so a retry never widens the grant. Any other error (revoked
314
+ # install, missing scope) still raises.
315
+ def install_or_mint_token(**attrs)
316
+ # Normalize once so the fallback re-requests exactly what create sent — string-keyed
317
+ # attrs (e.g. from JSON.parse) must not turn a restricted or empty grant into the ceiling.
318
+ attrs = attrs.transform_keys(&:to_sym)
319
+ create(**attrs)
320
+ rescue Wefunder::Error => e
321
+ existing_id = e.details["installation"] if e.type == "already_installed" && e.details.is_a?(Hash)
322
+ raise unless existing_id.is_a?(String) && !existing_id.empty?
323
+
324
+ mint_token(existing_id, attrs[:scopes])
325
+ end
326
+
327
+ # Revoke an install: its tokens stop working at once. Returns the install, now +revoked+.
328
+ def revoke(installation_id) = data_of(wrap { raw.installations.revoke_installation(installation_id) })
329
+ end
330
+
278
331
  # Endpoints belong to your application and are managed through the LIVE API
279
332
  # (write:webhooks). The signing secret is returned only on create and rotate.
280
333
  class WebhookEndpoints < Namespace
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wefunder
4
- VERSION = "0.1.0.beta3"
4
+ VERSION = "1.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wefunder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wefunder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-02 00:00:00.000000000 Z
11
+ date: 2026-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -452,5 +452,5 @@ requirements: []
452
452
  rubygems_version: 3.5.22
453
453
  signing_key:
454
454
  specification_version: 4
455
- summary: Official Ruby SDK for the Wefunder API (beta)
455
+ summary: Official Ruby SDK for the Wefunder API
456
456
  test_files: []