jscontact 0.1.0 → 0.2.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/CHANGELOG.md +5 -0
- data/README.md +43 -10
- data/SECURITY.md +7 -0
- data/lib/jscontact/vcard/to_jscontact.rb +12 -3
- data/lib/jscontact/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5d92a19bb9e19ed8bc57c8b3382cb2364f80e992109fc4f9bebc2abc1ec2729e
|
|
4
|
+
data.tar.gz: 83aea8cf6c39aa19696ca6b6085cf236f5f91c52efc59d829579abbef5c358d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c472a9ef316602575a4a82ca62410a1ffd4d782145ad0a29f86d6f7a647e0f7ddc71d86219c5877c8741220102210fe022480c3d3ee6f41c6bd37e858c87909
|
|
7
|
+
data.tar.gz: 18c076269b700e84346537cd6202c1c376920ba6bcec29ba673b4256b18b27be470975abe26451a68ca54a3c5898459e7879fdc1c708a6af57977f303ecce877
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 - 2026-10-12
|
|
4
|
+
|
|
5
|
+
- Preserve leap seconds when converting vCard timestamps to UTC.
|
|
6
|
+
- Retain timestamps without a UTC offset in vCard metadata instead of interpreting them in the system time zone.
|
|
7
|
+
|
|
3
8
|
## 0.1.0 - 2026-10-12
|
|
4
9
|
|
|
5
10
|
Initial release.
|
data/README.md
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">JSContact</h1>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">JSON contact cards with validation and vCard conversion.</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://rubygems.org/gems/jscontact"><img src="https://img.shields.io/gem/v/jscontact" alt="Gem version"></a>
|
|
7
|
+
<a href="https://github.com/ydah/jscontact/actions/workflows/main.yml"><img src="https://github.com/ydah/jscontact/actions/workflows/main.yml/badge.svg?branch=main" alt="CI"></a>
|
|
8
|
+
<a href="https://www.ruby-lang.org/"><img src="https://img.shields.io/badge/Ruby-%3E%3D%203.3-CC342D?logo=ruby&logoColor=white" alt="Ruby 3.3 or later"></a>
|
|
9
|
+
<a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="#installation">Installation</a> ·
|
|
14
|
+
<a href="#quick-start">Quick start</a> ·
|
|
15
|
+
<a href="#supported-scope">Supported scope</a> ·
|
|
16
|
+
<a href="#development">Development</a> ·
|
|
17
|
+
<a href="#license">License</a>
|
|
18
|
+
</p>
|
|
4
19
|
|
|
5
20
|
Parse, validate, build, and convert JSContact contact cards in Ruby. Supports
|
|
6
21
|
[RFC 9553](https://www.rfc-editor.org/rfc/rfc9553),
|
|
7
22
|
[RFC 9555](https://www.rfc-editor.org/rfc/rfc9555), and
|
|
8
23
|
[RFC 9982](https://www.rfc-editor.org/rfc/rfc9982).
|
|
9
24
|
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- Build typed JSContact 2.0 cards and read existing 1.0 cards.
|
|
28
|
+
- Apply patches and localizations while preserving vendor extensions.
|
|
29
|
+
- Convert vCard 4.0 through an optional jcard_jcal integration.
|
|
30
|
+
|
|
10
31
|
Unknown properties, vendor extensions, and map identifiers survive JSON round
|
|
11
32
|
trips. New cards use JSContact 2.0; reading a 1.0 card keeps its version until you
|
|
12
33
|
explicitly upgrade it.
|
|
@@ -15,16 +36,20 @@ explicitly upgrade it.
|
|
|
15
36
|
|
|
16
37
|
Requires Ruby 3.3 or later. CI also tests JRuby and TruffleRuby on Linux and macOS.
|
|
17
38
|
|
|
39
|
+
Add the gem to your Gemfile:
|
|
40
|
+
|
|
18
41
|
```ruby
|
|
19
42
|
gem "jscontact"
|
|
20
43
|
# Add only when using the optional vCard converter:
|
|
21
44
|
gem "jcard_jcal", "~> 0.1.0"
|
|
22
45
|
```
|
|
23
46
|
|
|
47
|
+
Then run `bundle install`.
|
|
48
|
+
|
|
24
49
|
The JSON API depends on `json` and `tzinfo`. On systems without a zoneinfo database
|
|
25
50
|
(such as Windows), also install `tzinfo-data` for time zone and country validation.
|
|
26
51
|
|
|
27
|
-
##
|
|
52
|
+
## Quick start
|
|
28
53
|
|
|
29
54
|
```ruby
|
|
30
55
|
require "jscontact"
|
|
@@ -124,6 +149,8 @@ vCard 4.0. A missing UID stays absent when converting to JSContact 2.0. Requesti
|
|
|
124
149
|
Conversion preserves data, rather than the original text's property order,
|
|
125
150
|
folding, or choice of equivalent representation. Date forms without a JSContact
|
|
126
151
|
equivalent and unmatched birth/death place properties are retained in `vCardProps`.
|
|
152
|
+
Timestamp conversion preserves leap seconds. Timestamps without a UTC offset
|
|
153
|
+
remain in `vCardProps` or `vCardParams`, since no UTC instant can be inferred.
|
|
127
154
|
|
|
128
155
|
JSContact date fields use the Gregorian calendar even when `calendarScale` names
|
|
129
156
|
another calendar. The converter preserves non-Gregorian vCard CALSCALE properties
|
|
@@ -177,9 +204,9 @@ vulnerabilities.
|
|
|
177
204
|
bundle install
|
|
178
205
|
bundle exec rake # fetch and verify external RFC inputs, then test
|
|
179
206
|
COVERAGE=1 bundle exec rake # minimum 90% line coverage
|
|
180
|
-
bundle exec rubocop
|
|
181
207
|
bundle exec rbs -I sig validate
|
|
182
|
-
bundle exec ruby script/
|
|
208
|
+
bundle exec ruby script/check_syntax.rb
|
|
209
|
+
bundle exec ruby script/check_licenses.rb
|
|
183
210
|
bundle exec ruby script/benchmark.rb # time, allocation and RSS measurements at limits
|
|
184
211
|
bundle exec ruby script/update_registry.rb # verify pinned IANA registry coverage
|
|
185
212
|
bundle exec ruby script/update_registry.rb --refresh # audit current IANA data and update pins
|
|
@@ -188,10 +215,10 @@ bundle exec ruby script/update_registry.rb --refresh # audit current IANA data a
|
|
|
188
215
|
The suite checks 97 generated RFC examples, both directions of 54 vCard conversion
|
|
189
216
|
pairs, malformed input, patches, limits, and deterministic random round trips.
|
|
190
217
|
See [conformance notes](docs/conformance.md) for extraction corrections, reported
|
|
191
|
-
errata, and the
|
|
218
|
+
errata, and the current comparison scope.
|
|
192
219
|
The [boundary measurements](docs/performance.md) explain the default limits.
|
|
193
220
|
|
|
194
|
-
RFC originals, extracted examples, IANA downloads
|
|
221
|
+
RFC originals, extracted examples, and IANA downloads
|
|
195
222
|
live only in ignored `tmp/` directories. Downloads retain their applicable notices;
|
|
196
223
|
RFC source hashes and the generated corpus fingerprint are checked before testing.
|
|
197
224
|
The packaged gem contains library code, original schema metadata, RBS, and user
|
|
@@ -205,8 +232,14 @@ the gem version and CHANGELOG, then push the matching `vVERSION` tag. The workfl
|
|
|
205
232
|
tests, builds, publishes through OIDC, and creates a GitHub release from that
|
|
206
233
|
version's CHANGELOG entry. A version already on RubyGems is not published again.
|
|
207
234
|
|
|
235
|
+
## Contributing
|
|
236
|
+
|
|
237
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/ydah/jscontact/issues). See [Development](#development) for the checks to run before submitting a change. Report security vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
|
|
238
|
+
|
|
208
239
|
## License
|
|
209
240
|
|
|
210
|
-
The Ruby library is available under the [MIT License](LICENSE.txt).
|
|
211
|
-
|
|
212
|
-
|
|
241
|
+
The Ruby library is available under the [MIT License](LICENSE.txt). Added runtime
|
|
242
|
+
and development libraries must offer MIT terms, including transitive dependencies;
|
|
243
|
+
Ruby runtimes, standard libraries, and bundled tools are explicit exceptions.
|
|
244
|
+
External RFC and registry test inputs retain their notices and are not included
|
|
245
|
+
in the gem. See [provenance and dependency review](docs/provenance.md).
|
data/SECURITY.md
CHANGED
|
@@ -4,3 +4,10 @@ Report vulnerabilities through [GitHub private vulnerability reporting](https://
|
|
|
4
4
|
Please include a minimal reproducer and the affected gem and Ruby versions.
|
|
5
5
|
|
|
6
6
|
The library treats documents as data. It does not retrieve contact URIs or execute embedded content.
|
|
7
|
+
|
|
8
|
+
Dependency policy: added runtime and development libraries, including transitive
|
|
9
|
+
dependencies, must offer MIT terms. Ruby runtimes, standard libraries, and bundled
|
|
10
|
+
tools are explicit exceptions. Externally downloaded RFC/registry test data retain
|
|
11
|
+
their own notices and stay outside the repository and gem package. Dependency
|
|
12
|
+
license review does not constitute a cryptographic or application security audit.
|
|
13
|
+
See [provenance and dependency review](docs/provenance.md) for the review scope.
|
|
@@ -130,6 +130,8 @@ module Jscontact
|
|
|
130
130
|
|
|
131
131
|
key = SCALARS.fetch(name)
|
|
132
132
|
converted = %w[created rev].include?(name) ? timestamp(value) : value
|
|
133
|
+
return preserve(prop) if converted.nil?
|
|
134
|
+
|
|
133
135
|
converted = converted.downcase if name == "kind"
|
|
134
136
|
converted = normalize_language(converted) if name == "language"
|
|
135
137
|
@card[key] = converted
|
|
@@ -215,10 +217,13 @@ module Jscontact
|
|
|
215
217
|
consumed << parameter
|
|
216
218
|
end
|
|
217
219
|
when "note"
|
|
218
|
-
|
|
220
|
+
if params["created"] && (created = timestamp(params["created"], compact: true))
|
|
221
|
+
object["created"] = created
|
|
222
|
+
consumed << "created"
|
|
223
|
+
end
|
|
219
224
|
author = { "name" => params["author-name"], "uri" => params["author"] }.compact
|
|
220
225
|
object["author"] = author unless author.empty?
|
|
221
|
-
consumed += %w[
|
|
226
|
+
consumed += %w[author author-name]
|
|
222
227
|
when "expertise", "hobby", "interest"
|
|
223
228
|
if params["level"]
|
|
224
229
|
level = params["level"].downcase
|
|
@@ -395,7 +400,11 @@ module Jscontact
|
|
|
395
400
|
|
|
396
401
|
def timestamp(value, compact: false)
|
|
397
402
|
value = JCardJCal::ValueTypes.from_text(value, "timestamp", format: :vcard) if compact
|
|
398
|
-
|
|
403
|
+
return unless value.match?(/(?:Z|[+-]\d{2}(?::\d{2})?)\z/)
|
|
404
|
+
|
|
405
|
+
# Convert the minute separately because Ruby Time normalizes leap seconds.
|
|
406
|
+
minute = Time.iso8601("#{value[0, 17]}00#{value[19..]}").utc
|
|
407
|
+
"#{minute.strftime("%Y-%m-%dT%H:%M:")}#{value[17, 2]}Z"
|
|
399
408
|
rescue ArgumentError
|
|
400
409
|
raise ConversionError, "invalid vCard timestamp"
|
|
401
410
|
end
|
data/lib/jscontact/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jscontact
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yudai Takada
|
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
rubygems_version:
|
|
101
|
+
rubygems_version: 3.6.9
|
|
102
102
|
specification_version: 4
|
|
103
103
|
summary: Read, validate, and convert JSContact contact cards
|
|
104
104
|
test_files: []
|