rom-ldap 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +251 -0
  3. data/CONTRIBUTING.md +18 -0
  4. data/README.md +172 -0
  5. data/TODO.md +33 -0
  6. data/config/responses.yml +328 -0
  7. data/lib/dry/monitor/ldap/colorizers/default.rb +17 -0
  8. data/lib/dry/monitor/ldap/colorizers/rouge.rb +31 -0
  9. data/lib/dry/monitor/ldap/logger.rb +58 -0
  10. data/lib/rom-ldap.rb +1 -0
  11. data/lib/rom/ldap.rb +22 -0
  12. data/lib/rom/ldap/alias.rb +30 -0
  13. data/lib/rom/ldap/associations.rb +6 -0
  14. data/lib/rom/ldap/associations/core.rb +23 -0
  15. data/lib/rom/ldap/associations/many_to_many.rb +18 -0
  16. data/lib/rom/ldap/associations/many_to_one.rb +22 -0
  17. data/lib/rom/ldap/associations/one_to_many.rb +32 -0
  18. data/lib/rom/ldap/associations/one_to_one.rb +19 -0
  19. data/lib/rom/ldap/associations/self_ref.rb +35 -0
  20. data/lib/rom/ldap/attribute.rb +327 -0
  21. data/lib/rom/ldap/client.rb +185 -0
  22. data/lib/rom/ldap/client/authentication.rb +118 -0
  23. data/lib/rom/ldap/client/operations.rb +233 -0
  24. data/lib/rom/ldap/commands.rb +6 -0
  25. data/lib/rom/ldap/commands/create.rb +41 -0
  26. data/lib/rom/ldap/commands/delete.rb +17 -0
  27. data/lib/rom/ldap/commands/update.rb +35 -0
  28. data/lib/rom/ldap/constants.rb +193 -0
  29. data/lib/rom/ldap/dataset.rb +286 -0
  30. data/lib/rom/ldap/dataset/conversion.rb +62 -0
  31. data/lib/rom/ldap/dataset/dsl.rb +299 -0
  32. data/lib/rom/ldap/dataset/persistence.rb +44 -0
  33. data/lib/rom/ldap/directory.rb +126 -0
  34. data/lib/rom/ldap/directory/capabilities.rb +71 -0
  35. data/lib/rom/ldap/directory/entry.rb +200 -0
  36. data/lib/rom/ldap/directory/env.rb +155 -0
  37. data/lib/rom/ldap/directory/operations.rb +282 -0
  38. data/lib/rom/ldap/directory/password.rb +122 -0
  39. data/lib/rom/ldap/directory/root.rb +187 -0
  40. data/lib/rom/ldap/directory/tokenization.rb +66 -0
  41. data/lib/rom/ldap/directory/transactions.rb +31 -0
  42. data/lib/rom/ldap/directory/vendors/active_directory.rb +129 -0
  43. data/lib/rom/ldap/directory/vendors/apache_ds.rb +27 -0
  44. data/lib/rom/ldap/directory/vendors/e_directory.rb +16 -0
  45. data/lib/rom/ldap/directory/vendors/open_directory.rb +12 -0
  46. data/lib/rom/ldap/directory/vendors/open_dj.rb +25 -0
  47. data/lib/rom/ldap/directory/vendors/open_ldap.rb +35 -0
  48. data/lib/rom/ldap/directory/vendors/three_eight_nine.rb +16 -0
  49. data/lib/rom/ldap/directory/vendors/unknown.rb +22 -0
  50. data/lib/rom/ldap/dsl.rb +76 -0
  51. data/lib/rom/ldap/errors.rb +47 -0
  52. data/lib/rom/ldap/expression.rb +77 -0
  53. data/lib/rom/ldap/expression_encoder.rb +174 -0
  54. data/lib/rom/ldap/extensions.rb +50 -0
  55. data/lib/rom/ldap/extensions/active_support_notifications.rb +26 -0
  56. data/lib/rom/ldap/extensions/compatibility.rb +11 -0
  57. data/lib/rom/ldap/extensions/dsml.rb +165 -0
  58. data/lib/rom/ldap/extensions/msgpack.rb +23 -0
  59. data/lib/rom/ldap/extensions/optimised_json.rb +25 -0
  60. data/lib/rom/ldap/extensions/rails_log_subscriber.rb +38 -0
  61. data/lib/rom/ldap/formatter.rb +26 -0
  62. data/lib/rom/ldap/functions.rb +207 -0
  63. data/lib/rom/ldap/gateway.rb +145 -0
  64. data/lib/rom/ldap/ldif.rb +74 -0
  65. data/lib/rom/ldap/ldif/exporter.rb +77 -0
  66. data/lib/rom/ldap/ldif/importer.rb +95 -0
  67. data/lib/rom/ldap/mapper_compiler.rb +19 -0
  68. data/lib/rom/ldap/matchers.rb +69 -0
  69. data/lib/rom/ldap/message_queue.rb +7 -0
  70. data/lib/rom/ldap/oid.rb +101 -0
  71. data/lib/rom/ldap/parsers/abstract_syntax.rb +91 -0
  72. data/lib/rom/ldap/parsers/attribute.rb +290 -0
  73. data/lib/rom/ldap/parsers/filter_syntax.rb +133 -0
  74. data/lib/rom/ldap/pdu.rb +285 -0
  75. data/lib/rom/ldap/plugin/pagination.rb +145 -0
  76. data/lib/rom/ldap/plugins.rb +7 -0
  77. data/lib/rom/ldap/projection_dsl.rb +38 -0
  78. data/lib/rom/ldap/relation.rb +135 -0
  79. data/lib/rom/ldap/relation/exporting.rb +72 -0
  80. data/lib/rom/ldap/relation/reading.rb +461 -0
  81. data/lib/rom/ldap/relation/writing.rb +64 -0
  82. data/lib/rom/ldap/responses.rb +17 -0
  83. data/lib/rom/ldap/restriction_dsl.rb +45 -0
  84. data/lib/rom/ldap/schema.rb +123 -0
  85. data/lib/rom/ldap/schema/attributes_inferrer.rb +59 -0
  86. data/lib/rom/ldap/schema/dsl.rb +13 -0
  87. data/lib/rom/ldap/schema/inferrer.rb +50 -0
  88. data/lib/rom/ldap/schema/type_builder.rb +133 -0
  89. data/lib/rom/ldap/scope.rb +19 -0
  90. data/lib/rom/ldap/search_request.rb +249 -0
  91. data/lib/rom/ldap/socket.rb +210 -0
  92. data/lib/rom/ldap/tasks/ldap.rake +103 -0
  93. data/lib/rom/ldap/tasks/ldif.rake +80 -0
  94. data/lib/rom/ldap/transaction.rb +29 -0
  95. data/lib/rom/ldap/type_map.rb +88 -0
  96. data/lib/rom/ldap/types.rb +158 -0
  97. data/lib/rom/ldap/version.rb +17 -0
  98. data/lib/rom/plugins/relation/ldap/active_directory.rb +182 -0
  99. data/lib/rom/plugins/relation/ldap/auto_restrictions.rb +69 -0
  100. data/lib/rom/plugins/relation/ldap/e_directory.rb +27 -0
  101. data/lib/rom/plugins/relation/ldap/instrumentation.rb +35 -0
  102. data/lib/rouge/lexers/ldap.rb +72 -0
  103. data/lib/rouge/themes/ldap.rb +49 -0
  104. metadata +231 -0
@@ -0,0 +1,103 @@
1
+ #
2
+ # Leverage LDAP env variables or RC files.
3
+ #
4
+ # @note
5
+ # Any LDAPURI must be compatible with ldapmodify.
6
+ #
7
+ # @example
8
+ # load 'rom/ldap/tasks/ldap.rake'
9
+ #
10
+ require 'pathname'
11
+ require 'pry'
12
+
13
+ module ROM
14
+ module LDAP
15
+ #
16
+ # `$ ldapmodify -a -H ldap://127.0.0.1:3389 -D 'cn=Directory Manager'
17
+ # -w 'topsecret' -c -v -f spec/fixtures/ldif/examples/users.ldif`
18
+ #
19
+ module RakeSupport
20
+ module_function
21
+
22
+ def message
23
+ puts "Using #{root}, alternatively set LDAPDIR=/path/to/root"
24
+ puts
25
+ puts "=========================================="
26
+ end
27
+
28
+ # ldapsearch with simple authentication.
29
+ #
30
+ def search(attrs:, filter:)
31
+ puts 'ldapsearch is not installed!' if ldapsearch.empty?
32
+ system(ldapsearch, '-x', *auth, filter, *attrs.split('.'))
33
+ end
34
+
35
+ # ldapmodify with simple authentication and continuous operation.
36
+ #
37
+ def modify(dir: root)
38
+ puts 'ldapmodify is not installed!' if ldapmodify.empty?
39
+
40
+ Dir.glob("#{dir}/*.ldif") do |file|
41
+ system(ldapmodify, '-x', *auth, '-a', '-c', '-v', '-f', file)
42
+ end
43
+ end
44
+
45
+ private_instance_methods
46
+
47
+ def root
48
+ Pathname(ENV['LDAPDIR'] || Dir.pwd)
49
+ end
50
+
51
+ def auth
52
+ abort('LDAPBINDDN and LDAPBINDPW are not set') unless ENV['LDAPBINDDN'] && ENV['LDAPBINDPW']
53
+ ['-D', ENV['LDAPBINDDN'], '-w', ENV['LDAPBINDPW']]
54
+ end
55
+
56
+ def ldapsearch
57
+ `which ldapsearch`.strip
58
+ end
59
+
60
+ def ldapmodify
61
+ `which ldapmodify`.strip
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ namespace :ldap do
69
+ task :env do
70
+ ROM::LDAP::RakeSupport.message
71
+ end
72
+
73
+ # Iterate through *.ldif files in a folder.
74
+ #
75
+ # @example
76
+ #
77
+ # $ LDAPURI=ldap://127.0.0.1:3389 \
78
+ # LDAPBINDDN='cn=Directory Manager' \
79
+ # LDAPBINDPW=topsecret \
80
+ # LDAPDIR=./spec/fixtures/ldif \
81
+ # rake ldap:modify
82
+ #
83
+ desc 'Use ldapmodify'
84
+ task :modify, [:dir] => :env do |_t, args|
85
+ ROM::LDAP::RakeSupport.modify(args)
86
+ end
87
+
88
+
89
+ # 'LDAPBASE=dc=foo ldap:search[cn=*foo,gn.sn]'
90
+ #
91
+ # @example
92
+ # $ rake ldap:search
93
+ # $ rake ldap:search[cn=*41,uid.mail.sn]
94
+ # $ rake ldap:search[gn=adele]
95
+ # $ rake ldap:search[userid=adele*]
96
+ #
97
+ desc 'Use ldapsearch'
98
+ task :search, [:filter, :attrs] => :env do |_t, args|
99
+ args.with_defaults(attrs: "+ \\*", filter: '(objectClass=*)')
100
+ ROM::LDAP::RakeSupport.search(args)
101
+ end
102
+
103
+ end
@@ -0,0 +1,80 @@
1
+ # @example
2
+ # load 'rom/ldap/tasks/ldif.rake'
3
+
4
+ require 'rom/ldap'
5
+
6
+ module ROM
7
+ module LDAP
8
+ module RakeSupport
9
+ module_function
10
+
11
+ def directory
12
+ @directory ||= config.gateways[:default].directory
13
+ end
14
+
15
+ private_instance_methods
16
+
17
+ def config
18
+ @config ||= ROM::Configuration.new(:ldap)
19
+ end
20
+
21
+ def container
22
+ @container ||= ROM.container(config)
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+ namespace :ldif do
31
+ task :env do
32
+ # ENV['DEBUG'] = 'y'
33
+ end
34
+
35
+
36
+ #
37
+ # Parse and import LDIF file
38
+ # rake 'ldif:import[examples/users.ldif]'
39
+ #
40
+ desc 'import'
41
+ task :import, [:file] => :env do |_t, args|
42
+ abort 'file is required' unless args[:file]
43
+
44
+ timer = Time.now.utc
45
+ counter = 0
46
+
47
+ ROM::LDAP::LDIF(File.read(args[:file])) do |entry|
48
+ counter += 1
49
+ ROM::LDAP::RakeSupport.directory.add(entry)
50
+ end
51
+
52
+ duration = Time.now.utc - timer
53
+
54
+ puts "========================================="
55
+ puts "#{counter} entries in #{duration} seconds"
56
+ end
57
+
58
+
59
+
60
+ #
61
+ # Print LDIF
62
+ # rake 'ldif:export[(cn=*)]'
63
+ #
64
+ desc 'export'
65
+ task :export, [:filter] => :env do |_t, args|
66
+ args.with_defaults(filter: '(objectClass=*)')
67
+
68
+ using ROM::LDAP::LDIF
69
+
70
+ directory = ROM::LDAP::RakeSupport.directory
71
+ dataset = ROM::LDAP::Dataset.new(directory: directory, name: args[:filter])
72
+
73
+ puts "#"
74
+ puts "# #{Time.now}"
75
+ puts "# ========================================="
76
+ puts ""
77
+ puts dataset.export.to_ldif
78
+ end
79
+
80
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module LDAP
5
+ # Work in progress
6
+ #
7
+ # @see https://tools.ietf.org/html/rfc5805
8
+ #
9
+ # @api private
10
+ class Transaction < ::ROM::Transaction
11
+
12
+ attr_reader :directory
13
+ private :directory
14
+
15
+ def initialize(directory)
16
+ @directory = directory
17
+ end
18
+
19
+ # rubocop:disable Lint/SuppressedException
20
+ def run(opts = EMPTY_OPTS)
21
+ directory.transaction(opts) { yield(self) }
22
+ rescue ::ROM::Transaction::Rollback
23
+ # noop
24
+ end
25
+ # rubocop:enable Lint/SuppressedException
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/HashAlignment
4
+ module ROM
5
+ module LDAP
6
+ # LDAPv3 Syntaxes
7
+ #
8
+ # @see https://ldapwiki.com/wiki/LDAPSyntaxes
9
+ #
10
+ OID_TYPE_MAP = {
11
+ '1.3.6.1.1.16.1' => 'String', # UUID
12
+ '1.3.6.1.4.1.1466.115.121.1.1' => 'String', # ACI Item
13
+ '1.3.6.1.4.1.1466.115.121.1.2' => 'String', # Access Point
14
+ '1.3.6.1.4.1.1466.115.121.1.3' => 'String', # Attribute Type Description
15
+ '1.3.6.1.4.1.1466.115.121.1.4' => 'Binary', # Audio
16
+ '1.3.6.1.4.1.1466.115.121.1.5' => 'Binary', # Binary
17
+ '1.3.6.1.4.1.1466.115.121.1.6' => 'String', # Bit String
18
+ '1.3.6.1.4.1.1466.115.121.1.7' => 'Bool', # Boolean
19
+ '1.3.6.1.4.1.1466.115.121.1.8' => 'String', # Certificate
20
+ '1.3.6.1.4.1.1466.115.121.1.9' => 'String', # Certificate List
21
+ '1.3.6.1.4.1.1466.115.121.1.10' => 'String', # Certificate Pair
22
+ '1.3.6.1.4.1.1466.115.121.1.11' => 'String', # Country String - IA5 ISO-646 (ASCII). Limited to exactly two characters describing the ISO 3166 country code.
23
+ '1.3.6.1.4.1.1466.115.121.1.12' => 'String', # DN
24
+ '1.3.6.1.4.1.1466.115.121.1.13' => 'String', # Data Quality Syntax
25
+ '1.3.6.1.4.1.1466.115.121.1.14' => 'String', # Delivery Method
26
+ '1.3.6.1.4.1.1466.115.121.1.15' => 'String', # Directory String
27
+ '1.3.6.1.4.1.1466.115.121.1.19' => 'String', # DSA Quality Syntax
28
+ '1.3.6.1.4.1.1466.115.121.1.20' => 'String', # DSE Type
29
+ '1.3.6.1.4.1.1466.115.121.1.21' => 'String', # Enhanced Guide
30
+ '1.3.6.1.4.1.1466.115.121.1.22' => 'String', # Facsimile Telephone Number
31
+ '1.3.6.1.4.1.1466.115.121.1.23' => 'String', # Fax
32
+ '1.3.6.1.4.1.1466.115.121.1.24' => 'Time', # Generalized Time
33
+ '1.3.6.1.4.1.1466.115.121.1.25' => 'String', # Guide
34
+ '1.3.6.1.4.1.1466.115.121.1.26' => 'String', # IA5String - IA5 ISO-646 (ASCII).
35
+ '1.3.6.1.4.1.1466.115.121.1.27' => 'Integer', # INTEGER - IntegerMatch / integerOrderingMatch
36
+ '1.3.6.1.4.1.1466.115.121.1.28' => 'Binary', # JPEG - RFC2798: Joint Photographic Experts Group (JPEG) image syntax from inetOrgPerson object class schema.
37
+ '1.3.6.1.4.1.1466.115.121.1.32' => 'String', # Mail Preference
38
+ '1.3.6.1.4.1.1466.115.121.1.34' => 'String', # Name And Optional UID
39
+ '1.3.6.1.4.1.1466.115.121.1.35' => 'String', # Name Form Description
40
+ '1.3.6.1.4.1.1466.115.121.1.36' => 'Integer', # Numeric String - IA5 ISO-646 (ASCII).
41
+ '1.3.6.1.4.1.1466.115.121.1.37' => 'String', # Object Class Description
42
+ '1.3.6.1.4.1.1466.115.121.1.38' => 'String', # OID
43
+ '1.3.6.1.4.1.1466.115.121.1.39' => 'String', # Other Mailbox
44
+ '1.3.6.1.4.1.1466.115.121.1.40' => 'String', # Octet String - Treated as transparent 8-bit bytes. (passwords)
45
+ '1.3.6.1.4.1.1466.115.121.1.41' => 'String', # Postal Address - UTF-8 ISO-10646 (Unicode). Split by dollar sign "$".
46
+ '1.3.6.1.4.1.1466.115.121.1.42' => 'String', # Protocol Information
47
+ '1.3.6.1.4.1.1466.115.121.1.43' => 'String', # Presentation Address
48
+ '1.3.6.1.4.1.1466.115.121.1.44' => 'String', # Printable String
49
+ '1.3.6.1.4.1.1466.115.121.1.50' => 'String', # Telephone Number
50
+ '1.3.6.1.4.1.1466.115.121.1.51' => 'String', # Teletex Terminal Identifier
51
+ '1.3.6.1.4.1.1466.115.121.1.52' => 'String', # Telex Number
52
+ '1.3.6.1.4.1.1466.115.121.1.53' => 'Time', # UTC Time
53
+ '1.3.6.1.4.1.1466.115.121.1.54' => 'String', # LDAP Syntax Description
54
+ '1.3.6.1.4.1.1466.115.121.1.56' => 'String', # LDAP Schema Definition
55
+ '1.3.6.1.4.1.1466.115.121.1.57' => 'String', # LDAP Schema Description
56
+
57
+ # Microsoft Active Directory
58
+ #
59
+ # @see https://ldapwiki.com/wiki/Microsoft%20Active%20Directory%20Syntax
60
+ # @see https://docs.microsoft.com/en-gb/windows/desktop/ADSchema/attributes-all
61
+ # @see https://docs.microsoft.com/en-us/windows/desktop/ADSI/data-type-mapping-between-active-directory-and-ldap
62
+ #
63
+ '1.2.840.113556.1.2.19' => 'Time', # uSNCreated
64
+ '1.2.840.113556.1.2.120' => 'Time', # uSNChanged
65
+
66
+ '1.2.840.113556.1.4.49' => 'Time', # badPasswordTime
67
+ '1.2.840.113556.1.4.52' => 'Time', # lastLogon
68
+ '1.2.840.113556.1.4.53' => 'Time', # lastSetTime
69
+ '1.2.840.113556.1.4.60' => 'Time', # lockoutDuration
70
+ '1.2.840.113556.1.4.74' => 'Time', # maxPwdAge
71
+ '1.2.840.113556.1.4.76' => 'Integer', # maxStorage
72
+ '1.2.840.113556.1.4.78' => 'Time', # minPwdAge
73
+ '1.2.840.113556.1.4.96' => 'Time', # pwdLastSet
74
+ '1.2.840.113556.1.4.159' => 'Time', # accountExpires
75
+ '1.2.840.113556.1.4.371' => 'Integer', # rIDAllocationPool
76
+ '1.2.840.113556.1.4.662' => 'Time', # lockoutTime
77
+ '1.2.840.113556.1.4.903' => 'String', # DNWithOctetString
78
+ '1.2.840.113556.1.4.904' => 'String', # DNWithString
79
+ '1.2.840.113556.1.4.905' => 'String', # Telex
80
+ '1.2.840.113556.1.4.906' => 'Integer', # INTEGER8
81
+ '1.2.840.113556.1.4.907' => 'String', # ObjectSecurityDescriptor
82
+ '1.2.840.113556.1.4.1221' => 'String', # CaseIgnoreString' / ORName
83
+ '1.2.840.113556.1.4.1362' => 'String', # CaseExactString
84
+ '1.2.840.113556.1.4.1696' => 'Time' # lastLogonTimeStamp
85
+ }.freeze
86
+ end
87
+ end
88
+ # rubocop:enable Layout/HashAlignment
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rom/types'
4
+ require 'rom/ldap/functions'
5
+
6
+ module ROM
7
+ module LDAP
8
+ module Types
9
+ include ROM::Types
10
+
11
+ # Protocol ldap(s) only
12
+ #
13
+ # @return [Dry::Types::Constrained]
14
+ #
15
+ # @api public
16
+ URI = Strict::String.constrained(format: LDAPURI_REGEX)
17
+
18
+ # Something in parentheses
19
+ #
20
+ # @return [Dry::Types::Constrained]
21
+ #
22
+ # @api public
23
+ Filter = Strict::String.constrained(format: FILTER_REGEX)
24
+
25
+ #
26
+ # @return [Dry::Types::Constrained]
27
+ #
28
+ # @api public
29
+ DN = Strict::String.constrained(format: DN_REGEX)
30
+
31
+ # @return [Dry::Types::Constrained]
32
+ #
33
+ # @api public
34
+ Direction = Strict::Symbol.constrained(included_in: %i[asc desc])
35
+
36
+ # @return [Dry::Types::Constrained]
37
+ #
38
+ # @api public
39
+ Scope = Strict::Integer.constrained(included_in: SCOPES)
40
+
41
+ # @return [Dry::Types::Constrained]
42
+ #
43
+ # @api public
44
+ Deref = Strict::Integer.constrained(included_in: DEREF_ALL)
45
+
46
+ # Abstraction of LDAP constructors and operators
47
+ #
48
+ # @return [Dry::Types::Constrained]
49
+ #
50
+ # @api public
51
+ Abstract = Strict::Symbol.constrained(included_in: ABSTRACTS)
52
+
53
+ # Compatible filter fields (formatters may symbolise)
54
+ #
55
+ # @return [Dry::Types::Sum::Constrained]
56
+ #
57
+ # @api public
58
+ Field = Strict::String | Strict::Symbol
59
+
60
+ # Compatible filter values (including wildcard abstraction)
61
+ #
62
+ # @return [Dry::Types::Sum::Constrained]
63
+ #
64
+ # @api public
65
+ Value = Strict::String | Strict::Integer | Strict::Float | Strict::Symbol.constrained(included_in: %i[wildcard])
66
+
67
+ # @example => "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...."
68
+ #
69
+ # @return [String]
70
+ #
71
+ # @api public
72
+ Media = Constructor(String, ->(v) { Functions[:mime_type].call(v[0]) })
73
+
74
+ # 1.3.6.1.4.1.1466.115.121.1.41
75
+ #
76
+ # A special format which uses UTF-8 encoding of ISO-10646 (Unicode)
77
+ # separated by '$' used for generating printable labels or other output.
78
+ # DOES allow extended characters e.g. é, Ø, å etc.
79
+ # Allows matchingRules of `caseIgnoreListMatch` and `caseIgnoreListSubstringsMatch`.
80
+ #
81
+ # @return [Array<String>]
82
+ #
83
+ # @api public
84
+ Address = Constructor(Array, ->(v) { v.split('$').map(&:strip) })
85
+
86
+ #
87
+ # Single Values --------
88
+ #
89
+ # @see Schema::Attribute read types
90
+
91
+ # @return [String]
92
+ #
93
+ # @api public
94
+ String = Constructor(String, ->(v) { Functions[:stringify].call(v[0]) })
95
+
96
+ # @return [Integer]
97
+ #
98
+ # @api public
99
+ Integer = Constructor(Integer, ->(v) { Functions[:map_to_integers][v][0] })
100
+
101
+ # @return [Symbol]
102
+ #
103
+ # @api public
104
+ Symbol = Constructor(Symbol, ->(v) { Functions[:map_to_symbols][v][0] })
105
+
106
+ # @return [Time]
107
+ #
108
+ # @api public
109
+ Time = Constructor(Time, ->(v) { Functions[:map_to_times][v][0] })
110
+
111
+ # @overload [ROM::Types::Bool]
112
+ #
113
+ # @return [Boolean]
114
+ #
115
+ # @api public
116
+ Bool = Constructor(Bool, ->(v) { Functions[:map_to_booleans][v][0] })
117
+
118
+ # @return [String]
119
+ #
120
+ # @api public
121
+ Binary = Constructor(String, ->(v) { Functions[:map_to_base64][v][0] }).meta(binary: true)
122
+
123
+ #
124
+ # Multiple Values --------
125
+ #
126
+
127
+ # @return [Array<String>]
128
+ #
129
+ # @api public
130
+ Strings = Constructor(Array, Functions[:stringify])
131
+
132
+ # @return [Array<Integer>]
133
+ #
134
+ # @api public
135
+ Integers = Constructor(Array, Functions[:map_to_integers])
136
+
137
+ # @return [Array<Symbol>]
138
+ #
139
+ # @api public
140
+ Symbols = Constructor(Array, Functions[:map_to_symbols])
141
+
142
+ # @return [Array<Time>]
143
+ #
144
+ # @api public
145
+ Times = Constructor(Array, Functions[:map_to_times])
146
+
147
+ # @return [Array<TrueClass, FalseClass>]
148
+ #
149
+ # @api public
150
+ Bools = Constructor(Array, Functions[:map_to_booleans])
151
+
152
+ # @return [Array<String>]
153
+ #
154
+ # @api public
155
+ Binaries = Constructor(Array, Functions[:map_to_base64]).meta(binary: true)
156
+ end
157
+ end
158
+ end