foobara-typescript-remote-command-generator 1.4.0 → 1.5.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/src/generate_typescript.rb +17 -11
- data/src/generators/command_cast_result_generator.rb +16 -16
- data/src/generators/command_result_generator.rb +2 -2
- data/src/generators/dependency_group.rb +4 -4
- data/src/generators/error_generator.rb +2 -2
- data/src/generators/type_generator.rb +4 -4
- data/src/generators/typescript_from_manifest_base_generator.rb +39 -20
- data/src/remote_generator.rb +14 -0
- data/src/write_typescript_to_disk.rb +8 -9
- data/templates/base/RemoteCommand.ts.erb +2 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3665400333aa868dea13a4812bfc7cfbaf13e1475d3823eac5824566b4e4bb2b
|
|
4
|
+
data.tar.gz: 764d0161640c99f2b5bfbe8f92f985455509c4a211e15703eb0bbfe1d38b043e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aa6643f0ff7c9661cc37f9294b50fbe28d52de56b8c2a34e4b549f085d026e76c3f38a84b42ee9004e1d911b7c7f302961999a819e3e796905330fa046f247e1
|
|
7
|
+
data.tar.gz: 70ec01c2a3664fcd68a973baa7b2ae5c9e5a519b0aac8067aade428307911bf035e388f84b249f4ac66486f5dc8867c2f1bb34f935e3ff8a04eed88fe815fcbf
|
data/CHANGELOG.md
CHANGED
data/src/generate_typescript.rb
CHANGED
|
@@ -12,19 +12,25 @@ module Foobara
|
|
|
12
12
|
raw_manifest :associative_array
|
|
13
13
|
manifest_url :string
|
|
14
14
|
auto_dirty_queries :boolean, default: false
|
|
15
|
+
no_foobara_auth :boolean,
|
|
16
|
+
default: false,
|
|
17
|
+
description: "Never generate Foobara::Auth's RequiresAuthCommand, even if the " \
|
|
18
|
+
"manifest contains that domain. For apps that import it from elsewhere."
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def execute
|
|
18
|
-
|
|
22
|
+
RemoteGenerator.no_foobara_auth(no_foobara_auth) do
|
|
23
|
+
load_manifest_if_needed
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
include_non_templated_files
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
add_root_manifest_to_set_of_elements_to_generate
|
|
28
|
+
# TODO: allow specifying subset of commands
|
|
29
|
+
add_all_commands_to_set_of_elements_to_generate
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
each_element_to_generate do
|
|
32
|
+
generate_element
|
|
33
|
+
end
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
paths_to_source_code
|
|
@@ -32,9 +38,9 @@ module Foobara
|
|
|
32
38
|
|
|
33
39
|
def validate
|
|
34
40
|
if raw_manifest.nil? && manifest_url.nil?
|
|
35
|
-
# :
|
|
41
|
+
# simplecov:disable
|
|
36
42
|
add_runtime_error(MissingManifestError.new(message: "Either raw_manifest or manifest_url must be given"))
|
|
37
|
-
# :
|
|
43
|
+
# simplecov:enable
|
|
38
44
|
end
|
|
39
45
|
end
|
|
40
46
|
|
|
@@ -52,7 +58,7 @@ module Foobara
|
|
|
52
58
|
self.manifest_data = if raw_manifest
|
|
53
59
|
raw_manifest
|
|
54
60
|
# TODO: introduce VCR to test the following elsif block
|
|
55
|
-
# :
|
|
61
|
+
# simplecov:disable
|
|
56
62
|
elsif manifest_url
|
|
57
63
|
url = URI.parse(manifest_url)
|
|
58
64
|
response = Net::HTTP.get_response(url)
|
|
@@ -65,7 +71,7 @@ module Foobara
|
|
|
65
71
|
end
|
|
66
72
|
|
|
67
73
|
JSON.parse(manifest_json)
|
|
68
|
-
# :
|
|
74
|
+
# simplecov:enable
|
|
69
75
|
end
|
|
70
76
|
end
|
|
71
77
|
|
|
@@ -117,14 +117,14 @@ module Foobara
|
|
|
117
117
|
result << "})"
|
|
118
118
|
elsif child_cast_tree.is_a?(::Hash)
|
|
119
119
|
# TODO: either test this code path or delete it
|
|
120
|
-
# :
|
|
120
|
+
# simplecov:disable
|
|
121
121
|
property = path_part =~ /\A\d+\z/ ? path_part.to_i : "\"#{path_part}\""
|
|
122
122
|
|
|
123
123
|
result << cast_json_result_function_body(child_cast_tree,
|
|
124
124
|
parent:,
|
|
125
125
|
property:,
|
|
126
126
|
value: "#{parent}?.#{path_part}")
|
|
127
|
-
# :
|
|
127
|
+
# simplecov:enable
|
|
128
128
|
elsif child_cast_tree.is_a?(CastTree)
|
|
129
129
|
result << cast_json_result_function_body(child_cast_tree.children,
|
|
130
130
|
parent: "#{parent}?.#{path_part}")
|
|
@@ -135,15 +135,15 @@ module Foobara
|
|
|
135
135
|
property:,
|
|
136
136
|
value: "#{parent}?.#{path_part}")
|
|
137
137
|
else
|
|
138
|
-
# :
|
|
138
|
+
# simplecov:disable
|
|
139
139
|
raise "Not sure how to handle a #{cast_tree.class}: #{cast_tree}"
|
|
140
|
-
# :
|
|
140
|
+
# simplecov:enable
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
143
|
else
|
|
144
|
-
# :
|
|
144
|
+
# simplecov:disable
|
|
145
145
|
raise "Not sure how to handle a #{cast_tree.class}: #{cast_tree}"
|
|
146
|
-
# :
|
|
146
|
+
# simplecov:enable
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
result.compact.join("\n")
|
|
@@ -151,9 +151,9 @@ module Foobara
|
|
|
151
151
|
|
|
152
152
|
def _ts_cast_expression(cast_tree, value:, parent: nil, property: nil)
|
|
153
153
|
unless cast_tree.is_a?(CastTree)
|
|
154
|
-
# :
|
|
154
|
+
# simplecov:disable
|
|
155
155
|
raise "Expected a CastTree but got a #{cast_tree.class}: #{cast_tree}"
|
|
156
|
-
# :
|
|
156
|
+
# simplecov:enable
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
type_declaration = cast_tree.declaration_to_cast
|
|
@@ -170,9 +170,9 @@ module Foobara
|
|
|
170
170
|
end
|
|
171
171
|
else
|
|
172
172
|
# TODO: either test this path or raise
|
|
173
|
-
# :
|
|
173
|
+
# simplecov:disable
|
|
174
174
|
value
|
|
175
|
-
# :
|
|
175
|
+
# simplecov:enable
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
type = if type_declaration.is_a?(Manifest::TypeDeclaration)
|
|
@@ -198,9 +198,9 @@ module Foobara
|
|
|
198
198
|
|
|
199
199
|
"#{lvalue} = new #{ts_model_name}(#{present_value})"
|
|
200
200
|
else
|
|
201
|
-
# :
|
|
201
|
+
# simplecov:disable
|
|
202
202
|
raise "Not sure how to cast type #{type} to a Typescript expression"
|
|
203
|
-
# :
|
|
203
|
+
# simplecov:enable
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
expression += "\n}"
|
|
@@ -243,7 +243,7 @@ module Foobara
|
|
|
243
243
|
|
|
244
244
|
CastTree.new(children:, declaration_to_cast: type_declaration, initial:)
|
|
245
245
|
# TODO: either test this code path or raise or delete it
|
|
246
|
-
# :
|
|
246
|
+
# simplecov:disable
|
|
247
247
|
elsif type_declaration.custom?
|
|
248
248
|
if type_requires_cast?(type_declaration.base_type.to_type_declaration)
|
|
249
249
|
tree = _construct_cast_tree(type_declaration.base_type.to_type_declaration)
|
|
@@ -253,7 +253,7 @@ module Foobara
|
|
|
253
253
|
end
|
|
254
254
|
end
|
|
255
255
|
end
|
|
256
|
-
# :
|
|
256
|
+
# simplecov:enable
|
|
257
257
|
end
|
|
258
258
|
|
|
259
259
|
# TODO: Feels like similar complicated logic is popping up in many places? How to find/converge such logic
|
|
@@ -305,11 +305,11 @@ module Foobara
|
|
|
305
305
|
models
|
|
306
306
|
elsif type_declaration.custom?
|
|
307
307
|
# TODO: either test this code path or raise or delete it
|
|
308
|
-
# :
|
|
308
|
+
# simplecov:disable
|
|
309
309
|
if type_requires_cast?(type_declaration.base_type.to_type_declaration)
|
|
310
310
|
_models_reachable_from_declaration(type_declaration.base_type.to_type_declaration)
|
|
311
311
|
end
|
|
312
|
-
# :
|
|
312
|
+
# simplecov:enable
|
|
313
313
|
end
|
|
314
314
|
end
|
|
315
315
|
end
|
|
@@ -27,9 +27,9 @@ module Foobara
|
|
|
27
27
|
|
|
28
28
|
collision_data[key].tap do |cd|
|
|
29
29
|
unless cd
|
|
30
|
-
# :
|
|
30
|
+
# simplecov:disable
|
|
31
31
|
raise "Dependency #{dep} is not part of this dependency group"
|
|
32
|
-
# :
|
|
32
|
+
# simplecov:enable
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -74,9 +74,9 @@ module Foobara
|
|
|
74
74
|
points = collision_data_for(dep).points
|
|
75
75
|
|
|
76
76
|
unless points
|
|
77
|
-
# :
|
|
77
|
+
# simplecov:disable
|
|
78
78
|
raise "Dependency #{dep} has no collision data"
|
|
79
|
-
# :
|
|
79
|
+
# simplecov:enable
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
points
|
|
@@ -17,9 +17,9 @@ module Foobara
|
|
|
17
17
|
when TypeGenerator
|
|
18
18
|
[*p.target_dir, p.type_short_name, "errors"]
|
|
19
19
|
when nil
|
|
20
|
-
# :
|
|
20
|
+
# simplecov:disable
|
|
21
21
|
raise "Expected #{error_name} to have a parent but it did not"
|
|
22
|
-
# :
|
|
22
|
+
# simplecov:enable
|
|
23
23
|
else
|
|
24
24
|
p.target_dir
|
|
25
25
|
end
|
|
@@ -83,16 +83,16 @@ module Foobara
|
|
|
83
83
|
value_to_ts_value(enum_item)
|
|
84
84
|
end.join(" | ")
|
|
85
85
|
else
|
|
86
|
-
# :
|
|
86
|
+
# simplecov:disable
|
|
87
87
|
raise "Haven't implemented other types yet"
|
|
88
|
-
# :
|
|
88
|
+
# simplecov:enable
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
if declaration_data["allow_nil"]
|
|
92
92
|
# TODO: add a custom type to the fixture manifest that includes allows_nil
|
|
93
|
-
# :
|
|
93
|
+
# simplecov:disable
|
|
94
94
|
guts += " | undefined"
|
|
95
|
-
# :
|
|
95
|
+
# simplecov:enable
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
guts
|
|
@@ -25,6 +25,25 @@ module Foobara
|
|
|
25
25
|
module Generators
|
|
26
26
|
class TypescriptFromManifestBaseGenerator < Foobara::FilesGenerator
|
|
27
27
|
class << self
|
|
28
|
+
def requires_auth_command_generatable?(manifest)
|
|
29
|
+
return false if RemoteGenerator.no_foobara_auth?
|
|
30
|
+
|
|
31
|
+
root = manifest.root_manifest
|
|
32
|
+
commands = root[:command] || root["command"] || {}
|
|
33
|
+
names = commands.keys.to_set(&:to_s)
|
|
34
|
+
|
|
35
|
+
names.include?("Foobara::Auth::RefreshLogin") &&
|
|
36
|
+
names.intersect?(["Foobara::Auth::Login", "Foobara::Auth::Logout"].to_set)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def requires_auth_generator_for(manifest)
|
|
40
|
+
if requires_auth_command_generatable?(manifest)
|
|
41
|
+
Auth::RequiresAuthGenerator
|
|
42
|
+
else
|
|
43
|
+
CommandGenerator
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
28
47
|
def manifest_to_generator_classes(manifest)
|
|
29
48
|
case manifest
|
|
30
49
|
when Manifest::Command
|
|
@@ -36,10 +55,10 @@ module Foobara
|
|
|
36
55
|
when "Foobara::Auth::Logout"
|
|
37
56
|
Auth::LogoutGenerator
|
|
38
57
|
when /\bGetCurrentUser$/
|
|
39
|
-
|
|
58
|
+
requires_auth_generator_for(manifest)
|
|
40
59
|
else
|
|
41
60
|
if manifest.requires_authentication?
|
|
42
|
-
|
|
61
|
+
requires_auth_generator_for(manifest)
|
|
43
62
|
else
|
|
44
63
|
CommandGenerator
|
|
45
64
|
end
|
|
@@ -87,9 +106,9 @@ module Foobara
|
|
|
87
106
|
when Manifest::Type
|
|
88
107
|
TypeGenerator
|
|
89
108
|
else
|
|
90
|
-
# :
|
|
109
|
+
# simplecov:disable
|
|
91
110
|
raise "Not sure how build a generator for a #{manifest}"
|
|
92
|
-
# :
|
|
111
|
+
# simplecov:enable
|
|
93
112
|
end
|
|
94
113
|
end
|
|
95
114
|
end
|
|
@@ -98,9 +117,9 @@ module Foobara
|
|
|
98
117
|
if none_given || relevant_manifest.is_a?(Manifest::BaseManifest)
|
|
99
118
|
super
|
|
100
119
|
else
|
|
101
|
-
# :
|
|
120
|
+
# simplecov:disable
|
|
102
121
|
raise ArgumentError, "Expected a Foobara::Manifest, got #{relevant_manifest.class}"
|
|
103
|
-
# :
|
|
122
|
+
# simplecov:enable
|
|
104
123
|
end
|
|
105
124
|
end
|
|
106
125
|
|
|
@@ -136,10 +155,10 @@ module Foobara
|
|
|
136
155
|
return @dependency_roots if defined?(@dependency_roots)
|
|
137
156
|
|
|
138
157
|
unless dependency_group
|
|
139
|
-
# :
|
|
158
|
+
# simplecov:disable
|
|
140
159
|
raise "This generator was created without a " \
|
|
141
160
|
"dependency_group and therefore cannot call #{__method__}"
|
|
142
|
-
# :
|
|
161
|
+
# simplecov:enable
|
|
143
162
|
end
|
|
144
163
|
|
|
145
164
|
@dependency_roots = dependency_group.non_colliding_dependency_roots.sort_by(&:scoped_full_name)
|
|
@@ -201,9 +220,9 @@ module Foobara
|
|
|
201
220
|
when ::Symbol
|
|
202
221
|
value.to_s.inspect
|
|
203
222
|
else
|
|
204
|
-
# :
|
|
223
|
+
# simplecov:disable
|
|
205
224
|
raise "Not sure how to represent #{value} in typescript. Maybe implement it."
|
|
206
|
-
# :
|
|
225
|
+
# simplecov:enable
|
|
207
226
|
end
|
|
208
227
|
end
|
|
209
228
|
|
|
@@ -241,18 +260,18 @@ module Foobara
|
|
|
241
260
|
|
|
242
261
|
if name
|
|
243
262
|
# TODO: test this code path or delete it
|
|
244
|
-
# :
|
|
263
|
+
# simplecov:disable
|
|
245
264
|
return is_empty ? "undefined" : "interface #{name} #{ts_type}"
|
|
246
|
-
# :
|
|
265
|
+
# simplecov:enable
|
|
247
266
|
else
|
|
248
267
|
is_empty ? "undefined" : ts_type
|
|
249
268
|
end
|
|
250
269
|
else
|
|
251
270
|
# TODO: test this path with an :attributes type (not extended from :attributes but
|
|
252
271
|
# the built-in type itself directly)
|
|
253
|
-
# :
|
|
272
|
+
# simplecov:disable
|
|
254
273
|
ts_type
|
|
255
|
-
# :
|
|
274
|
+
# simplecov:enable
|
|
256
275
|
end
|
|
257
276
|
elsif type_declaration.is_a?(Manifest::Array)
|
|
258
277
|
# TODO: which association_depth do we pass here?
|
|
@@ -328,9 +347,9 @@ module Foobara
|
|
|
328
347
|
# TODO: Add description as a comment?
|
|
329
348
|
name ? "type #{name} = #{type_string}" : type_string
|
|
330
349
|
else
|
|
331
|
-
# :
|
|
350
|
+
# simplecov:disable
|
|
332
351
|
raise "Not sure how to convert #{type_declaration} to a TS type"
|
|
333
|
-
# :
|
|
352
|
+
# simplecov:enable
|
|
334
353
|
end
|
|
335
354
|
end
|
|
336
355
|
|
|
@@ -378,9 +397,9 @@ module Foobara
|
|
|
378
397
|
else
|
|
379
398
|
# TODO: test this path with an :attributes type (not extended from :attributes but
|
|
380
399
|
# the built-in type itself directly)
|
|
381
|
-
# :
|
|
400
|
+
# simplecov:disable
|
|
382
401
|
"Record<string, any>"
|
|
383
|
-
# :
|
|
402
|
+
# simplecov:enable
|
|
384
403
|
end
|
|
385
404
|
end
|
|
386
405
|
|
|
@@ -399,9 +418,9 @@ module Foobara
|
|
|
399
418
|
when AssociationDepth::AGGREGATE
|
|
400
419
|
AggregateModelGenerator
|
|
401
420
|
else
|
|
402
|
-
# :
|
|
421
|
+
# simplecov:disable
|
|
403
422
|
raise "Bad association_depth: #{association_depth}"
|
|
404
|
-
# :
|
|
423
|
+
# simplecov:enable
|
|
405
424
|
end
|
|
406
425
|
|
|
407
426
|
generator = generator_class.new(model)
|
data/src/remote_generator.rb
CHANGED
|
@@ -21,6 +21,20 @@ module Foobara
|
|
|
21
21
|
def auto_dirty_queries?
|
|
22
22
|
@auto_dirty_queries
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
def no_foobara_auth(no_foobara_auth)
|
|
26
|
+
old = @no_foobara_auth
|
|
27
|
+
begin
|
|
28
|
+
@no_foobara_auth = no_foobara_auth
|
|
29
|
+
yield
|
|
30
|
+
ensure
|
|
31
|
+
@no_foobara_auth = old
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def no_foobara_auth?
|
|
36
|
+
@no_foobara_auth
|
|
37
|
+
end
|
|
24
38
|
end
|
|
25
39
|
end
|
|
26
40
|
end
|
|
@@ -15,6 +15,10 @@ module Foobara
|
|
|
15
15
|
output_directory :string, default: "src/domains"
|
|
16
16
|
fail_if_does_not_pass_linter :boolean, default: false
|
|
17
17
|
auto_dirty_queries :boolean, default: false
|
|
18
|
+
no_foobara_auth :boolean,
|
|
19
|
+
default: false,
|
|
20
|
+
description: "Never generate Foobara::Auth's RequiresAuthCommand, even if the " \
|
|
21
|
+
"manifest contains that domain. For apps that import it from elsewhere."
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
possible_error :missing_manifest
|
|
@@ -50,17 +54,12 @@ module Foobara
|
|
|
50
54
|
# TODO: we need a way to allow values to be nil in type declarations
|
|
51
55
|
inputs = raw_manifest ? { raw_manifest: } : { manifest_url: }
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
57
|
+
inputs[:auto_dirty_queries] = auto_dirty_queries
|
|
58
|
+
inputs[:no_foobara_auth] = no_foobara_auth
|
|
56
59
|
|
|
57
60
|
self.paths_to_source_code = run_subcommand!(GenerateTypescript, inputs)
|
|
58
61
|
end
|
|
59
62
|
|
|
60
|
-
def auto_dirty_queries?
|
|
61
|
-
auto_dirty_queries
|
|
62
|
-
end
|
|
63
|
-
|
|
64
63
|
def run_post_generation_tasks
|
|
65
64
|
Dir.chdir(project_directory || output_directory) do
|
|
66
65
|
eslint_fix
|
|
@@ -74,7 +73,7 @@ module Foobara
|
|
|
74
73
|
exit_status = wait_thr.value
|
|
75
74
|
|
|
76
75
|
unless exit_status.success?
|
|
77
|
-
# :
|
|
76
|
+
# simplecov:disable
|
|
78
77
|
out = stdout.read
|
|
79
78
|
err = stderr.read
|
|
80
79
|
|
|
@@ -83,7 +82,7 @@ module Foobara
|
|
|
83
82
|
else
|
|
84
83
|
warn "WARNING: could not #{cmd}\n#{out}\n#{err}"
|
|
85
84
|
end
|
|
86
|
-
# :
|
|
85
|
+
# simplecov:enable
|
|
87
86
|
end
|
|
88
87
|
end
|
|
89
88
|
end
|
|
@@ -121,7 +121,9 @@ export default abstract class RemoteCommand<Inputs, Result, CommandError extends
|
|
|
121
121
|
|
|
122
122
|
this.outcome = new SuccessfulOutcome<Result, CommandError>(result)
|
|
123
123
|
this.commandState = 'succeeded'
|
|
124
|
+
<% if auto_dirty_queries? %>
|
|
124
125
|
this.dirtyQueries()
|
|
126
|
+
<% end %>
|
|
125
127
|
} else if (response.status === 422 || response.status === 401 || response.status === 403) {
|
|
126
128
|
this.commandState = 'errored'
|
|
127
129
|
this.outcome = new ErrorOutcome<Result, CommandError>(body)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foobara-typescript-remote-command-generator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miles Georgi
|
|
@@ -153,13 +153,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
153
153
|
- - ">="
|
|
154
154
|
- !ruby/object:Gem::Version
|
|
155
155
|
version: 3.4.0
|
|
156
|
+
- - "<"
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '4.1'
|
|
156
159
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
160
|
requirements:
|
|
158
161
|
- - ">="
|
|
159
162
|
- !ruby/object:Gem::Version
|
|
160
163
|
version: '0'
|
|
161
164
|
requirements: []
|
|
162
|
-
rubygems_version:
|
|
165
|
+
rubygems_version: 4.0.16
|
|
163
166
|
specification_version: 4
|
|
164
167
|
summary: Generates remote commands for Typescript from a foobara manifest
|
|
165
168
|
test_files: []
|