fortnox-api 1.0.0.rc5 → 1.0.0.rc7

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: 5d9ec48a070723310f19f5c87fa23c64e3c92c0e3a04d9e000a6390f0d6e2f65
4
- data.tar.gz: 7b95b905d0d908bee63b1130cede763d7a0697de0ef8d008e92b710580457674
3
+ metadata.gz: 1572886bdede9cde4d2de4970160e66e53b83f2dbd19f7cd5ab6165fe28a3c6b
4
+ data.tar.gz: f76deefb58d635d1fc1a0583fa96a398d47131fbdb9eb5b9e5454281eeac4686
5
5
  SHA512:
6
- metadata.gz: fc85ca3a86615ab6d329091fcdf1ec565d03325bf2b98776602e32fa74e9c440081f9e8f37c4ee4baf759cdcdd29e339c0abe0eeaae777abe52ef162e382eced
7
- data.tar.gz: 5b01d27ef5d0d7d61961378ada0ed97356c8e2f17412bc191b711c902cda18c754058bafd86ec3409bec895da890fdda425ca6274a097c51061835eb2ede4889
6
+ metadata.gz: a99b87e8f1d3ef0370b3258000c4a6fe65561305338a9c1d52590faacd0ecd851e6423973c8043857a3b9aadeb750c703e51cdda3362303dda628e953ecfd521
7
+ data.tar.gz: baa027a8995db227621be745ca00856c84d60f93f6772e21ca0f3c5666c94a96d0b85c992a3682b6688054eab68c4aca383936fc866e3d71057851a338617990
data/CHANGELOG.md CHANGED
@@ -6,6 +6,42 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to
7
7
  [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [Unreleased]
10
+
11
+ ## [1.0.0.rc7] - 2026-05-19
12
+
13
+ ### Changed
14
+
15
+ - **Breaking** Minimum Ruby version raised to 3.2. Ruby 3.1 reached
16
+ end-of-life in March 2025 and is no longer supported or tested.
17
+ - Upgraded `rest-easy` dependency to `~> 1.3.0`.
18
+
19
+ ### Fixed
20
+
21
+ - Declare `base64` as a runtime dependency. It is `require`d by the gem
22
+ and used for OAuth credential encoding, but `base64` was removed from
23
+ Ruby's default gems in 3.4, so the gem failed to load on Ruby 3.4 with
24
+ `LoadError: cannot load such file -- base64`.
25
+ - Saving a persisted record with no changes is again a no-op, matching
26
+ 0.9. In that version `save` returned early for an unchanged persisted record
27
+ without issuing a request. The 1.0.0.rc1 rest-easy rewrite regressed
28
+ this: `save` on a record fetched via `find` re-sent every attribute
29
+ via a full-record `PUT`, which could clobber fields changed elsewhere
30
+ since it was loaded.
31
+
32
+ ## [1.0.0.rc6] - 2026-05-18
33
+
34
+ ### Added
35
+
36
+ - HTTP wire logging via `Fortnox.configure { logger ... }`, with an
37
+ optional `log_bodies` toggle for request/response bodies. Standard
38
+ auth headers are redacted automatically. Inherited from `rest-easy`
39
+ 1.2.
40
+
41
+ ### Changed
42
+
43
+ - Upgraded `rest-easy` dependency to `~> 1.2.0`.
44
+
9
45
  ## [1.0.0.rc5] - 2026-05-15
10
46
 
11
47
  ### Changed
@@ -181,6 +217,10 @@ for the full list of breaking changes.
181
217
  For changes prior to the 1.0 rewrite, see the
182
218
  [0.x changelog](https://github.com/accodeing/fortnox-api/blob/v0.9.2/CHANGELOG.md).
183
219
 
220
+ [Unreleased]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc7...HEAD
221
+ [1.0.0.rc7]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc6...v1.0.0.rc7
222
+ [1.0.0.rc6]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc5...v1.0.0.rc6
223
+ [1.0.0.rc5]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc4...v1.0.0.rc5
184
224
  [1.0.0.rc4]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc3...v1.0.0.rc4
185
225
  [1.0.0.rc3]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc2...v1.0.0.rc3
186
226
  [1.0.0.rc2]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc1...v1.0.0.rc2
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # fortnox-api
2
2
 
3
+ [![CI](https://github.com/accodeing/fortnox-api/actions/workflows/ci.yml/badge.svg)](https://github.com/accodeing/fortnox-api/actions/workflows/ci.yml)
4
+
3
5
  Ruby gem for Fortnox's version 3 REST API, built on
4
6
  [rest-easy](https://github.com/accodeing/rest-easy). If you need to integrate an existing or new Ruby
5
7
  or Rails app against Fortnox this gem will save you a lot of time.
@@ -10,13 +12,13 @@ Feel free to repay the community with some nice PRs of your own.
10
12
 
11
13
  Article, Customer, Invoice, Label, Order, Project, TermsOfPayment, Unit
12
14
 
13
- Adding more resources is quick and easy, see the
14
- [Contributing](#contributing) section.
15
+ Adding more resources is quick and easy see the
16
+ [Developer readme](DEVELOPER_README.md).
15
17
 
16
18
  ## Status
17
19
 
18
20
  Version 1.0 is a complete rewrite, currently in release candidate
19
- (`1.0.0.rc5`). It is built on
21
+ (`1.0.0.rc7`). It is built on
20
22
  [rest-easy](https://github.com/accodeing/rest-easy), replacing the old
21
23
  HTTParty + Data Mapper architecture with a single resource class per entity.
22
24
  Authorization uses the Fortnox client credentials flow.
@@ -71,7 +73,17 @@ The gem raises the following exceptions:
71
73
  - `Fortnox::RequestError` — 4xx/5xx responses from the Fortnox API. The
72
74
  exception message includes the API's `ErrorInformation.Message` and code
73
75
  when present (Fortnox is inconsistent about the key casing — the gem
74
- normalises both). The full response is on `.response`.
76
+ normalises both). The full response is on `.response`, which exposes
77
+ the HTTP status code and body — match on `.status` rather than the
78
+ message text:
79
+
80
+ ```ruby
81
+ Fortnox::Customer.find(id)
82
+ rescue Fortnox::RequestError => e
83
+ return nil if e.response&.status == 404
84
+
85
+ raise
86
+ ```
75
87
  - `Fortnox::AttributeError` — base for attribute validation failures.
76
88
  - `Fortnox::ConstraintError` — an attribute value violates a type
77
89
  constraint (max size, format, etc.). Carries `.attribute_name` and
@@ -83,7 +95,7 @@ The gem raises the following exceptions:
83
95
 
84
96
  ## Requirements
85
97
 
86
- Ruby 3.1 or higher.
98
+ Ruby 3.2 or higher.
87
99
 
88
100
  ### Installation
89
101
 
@@ -308,6 +320,19 @@ updated = customer.update(name: 'Acme Inc')
308
320
  Fortnox::Customer.save(updated)
309
321
  ```
310
322
 
323
+ Updates are partial: only the attributes you pass to `.update` are sent to
324
+ Fortnox. Attributes you don't touch are left as-is on the record (so a
325
+ field changed elsewhere in the meantime is not clobbered). Note this is
326
+ based on *which* attributes you pass, not a value comparison — passing an
327
+ attribute equal to its stored value still sends it. Setting an attribute
328
+ to `nil` is sent as an explicit clear:
329
+
330
+ ```ruby
331
+ customer = Fortnox::Customer.find(1)
332
+ updated = customer.update(phone1: nil)
333
+ Fortnox::Customer.save(updated) # phone1 is now cleared in Fortnox
334
+ ```
335
+
311
336
  ### Searching
312
337
 
313
338
  ```ruby
@@ -322,6 +347,43 @@ Some resources support server-side filters:
322
347
  Fortnox::Invoice.only('unpaid')
323
348
  ```
324
349
 
350
+ ### Logging
351
+
352
+ Set a `Logger`-compatible instance on the gem-level config to log every
353
+ HTTP request and response. Faraday's built-in logger middleware is attached
354
+ only when this setting is non-nil — no overhead when unset:
355
+
356
+ ```ruby
357
+ require 'logger'
358
+
359
+ Fortnox.configure do
360
+ logger Logger.new($stdout)
361
+ end
362
+ ```
363
+
364
+ By default only request/response lines and headers are logged, with the
365
+ standard auth headers (`Authorization`, `Proxy-Authorization`, `Cookie`,
366
+ `Set-Cookie`) filtered to `[FILTERED]`. To also log bodies, opt in:
367
+
368
+ ```ruby
369
+ Fortnox.configure do
370
+ logger Logger.new($stdout)
371
+ log_bodies true
372
+ end
373
+ ```
374
+
375
+ The Faraday connection is built once on the first request and cached for
376
+ the life of the process, so changes to `logger` or `log_bodies` after that
377
+ take effect only on restart.
378
+
379
+ The `fortnox-setup` and `fortnox-update-env` executables talk directly to
380
+ the OAuth token endpoint and are not routed through this logger.
381
+
382
+ If you suspect the gem is silently dropping a field Fortnox added — or
383
+ hitting some other schema-drift issue — please open an issue. There's a
384
+ maintainer-only knob to surface those warnings; see the
385
+ [Developer readme](DEVELOPER_README.md) for details.
386
+
325
387
  ### Gotchas
326
388
 
327
389
  See [docs/gotchas.md](docs/gotchas.md) for known quirks and edge cases in the
data/fortnox.gemspec CHANGED
@@ -19,11 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = ['fortnox-setup', 'fortnox-update-env']
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.required_ruby_version = '>= 3.1.0'
22
+ spec.required_ruby_version = '>= 3.2.0'
23
23
 
24
+ spec.add_dependency 'base64'
24
25
  spec.add_dependency 'countries', '~> 7.1'
25
26
  spec.add_dependency 'dry-struct', '~> 1.5'
26
- spec.add_dependency 'rest-easy', '~> 1.1.2'
27
+ spec.add_dependency 'rest-easy', '~> 1.3.0'
27
28
 
28
29
  spec.metadata['rubygems_mfa_required'] = 'true'
29
30
  end
@@ -29,7 +29,9 @@ module Fortnox
29
29
  # Strip nils for new records — rely on Fortnox defaults
30
30
  data = data.compact
31
31
  elsif __changes__.any?
32
- # Only send changed attributes on update, preserving explicit nils
32
+ # Send only the attributes passed to .update field-level dirty
33
+ # tracking, not a value diff, so an attribute equal to its stored
34
+ # value is still sent, and an explicit nil reaches Fortnox as a clear.
33
35
  changed_api_names = __changes__.keys.filter_map do |model_name|
34
36
  self.class.all_attribute_definitions[model_name]&.api_name
35
37
  end
@@ -61,6 +63,12 @@ module Fortnox
61
63
  end
62
64
 
63
65
  def save(instance)
66
+ # A persisted record with no recorded changes has nothing to write.
67
+ # Without this short-circuit rest-easy would PUT the entire record
68
+ # back, re-sending every untouched attribute and risking clobbering
69
+ # changes made elsewhere since it was loaded.
70
+ return instance if !instance.meta.new? && instance.__changes__.empty?
71
+
64
72
  with_translated_errors { super }
65
73
  end
66
74
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fortnox
4
- VERSION = '1.0.0.rc5'
4
+ VERSION = '1.0.0.rc7'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fortnox-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc5
4
+ version: 1.0.0.rc7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Schubert Erlandsson
@@ -11,8 +11,22 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2026-05-15 00:00:00.000000000 Z
14
+ date: 2026-05-19 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: base64
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
16
30
  - !ruby/object:Gem::Dependency
17
31
  name: countries
18
32
  requirement: !ruby/object:Gem::Requirement
@@ -47,14 +61,14 @@ dependencies:
47
61
  requirements:
48
62
  - - "~>"
49
63
  - !ruby/object:Gem::Version
50
- version: 1.1.2
64
+ version: 1.3.0
51
65
  type: :runtime
52
66
  prerelease: false
53
67
  version_requirements: !ruby/object:Gem::Requirement
54
68
  requirements:
55
69
  - - "~>"
56
70
  - !ruby/object:Gem::Version
57
- version: 1.1.2
71
+ version: 1.3.0
58
72
  description: Fortnox F3 REST API library, based on rest-easy.
59
73
  email:
60
74
  - info@accodeing.com
@@ -116,14 +130,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
130
  requirements:
117
131
  - - ">="
118
132
  - !ruby/object:Gem::Version
119
- version: 3.1.0
133
+ version: 3.2.0
120
134
  required_rubygems_version: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - ">"
123
137
  - !ruby/object:Gem::Version
124
138
  version: 1.3.1
125
139
  requirements: []
126
- rubygems_version: 3.4.6
140
+ rubygems_version: 3.4.19
127
141
  signing_key:
128
142
  specification_version: 4
129
143
  summary: Fortnox F3 REST API library, based on rest-easy.