usps-imis-api 0.13.5 → 0.13.7

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: 6f533f6f1c46a836c57ed615db3e4ed3a960e1cf6e280d258cc59ee72bbe735d
4
- data.tar.gz: b2877c785c60738326dc96e7aa50da21eff214e21b961a30773dc2f0f843e195
3
+ metadata.gz: 0c08ef9fb00018afc5a5ff89f2504c1c3eb50966834323549a0d5b889bf62fc8
4
+ data.tar.gz: cb0eb88ff00dcff37318ae4db9d5eba37c82a1138aab77c257dd9c81455adb70
5
5
  SHA512:
6
- metadata.gz: 1c032d83d0b9c87de3d0e705e330e840cf159dc252837b54b138b5ee7a791d587b21630050b05427a59d81a5c2c605331b514dbed339634a199c2fc67f61b35c
7
- data.tar.gz: 6f6a335d752b0aacef359d5fb79a499e7f6224a9c884acc42730beb44ab595d4a88659545fb7ec8ae612d84c3ba16159cc568a8993a1101bbf7bca74bd399e48
6
+ metadata.gz: e828834ae003610f3c3e217763bc26602626cb840b69cd4590b1ebe07659cd960cc1988da5ac0551fcac9fcfc71e89ab1ffaf004831d69344b9ad8503b787e83
7
+ data.tar.gz: fc6eccef25f63c11fd8e997d99c6527da8a56a0cfdcd16034744d457c214a86a973262de5215d1979f8cee5581c7f130992c3b9e7abeea85687d2ad8ab200177
data/Readme.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # USPS iMIS API for Ruby
2
2
 
3
- [![Gem Version](https://img.shields.io/gem/v/usps-imis-api)](https://rubygems.org/gems/usps-imis-api)
3
+ [![Gem Version][gem-badge]](https://rubygems.org/gems/usps-imis-api)
4
+ [![iMIS API PHP Wrapper Version][php-badge]](https://github.com/unitedstatespowersquadrons/imis-api-php)
4
5
 
5
6
  ## Installation
6
7
 
@@ -29,7 +30,6 @@ Usps::Imis.configure do |config|
29
30
  config.environment = :development
30
31
 
31
32
  # These options will default to the listed `ENV` variable if available.
32
- config.imis_id_query_name = ENV['IMIS_ID_QUERY_NAME']
33
33
  config.username = ENV['IMIS_USERNAME']
34
34
  config.password = ENV['IMIS_PASSWORD']
35
35
 
@@ -83,7 +83,10 @@ file to [rubygems.org](https://rubygems.org).
83
83
 
84
84
  ## PHP
85
85
 
86
- A wrapper for the CLI from this API is
87
- [available for PHP](https://github.com/unitedstatespowersquadrons/imis-api-php).
86
+ A wrapper for the CLI from this API is [available for PHP][php-repo].
88
87
 
89
88
  You can also view the (***deprecated***) [original PHP API](https://github.com/unitedstatespowersquadrons/imis-api).
89
+
90
+ [gem-badge]: https://img.shields.io/gem/v/usps-imis-api?logo=rubygems&logoColor=white
91
+ [php-badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Fadmin.aws.usps.org%2Flibrary_badge%2Fimis-api-php&label=wrapper&logo=php&logoColor=white
92
+ [php-repo]: https://github.com/unitedstatespowersquadrons/imis-api-php
data/lib/usps/imis/api.rb CHANGED
@@ -11,6 +11,7 @@ module Usps
11
11
  #
12
12
  class Api
13
13
  include Requests
14
+ include Imis::Helpers
14
15
 
15
16
  NAME = 'USPS iMIS API - Ruby'
16
17
 
@@ -59,9 +60,13 @@ module Usps
59
60
  #
60
61
  # @param imis_id [Integer, String] iMIS ID to select immediately on initialization
61
62
  #
62
- def initialize(imis_id: nil, record_id: nil)
63
+ def initialize(imis_id: nil, record_id: nil, certificate: nil)
64
+ raise ArgumentError, 'Cannot provide both imis_id and certificate' if imis_id && certificate
65
+
63
66
  self.imis_id = imis_id if imis_id
64
67
  self.record_id = record_id if record_id
68
+ imis_id_for(certificate) if certificate
69
+
65
70
  @logger = Imis.logger('Api')
66
71
  Imis.config.validate!
67
72
  end
@@ -77,15 +82,7 @@ module Usps
77
82
  def imis_id=(id)
78
83
  raise Errors::LockedIdError if lock_imis_id
79
84
 
80
- hex = '[0-9a-fA-F]'
81
- uuid_pattern = /^#{hex}{8}-#{hex}{4}-#{hex}{4}-#{hex}{4}-#{hex}{12}$/
82
- @imis_id =
83
- if id.to_s.match?(uuid_pattern) then id
84
- elsif id.to_i.to_s == id.to_s.gsub(' ', '') then id.to_i
85
- elsif id.nil? then nil
86
- else
87
- raise ArgumentError, "Invalid id: #{id.inspect}"
88
- end
85
+ @imis_id = format_id(id)
89
86
  end
90
87
 
91
88
  # Manually set the current record ID
@@ -119,11 +116,13 @@ module Usps
119
116
 
120
117
  logger.debug "Fetching iMIS ID for #{certificate}"
121
118
 
122
- result = query(Imis.configuration.imis_id_query_name, { certificate: })
123
- page = result.page.tap { logger.tagged('Response').debug it }
124
- raise Errors::NotFoundError, 'Member not found' if page.empty?
119
+ net_contact_data = query('NetContactData', MajorKey: certificate).one
120
+ raise Errors::NotFoundError, 'Member not found' if net_contact_data.nil?
121
+
122
+ party = query('Party', UniformId: net_contact_data.id).one
123
+ raise Errors::NotFoundError, 'Member not found' if party.nil?
125
124
 
126
- self.imis_id = page.first['ID'].to_i
125
+ self.imis_id = party.id
127
126
  rescue Errors::ResponseError
128
127
  raise Errors::NotFoundError, 'Member not found'
129
128
  end
@@ -26,6 +26,10 @@ module Usps
26
26
  #
27
27
  ESCAPE_PADDING = 14
28
28
 
29
+ # Pattern for removing escape codes from strings
30
+ #
31
+ ESCAPE_PATTERN = /\e\[[0-9;]*m/
32
+
29
33
  def banner_header(version)
30
34
  <<~BANNER
31
35
  #{version.bold.blue}
@@ -50,7 +54,7 @@ module Usps
50
54
 
51
55
  #{wiki}
52
56
 
53
- https://github.com/unitedstatespowersquadrons/imis-api-ruby/wiki/Command-Line
57
+ #{'https://github.com/unitedstatespowersquadrons/imis-api-ruby/wiki/Command-Line'.light_blue}
54
58
 
55
59
  BANNER
56
60
  end
@@ -71,12 +75,13 @@ module Usps
71
75
  raw_description, details = options[key]
72
76
  details ||= {}
73
77
 
74
- flag = option_flag_string(key, details).ljust(option_column_width)
78
+ flag_string = option_flag_string(key, details)
79
+ flag = flag_string.ljust(option_column_width + invisible_length(flag_string))
75
80
  left_width = option_column_width + indent(3).length # Indent additional lines one step further
76
81
  tags = [
77
82
  (" (default: #{details[:default]})" if details[:default]),
78
83
  (" (max: #{details[:max]})" if details[:max])
79
- ].compact.join
84
+ ].compact.join.gray
80
85
 
81
86
  "#{flag}#{wrap_description(raw_description, left_width, suffix: tags)}"
82
87
  end
@@ -118,8 +123,8 @@ module Usps
118
123
 
119
124
  legacy_flags.each do |flags, replacement|
120
125
  left_width = indent(2).length + option_column_width
121
- description = wrap_description("use: #{replacement}", left_width)
122
- lines << "#{indent(2)}#{flags.ljust(option_column_width)}#{description}"
126
+ description = wrap_description("#{'use:'.light_magenta} #{replacement}", left_width)
127
+ lines << "#{indent(2)}#{flags.ljust(option_column_width + invisible_length(flags))}#{description}"
123
128
  end
124
129
  lines << "\n"
125
130
  end
@@ -147,7 +152,7 @@ module Usps
147
152
  when :io then '=<io>'
148
153
  when :ios then '=<io+>'
149
154
  else ''
150
- end
155
+ end.gray
151
156
  end
152
157
 
153
158
  def wrap_description(text, left_width, suffix: '')
@@ -181,17 +186,16 @@ module Usps
181
186
  lines
182
187
  end
183
188
 
184
- def visible_length(text)
185
- text.gsub(/\e\[[0-9;]*m/, '').length
186
- end
189
+ def visible_length(text) = text.gsub(ESCAPE_PATTERN, '').length
190
+ def invisible_length(text) = text.length - visible_length(text)
187
191
 
188
192
  def option_column_width
189
193
  option_widths = option_groups.values.flatten.map do |key|
190
194
  _, details = options[key]
191
- option_flag_string(key, details || {}).length
195
+ visible_length(option_flag_string(key, details || {}))
192
196
  end
193
197
 
194
- all_widths = option_widths + legacy_flags.keys.map(&:length)
198
+ all_widths = option_widths + legacy_flags.keys.map { visible_length(it) }
195
199
  all_widths.max + GAP
196
200
  end
197
201
  end
@@ -168,9 +168,11 @@ module Usps
168
168
 
169
169
  def default_options? = options[:log_level] == 'info' && options.except(:log_level).values.none?
170
170
 
171
- # :nocov:
172
- def handle_exception!(exception) = options[:trace] ? raise(exception) : exit(2)
173
- # :nocov:
171
+ def handle_exception!(exception)
172
+ raise(exception) if options[:trace] || ENV.fetch('TESTING', false) || ENV.fetch('CI', false)
173
+
174
+ exit(2)
175
+ end
174
176
  end
175
177
  end
176
178
  end
@@ -2,47 +2,40 @@ Subcommands:
2
2
  object:
3
3
  description: Interact with a Business Object
4
4
  value: name
5
- legacy_name: 'on'
5
+ legacy: 'on'
6
6
  option:
7
- - Business Object name
8
- - type: string
9
- short: O
7
+ type: string
8
+ short: O
10
9
  panel:
11
10
  description: Interact with a Panel
12
11
  value: name
13
12
  option:
14
- - Panel name
15
- - type: string
16
- short: P
13
+ type: string
14
+ short: P
17
15
  query:
18
16
  description: Run an IQA or Business Object Query
19
17
  value: name
20
18
  option:
21
- - IQA Query or Business Object name to query
22
- - type: string
23
- short: Q
19
+ type: string
20
+ short: Q
24
21
  mapper:
25
22
  description: Interact with mapped fields
26
23
  option:
27
- - Interact with mapped fields
28
- - short: M
24
+ short: M
29
25
  map:
30
26
  description: Shorthand for `%{green:mapper -f}` to access a single mapped field
31
27
  value: field
32
28
  option:
33
- - Shorthand for %{green:-Mf} to access a single mapped field
34
- - type: string
35
- short: m
29
+ type: string
30
+ short: m
36
31
  business-objects:
37
32
  description: List available Business Objects
38
33
  option:
39
- - List available Business Objects
40
- - short: B
34
+ short: B
41
35
  auth-token:
42
36
  description: Return an auth token for other language wrappers
43
37
  option:
44
- - Return an auth token for other language wrappers
45
- - short: T
38
+ short: T
46
39
 
47
40
  Options:
48
41
  Identity:
@@ -164,10 +157,10 @@ Options:
164
157
 
165
158
  Misc:
166
159
  version:
167
- - Print version and exit
160
+ - Return API version
168
161
  - short: v
169
162
  environment:
170
- - Print configured environment and exit
163
+ - Return configured environment
171
164
  - short: E
172
165
  help:
173
166
  - Show this message
@@ -36,15 +36,15 @@ module Usps
36
36
 
37
37
  def legacy_aliases
38
38
  @legacy_aliases ||= subcommands.each_with_object({}) do |(name, details), aliases|
39
- next unless details[:legacy_name]
39
+ next unless details[:legacy]
40
40
 
41
- aliases["--#{details[:legacy_name]}"] = "--#{name}"
41
+ aliases["--#{details[:legacy]}"] = "--#{name}"
42
42
  end
43
43
  end
44
44
 
45
45
  def legacy_flags
46
46
  @legacy_flags ||= subcommands.to_h do |name, details|
47
- flag_name = details[:legacy_name] || name.tr('-', '_')
47
+ flag_name = details[:legacy] || name.tr('-', '_')
48
48
  option_key = name.tr('-', '_').to_sym
49
49
  _, option_details = options[option_key]
50
50
 
@@ -62,18 +62,18 @@ module Usps
62
62
  end
63
63
 
64
64
  def colorize_text(text)
65
- text.gsub(STYLE_PATTERN) { Regexp.last_match(2).colorize(style_args(Regexp.last_match(1))) }
66
- end
67
-
68
- def style_args(styles)
69
- styles.split('.').each_with_object({}) do |name, args|
70
- key = String.colors.include?(name.to_sym) ? :color : :mode
71
- args[key] = name.to_sym
65
+ text.gsub(STYLE_PATTERN) do
66
+ Regexp.last_match(2).colorize(
67
+ Regexp.last_match(1).split('.').each_with_object({}) do |name, args|
68
+ key = String.colors.include?(name.to_sym) ? :color : :mode
69
+ args[key] = name.to_sym
70
+ end
71
+ )
72
72
  end
73
73
  end
74
74
 
75
75
  def merged_options
76
- subcommand_options = subcommands.transform_values { it[:option] }.transform_keys { it.gsub('-', '_') }
76
+ subcommand_options = subcommands.transform_values { ['', it[:option]] }.transform_keys { it.gsub('-', '_') }
77
77
  yaml['Options'].values.inject(:merge).merge(subcommand_options)
78
78
  end
79
79
  end
@@ -14,16 +14,15 @@ module Usps
14
14
  IMIS_ROOT_URL_PROD = 'https://portal.americasboatingclub.org'
15
15
  IMIS_ROOT_URL_DEV = 'https://abcdev.imiscloud.com'
16
16
  DEFAULT_GLOBAL_LOG_PATH = '/var/log/imis/imis.log'
17
- REQUIRED = %w[imis_id_query_name username password].freeze
17
+ REQUIRED = %w[username password].freeze
18
18
  OPTIONAL = %w[environment logger_file global_log_path].freeze
19
19
  SETTABLE = (REQUIRED + OPTIONAL).freeze
20
20
 
21
- attr_accessor :imis_id_query_name, :username, :password
21
+ attr_accessor :username, :password
22
22
  attr_reader :environment, :logger, :logger_level, :logger_file
23
23
 
24
24
  def initialize
25
25
  @environment = default_environment
26
- @imis_id_query_name = ENV.fetch('IMIS_ID_QUERY_NAME', nil)
27
26
  @username = ENV.fetch('IMIS_USERNAME', nil)
28
27
  @password = ENV.fetch('IMIS_PASSWORD', nil)
29
28
  @base_logger = Logger.new($stdout, level: :info)
@@ -10,18 +10,23 @@ module Usps
10
10
  # Convenience wrapper for accessing specific properties within an API data response
11
11
  #
12
12
  class Data < BaseData
13
+ include Imis::Helpers
14
+
13
15
  # The Business Object or Panel name
14
16
  #
15
17
  def entity = raw['EntityTypeName']
16
18
 
17
19
  # Access the iMIS ID (i.e. Party ID) property
18
20
  #
19
- def imis_id = raw['PrimaryParentIdentity']['IdentityElements']['$values'].first.to_i
21
+ def imis_id = format_id(raw['PrimaryParentIdentity']['IdentityElements']['$values'].first)
20
22
  alias id imis_id
21
23
 
22
24
  # Access the Record ID property
23
25
  #
24
- def record_id = raw['Identity']['IdentityElements']['$values'].first.to_i
26
+ def record_id
27
+ identity = format_id(raw['Identity']['IdentityElements']['$values'].first)
28
+ identity unless identity == imis_id
29
+ end
25
30
 
26
31
  # Access the Ordinal identifier property (if present)
27
32
  #
@@ -51,7 +56,7 @@ module Usps
51
56
  private
52
57
 
53
58
  def pretty_print_data
54
- { entity:, imis_id:, record_id: (record_id unless record_id == imis_id), ordinal: }.compact
59
+ { entity:, imis_id:, record_id:, ordinal: }.compact
55
60
  end
56
61
 
57
62
  def property_values = raw['Properties']['$values']
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Usps
4
+ module Imis
5
+ # General helper methods
6
+ #
7
+ module Helpers
8
+ # Helper for consistently formatting valid IDs
9
+ #
10
+ def format_id(raw_id)
11
+ hex = '[0-9a-fA-F]'
12
+ uuid_pattern = /^#{hex}{8}-#{hex}{4}-#{hex}{4}-#{hex}{4}-#{hex}{12}$/
13
+
14
+ if raw_id.to_s.match?(uuid_pattern) then raw_id
15
+ elsif raw_id.to_i.to_s == raw_id.to_s.gsub(' ', '') then raw_id.to_i
16
+ elsif raw_id.nil? then nil
17
+ else
18
+ raise ArgumentError, "Invalid id: #{raw_id.inspect}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -90,6 +90,10 @@ module Usps
90
90
  #
91
91
  def page = fetch_next['Items']['$values'].map { iqa? ? it.except('$type') : wrap(it) }
92
92
 
93
+ # Fetch the first result from a single query page
94
+ #
95
+ def one = page.first
96
+
93
97
  # Fetch the next raw query page, and update the current offset
94
98
  #
95
99
  def fetch_next
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module Imis
5
- VERSION = '0.13.5'
5
+ VERSION = '0.13.7'
6
6
  end
7
7
  end
data/lib/usps/imis.rb CHANGED
@@ -20,6 +20,7 @@ require 'active_support/tagged_logging'
20
20
  require 'dotenv/load'
21
21
 
22
22
  # Internal requires
23
+ require_relative 'imis/helpers'
23
24
  require_relative 'imis/config'
24
25
  require_relative 'imis/error'
25
26
  require_relative 'imis/api'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-imis-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.5
4
+ version: 0.13.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander
@@ -115,6 +115,7 @@ files:
115
115
  - lib/usps/imis/errors/pattern_matching_error.rb
116
116
  - lib/usps/imis/errors/response_error.rb
117
117
  - lib/usps/imis/errors/unexpected_property_type_error.rb
118
+ - lib/usps/imis/helpers.rb
118
119
  - lib/usps/imis/logger.rb
119
120
  - lib/usps/imis/logger_formatter.rb
120
121
  - lib/usps/imis/logger_helpers.rb