foobara-typescript-remote-command-generator 1.4.0 → 1.5.1

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: 16a68cb56fbf77e520f577b5ef5d0b6c677d6461fb69ce242906d608b6412e3f
4
- data.tar.gz: 35dcccf09cff04cad00c02423b77ebecdebc3643080cc9e534bae8e957dd273c
3
+ metadata.gz: 3ea5e21e87c906d2b3605a56ef2a49245d7eb47266909cd6763c3272872e3ce3
4
+ data.tar.gz: 02fb6e36dce4acd76a517f42c6950617a80350bd570708321877daf7d523005e
5
5
  SHA512:
6
- metadata.gz: 952c659c1ace30fbbd24f980c8382db56f95757ac5a802b25ed19e5c6faf276dd1647f6fe999cb3afc49c3bb35b90003e95765ad2363f1ce160846cd9d3100d3
7
- data.tar.gz: 78c60b378c18f6786c9d6cd29db44d7c693c45c433977deedeaec79694ccb4f640f092159349758be3d1094d04c83f379e6caaea4c3e3bd4c9d5e820e4929fcc
6
+ metadata.gz: c73ce6914c21030225dc6b29a27c49e9e0828e6dcb4c6e0ff96c66c63a50b989480dd66bbb67d5f982c84934057cd5ee6024893a1cf36125f82a3aa9f997f7eb
7
+ data.tar.gz: 75a7d0058162533cce17ec2a3b8693bbd19c2f9f30f7cb43dbd960dfdf19aa5c6cb83dceb15c6e5882c80e9a7adc4ff995cc5233a2e79ea69c31402d2c156a69
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [1.5.1] - 2026-08-22
2
+
3
+ - Allow setting the env expression to either import.meta.env or process.env with --env-expression
4
+
5
+ ## [1.5.0] - 2026-08-06
6
+
7
+ - Only generate RequiresAuthCommand when its imports will exist
8
+ - Only call dirtyQueries when it is defined
9
+
1
10
  ## [1.4.0] - 2026-03-19
2
11
 
3
12
  - Make things work with Vite instead of CRA
@@ -1,6 +1,8 @@
1
1
  require "net/http"
2
2
  require "uri"
3
3
 
4
+ require_relative "remote_generator"
5
+
4
6
  module Foobara
5
7
  module RemoteGenerator
6
8
  class GenerateTypescript < Foobara::Generators::Generate
@@ -12,29 +14,46 @@ module Foobara
12
14
  raw_manifest :associative_array
13
15
  manifest_url :string
14
16
  auto_dirty_queries :boolean, default: false
17
+ no_foobara_auth :boolean,
18
+ default: false,
19
+ description: "Never generate Foobara::Auth's RequiresAuthCommand, even if the " \
20
+ "manifest contains that domain. For apps that import it from elsewhere."
21
+ env_expression :env_expression, default: "import.meta.env"
15
22
  end
16
23
 
17
24
  def execute
18
- load_manifest_if_needed
25
+ apply_remote_generator_config do
26
+ load_manifest_if_needed
19
27
 
20
- include_non_templated_files
28
+ include_non_templated_files
21
29
 
22
- add_root_manifest_to_set_of_elements_to_generate
23
- # TODO: allow specifying subset of commands
24
- add_all_commands_to_set_of_elements_to_generate
30
+ add_root_manifest_to_set_of_elements_to_generate
31
+ # TODO: allow specifying subset of commands
32
+ add_all_commands_to_set_of_elements_to_generate
25
33
 
26
- each_element_to_generate do
27
- generate_element
34
+ each_element_to_generate do
35
+ generate_element
36
+ end
28
37
  end
29
38
 
30
39
  paths_to_source_code
31
40
  end
32
41
 
42
+ def apply_remote_generator_config
43
+ RemoteGenerator.no_foobara_auth(no_foobara_auth) do
44
+ RemoteGenerator.auto_dirty_queries(auto_dirty_queries) do
45
+ RemoteGenerator.with_env_expression(env_expression) do
46
+ yield
47
+ end
48
+ end
49
+ end
50
+ end
51
+
33
52
  def validate
34
53
  if raw_manifest.nil? && manifest_url.nil?
35
- # :nocov:
54
+ # simplecov:disable
36
55
  add_runtime_error(MissingManifestError.new(message: "Either raw_manifest or manifest_url must be given"))
37
- # :nocov:
56
+ # simplecov:enable
38
57
  end
39
58
  end
40
59
 
@@ -52,7 +71,7 @@ module Foobara
52
71
  self.manifest_data = if raw_manifest
53
72
  raw_manifest
54
73
  # TODO: introduce VCR to test the following elsif block
55
- # :nocov:
74
+ # simplecov:disable
56
75
  elsif manifest_url
57
76
  url = URI.parse(manifest_url)
58
77
  response = Net::HTTP.get_response(url)
@@ -65,7 +84,7 @@ module Foobara
65
84
  end
66
85
 
67
86
  JSON.parse(manifest_json)
68
- # :nocov:
87
+ # simplecov:enable
69
88
  end
70
89
  end
71
90
 
@@ -77,12 +96,6 @@ module Foobara
77
96
  end
78
97
  end
79
98
 
80
- def generate_element
81
- RemoteGenerator.auto_dirty_queries(auto_dirty_queries) do
82
- super
83
- end
84
- end
85
-
86
99
  def add_root_manifest_to_set_of_elements_to_generate
87
100
  elements_to_generate << manifest
88
101
  end
@@ -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
- # :nocov:
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
- # :nocov:
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
- # :nocov:
138
+ # simplecov:disable
139
139
  raise "Not sure how to handle a #{cast_tree.class}: #{cast_tree}"
140
- # :nocov:
140
+ # simplecov:enable
141
141
  end
142
142
  end
143
143
  else
144
- # :nocov:
144
+ # simplecov:disable
145
145
  raise "Not sure how to handle a #{cast_tree.class}: #{cast_tree}"
146
- # :nocov:
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
- # :nocov:
154
+ # simplecov:disable
155
155
  raise "Expected a CastTree but got a #{cast_tree.class}: #{cast_tree}"
156
- # :nocov:
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
- # :nocov:
173
+ # simplecov:disable
174
174
  value
175
- # :nocov:
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
- # :nocov:
201
+ # simplecov:disable
202
202
  raise "Not sure how to cast type #{type} to a Typescript expression"
203
- # :nocov:
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
- # :nocov:
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
- # :nocov:
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
- # :nocov:
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
- # :nocov:
312
+ # simplecov:enable
313
313
  end
314
314
  end
315
315
  end
@@ -86,9 +86,9 @@ module Foobara
86
86
 
87
87
  if type && !type.builtin? && !type.model?
88
88
  # TODO: Test this!!
89
- # :nocov:
89
+ # simplecov:disable
90
90
  [TypeGenerator.new(type)]
91
- # :nocov:
91
+ # simplecov:enable
92
92
  else
93
93
  []
94
94
  end
@@ -27,9 +27,9 @@ module Foobara
27
27
 
28
28
  collision_data[key].tap do |cd|
29
29
  unless cd
30
- # :nocov:
30
+ # simplecov:disable
31
31
  raise "Dependency #{dep} is not part of this dependency group"
32
- # :nocov:
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
- # :nocov:
77
+ # simplecov:disable
78
78
  raise "Dependency #{dep} has no collision data"
79
- # :nocov:
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
- # :nocov:
20
+ # simplecov:disable
21
21
  raise "Expected #{error_name} to have a parent but it did not"
22
- # :nocov:
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
- # :nocov:
86
+ # simplecov:disable
87
87
  raise "Haven't implemented other types yet"
88
- # :nocov:
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
- # :nocov:
93
+ # simplecov:disable
94
94
  guts += " | undefined"
95
- # :nocov:
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
- Auth::RequiresAuthGenerator
58
+ requires_auth_generator_for(manifest)
40
59
  else
41
60
  if manifest.requires_authentication?
42
- Auth::RequiresAuthGenerator
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
- # :nocov:
109
+ # simplecov:disable
91
110
  raise "Not sure how build a generator for a #{manifest}"
92
- # :nocov:
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
- # :nocov:
120
+ # simplecov:disable
102
121
  raise ArgumentError, "Expected a Foobara::Manifest, got #{relevant_manifest.class}"
103
- # :nocov:
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
- # :nocov:
158
+ # simplecov:disable
140
159
  raise "This generator was created without a " \
141
160
  "dependency_group and therefore cannot call #{__method__}"
142
- # :nocov:
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
- # :nocov:
223
+ # simplecov:disable
205
224
  raise "Not sure how to represent #{value} in typescript. Maybe implement it."
206
- # :nocov:
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
- # :nocov:
263
+ # simplecov:disable
245
264
  return is_empty ? "undefined" : "interface #{name} #{ts_type}"
246
- # :nocov:
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
- # :nocov:
272
+ # simplecov:disable
254
273
  ts_type
255
- # :nocov:
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
- # :nocov:
350
+ # simplecov:disable
332
351
  raise "Not sure how to convert #{type_declaration} to a TS type"
333
- # :nocov:
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
- # :nocov:
400
+ # simplecov:disable
382
401
  "Record<string, any>"
383
- # :nocov:
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
- # :nocov:
421
+ # simplecov:disable
403
422
  raise "Bad association_depth: #{association_depth}"
404
- # :nocov:
423
+ # simplecov:enable
405
424
  end
406
425
 
407
426
  generator = generator_class.new(model)
@@ -435,6 +454,8 @@ module Foobara
435
454
  def auto_dirty_queries?
436
455
  RemoteGenerator.auto_dirty_queries?
437
456
  end
457
+
458
+ def env_expression = RemoteGenerator.env_expression
438
459
  end
439
460
  end
440
461
  end
@@ -2,6 +2,8 @@ module Foobara
2
2
  module RemoteGenerator
3
3
  foobara_domain!
4
4
 
5
+ foobara_register_type(:env_expression, :string, one_of: ["import.meta.env", "process.env"])
6
+
5
7
  class << self
6
8
  def auto_dirty_queries(auto_dirty_queries)
7
9
  if auto_dirty_queries == @auto_dirty_queries
@@ -21,6 +23,33 @@ module Foobara
21
23
  def auto_dirty_queries?
22
24
  @auto_dirty_queries
23
25
  end
26
+
27
+ def no_foobara_auth(no_foobara_auth)
28
+ old = @no_foobara_auth
29
+ begin
30
+ @no_foobara_auth = no_foobara_auth
31
+ yield
32
+ ensure
33
+ @no_foobara_auth = old
34
+ end
35
+ end
36
+
37
+ def no_foobara_auth?
38
+ @no_foobara_auth
39
+ end
40
+
41
+ def with_env_expression(env_expression)
42
+ old = @env_expression
43
+
44
+ begin
45
+ @env_expression = env_expression
46
+ yield
47
+ ensure
48
+ @env_expression = old
49
+ end
50
+ end
51
+
52
+ attr_reader :env_expression
24
53
  end
25
54
  end
26
55
  end
@@ -15,6 +15,11 @@ 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."
22
+ env_expression :env_expression, default: "import.meta.env"
18
23
  end
19
24
 
20
25
  possible_error :missing_manifest
@@ -50,17 +55,13 @@ module Foobara
50
55
  # TODO: we need a way to allow values to be nil in type declarations
51
56
  inputs = raw_manifest ? { raw_manifest: } : { manifest_url: }
52
57
 
53
- if auto_dirty_queries?
54
- inputs[:auto_dirty_queries] = auto_dirty_queries
55
- end
58
+ inputs[:auto_dirty_queries] = auto_dirty_queries
59
+ inputs[:no_foobara_auth] = no_foobara_auth
60
+ inputs[:env_expression] = env_expression
56
61
 
57
62
  self.paths_to_source_code = run_subcommand!(GenerateTypescript, inputs)
58
63
  end
59
64
 
60
- def auto_dirty_queries?
61
- auto_dirty_queries
62
- end
63
-
64
65
  def run_post_generation_tasks
65
66
  Dir.chdir(project_directory || output_directory) do
66
67
  eslint_fix
@@ -74,7 +75,7 @@ module Foobara
74
75
  exit_status = wait_thr.value
75
76
 
76
77
  unless exit_status.success?
77
- # :nocov:
78
+ # simplecov:disable
78
79
  out = stdout.read
79
80
  err = stderr.read
80
81
 
@@ -83,7 +84,7 @@ module Foobara
83
84
  else
84
85
  warn "WARNING: could not #{cmd}\n#{out}\n#{err}"
85
86
  end
86
- # :nocov:
87
+ # simplecov:enable
87
88
  end
88
89
  end
89
90
  end
@@ -1,4 +1,4 @@
1
- let _urlBase = import.meta.env.REACT_APP_FOOBARA_GLOBAL_URL_BASE
1
+ let _urlBase = <%= env_expression %>.REACT_APP_FOOBARA_GLOBAL_URL_BASE
2
2
 
3
3
  const config = {
4
4
  get urlBase(): string {
@@ -1,4 +1,4 @@
1
- let _urlBase = import.meta.env.REACT_APP_FOOBARA_GLOBAL_URL_BASE
1
+ let _urlBase = <%= env_expression %>.REACT_APP_FOOBARA_GLOBAL_URL_BASE
2
2
 
3
3
  const config = {
4
4
  get urlBase(): string {
@@ -15,7 +15,7 @@ export default abstract class RemoteCommand<Inputs, Result, CommandError extends
15
15
  let base = this._urlBase
16
16
 
17
17
  if (base == null) {
18
- base = import.meta.env.REACT_APP_FOOBARA_GLOBAL_URL_BASE
18
+ base = <%= env_expression %>.REACT_APP_FOOBARA_GLOBAL_URL_BASE
19
19
  }
20
20
 
21
21
  if (base == null) {
@@ -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.0
4
+ version: 1.5.1
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: 3.6.9
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: []