ask-schema 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +350 -0
- data/lib/ask/schema/dsl/complex_types.rb +72 -0
- data/lib/ask/schema/dsl/conditionals.rb +243 -0
- data/lib/ask/schema/dsl/primitive_types.rb +60 -0
- data/lib/ask/schema/dsl/schema_builders.rb +254 -0
- data/lib/ask/schema/dsl/utilities.rb +99 -0
- data/lib/ask/schema/dsl.rb +24 -0
- data/lib/ask/schema/errors.rb +31 -0
- data/lib/ask/schema/helpers.rb +19 -0
- data/lib/ask/schema/json_output.rb +49 -0
- data/lib/ask/schema/validator.rb +100 -0
- data/lib/ask/schema/version.rb +7 -0
- data/lib/ask-schema.rb +176 -0
- metadata +97 -0
data/lib/ask-schema.rb
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "ask/schema/version"
|
|
4
|
+
require_relative "ask/schema/errors"
|
|
5
|
+
require_relative "ask/schema/helpers"
|
|
6
|
+
require_relative "ask/schema/validator"
|
|
7
|
+
require_relative "ask/schema/dsl"
|
|
8
|
+
require_relative "ask/schema/json_output"
|
|
9
|
+
require "json"
|
|
10
|
+
|
|
11
|
+
module Ask
|
|
12
|
+
# Build standards-compliant JSON Schema documents using a compact Ruby DSL.
|
|
13
|
+
#
|
|
14
|
+
# Supports both block-based and class-based usage patterns, with full support
|
|
15
|
+
# for JSON Schema Draft 07/2020-12 features including composition, conditionals,
|
|
16
|
+
# definitions, and validation.
|
|
17
|
+
#
|
|
18
|
+
# @example Block-based DSL
|
|
19
|
+
# schema = Ask::Schema.create do
|
|
20
|
+
# string :name, description: "Full name"
|
|
21
|
+
# integer :age, minimum: 0
|
|
22
|
+
# end
|
|
23
|
+
# schema.new("user").to_json_schema
|
|
24
|
+
#
|
|
25
|
+
# @example Class-based DSL
|
|
26
|
+
# class Product < Ask::Schema
|
|
27
|
+
# string :name, description: "Product name"
|
|
28
|
+
# number :price
|
|
29
|
+
# end
|
|
30
|
+
# Product.new("product").to_json_schema
|
|
31
|
+
class Schema
|
|
32
|
+
extend DSL
|
|
33
|
+
include JsonOutput
|
|
34
|
+
|
|
35
|
+
# Primitive JSON Schema types available in the DSL.
|
|
36
|
+
PRIMITIVE_TYPES = %i[string number integer boolean null].freeze
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
# Create a new Schema subclass from a DSL block.
|
|
40
|
+
#
|
|
41
|
+
# @param block [Proc] DSL block with type definitions
|
|
42
|
+
# @return [Class<Schema>] A dynamically-created Schema subclass
|
|
43
|
+
#
|
|
44
|
+
# @example
|
|
45
|
+
# schema = Ask::Schema.create do
|
|
46
|
+
# string :name
|
|
47
|
+
# integer :age
|
|
48
|
+
# end
|
|
49
|
+
def create(&block)
|
|
50
|
+
schema_class = Class.new(Schema)
|
|
51
|
+
schema_class.class_eval(&block)
|
|
52
|
+
schema_class
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Properties defined on this schema class (inheritable).
|
|
56
|
+
#
|
|
57
|
+
# @return [Hash{Symbol => Hash}] Property definitions keyed by name
|
|
58
|
+
def properties
|
|
59
|
+
@properties ||= {}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Required property names for this schema class (inheritable).
|
|
63
|
+
#
|
|
64
|
+
# @return [Array<Symbol>] Required property names
|
|
65
|
+
def required_properties
|
|
66
|
+
@required_properties ||= []
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Named sub-schema definitions for `$defs`.
|
|
70
|
+
#
|
|
71
|
+
# @return [Hash{Symbol => Hash}] Named definitions keyed by symbol
|
|
72
|
+
def definitions
|
|
73
|
+
@definitions ||= {}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Set or get the schema name used in JSON output.
|
|
77
|
+
#
|
|
78
|
+
# @param name [String, nil] The schema name
|
|
79
|
+
# @return [String, nil] The current schema name
|
|
80
|
+
def name(name = nil)
|
|
81
|
+
@schema_name = name if name
|
|
82
|
+
return @schema_name if defined?(@schema_name)
|
|
83
|
+
|
|
84
|
+
super()
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Set or get the schema description used in JSON output.
|
|
88
|
+
#
|
|
89
|
+
# @param description [String, nil] The schema description
|
|
90
|
+
# @return [String, nil] The current description
|
|
91
|
+
def description(description = nil)
|
|
92
|
+
@description = description if description
|
|
93
|
+
@description
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Set or get whether additional (undeclared) properties are allowed.
|
|
97
|
+
#
|
|
98
|
+
# @param value [Boolean, nil] True to allow additional properties
|
|
99
|
+
# @return [Boolean] Defaults to +false+
|
|
100
|
+
def additional_properties(value = nil)
|
|
101
|
+
return @additional_properties ||= false if value.nil?
|
|
102
|
+
|
|
103
|
+
@additional_properties = value
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Set or get strict mode for the schema.
|
|
107
|
+
#
|
|
108
|
+
# When strict, the schema includes `"strict": true` in output.
|
|
109
|
+
#
|
|
110
|
+
# @param args [Boolean, nil] The strict mode value
|
|
111
|
+
# @return [Boolean] Defaults to +true+
|
|
112
|
+
def strict(*args)
|
|
113
|
+
if args.empty?
|
|
114
|
+
instance_variable_defined?(:@strict) ? @strict : true
|
|
115
|
+
else
|
|
116
|
+
@strict = args.first
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Validate the schema definition, raising on circular references or other errors.
|
|
121
|
+
#
|
|
122
|
+
# @return [nil] if the schema is valid
|
|
123
|
+
# @raise [ValidationError] if the schema has circular references
|
|
124
|
+
def validate!
|
|
125
|
+
validator = Validator.new(self)
|
|
126
|
+
validator.validate!
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Check if the schema definition is valid.
|
|
130
|
+
#
|
|
131
|
+
# @return [Boolean] true if the schema has no validation errors
|
|
132
|
+
def valid?
|
|
133
|
+
validator = Validator.new(self)
|
|
134
|
+
validator.valid?
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Create a new schema instance.
|
|
139
|
+
#
|
|
140
|
+
# @param name [String, nil] Instance name (overrides class name in JSON output)
|
|
141
|
+
# @param description [String, nil] Instance description (overrides class description)
|
|
142
|
+
def initialize(name = nil, description: nil)
|
|
143
|
+
@name = name || self.class.name || "Schema"
|
|
144
|
+
@description = description
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Validate this schema instance.
|
|
148
|
+
#
|
|
149
|
+
# @return [nil] if valid
|
|
150
|
+
# @raise [ValidationError] if invalid
|
|
151
|
+
def validate!
|
|
152
|
+
self.class.validate!
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Check if this schema instance is valid.
|
|
156
|
+
#
|
|
157
|
+
# @return [Boolean]
|
|
158
|
+
def valid?
|
|
159
|
+
self.class.valid?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Delegate DSL methods (string, number, integer, etc.) to the class level.
|
|
163
|
+
def method_missing(method_name, ...)
|
|
164
|
+
if respond_to_missing?(method_name)
|
|
165
|
+
self.class.send(method_name, ...)
|
|
166
|
+
else
|
|
167
|
+
super
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Check if a method can be delegated to the class level.
|
|
172
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
173
|
+
%i[string number integer boolean array object any_of one_of null].include?(method_name) || super
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ask-schema
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kaka Ruto
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '5.25'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '5.25'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mocha
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.1'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
description: A compact Ruby DSL for building standards-oriented JSON Schema documents.
|
|
55
|
+
Zero dependencies.
|
|
56
|
+
email:
|
|
57
|
+
- kaka@myrrlabs.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- LICENSE
|
|
63
|
+
- README.md
|
|
64
|
+
- lib/ask-schema.rb
|
|
65
|
+
- lib/ask/schema/dsl.rb
|
|
66
|
+
- lib/ask/schema/dsl/complex_types.rb
|
|
67
|
+
- lib/ask/schema/dsl/conditionals.rb
|
|
68
|
+
- lib/ask/schema/dsl/primitive_types.rb
|
|
69
|
+
- lib/ask/schema/dsl/schema_builders.rb
|
|
70
|
+
- lib/ask/schema/dsl/utilities.rb
|
|
71
|
+
- lib/ask/schema/errors.rb
|
|
72
|
+
- lib/ask/schema/helpers.rb
|
|
73
|
+
- lib/ask/schema/json_output.rb
|
|
74
|
+
- lib/ask/schema/validator.rb
|
|
75
|
+
- lib/ask/schema/version.rb
|
|
76
|
+
homepage: https://github.com/ask-rb/ask-schema
|
|
77
|
+
licenses:
|
|
78
|
+
- MIT
|
|
79
|
+
metadata: {}
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
require_paths:
|
|
82
|
+
- lib
|
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '3.2'
|
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '0'
|
|
93
|
+
requirements: []
|
|
94
|
+
rubygems_version: 4.0.3
|
|
95
|
+
specification_version: 4
|
|
96
|
+
summary: JSON Schema DSL for Ruby
|
|
97
|
+
test_files: []
|