Class: TypeSpecFromSerializers::Interface

Inherits:
Struct
  • Object
show all
Defined in:
lib/typespec_from_serializers/generator.rb

Overview

Internal: Information to generate a TypeSpec model for a serializer.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#docObject

Returns the value of attribute doc

Returns:

  • (Object)

    the current value of doc



245
246
247
# File 'lib/typespec_from_serializers/generator.rb', line 245

def doc
  @doc
end

#filenameObject

Returns the value of attribute filename

Returns:

  • (Object)

    the current value of filename



245
246
247
# File 'lib/typespec_from_serializers/generator.rb', line 245

def filename
  @filename
end

#nameObject

Returns the value of attribute name

Returns:

  • (Object)

    the current value of name



245
246
247
# File 'lib/typespec_from_serializers/generator.rb', line 245

def name
  @name
end

#propertiesObject

Returns the value of attribute properties

Returns:

  • (Object)

    the current value of properties



245
246
247
# File 'lib/typespec_from_serializers/generator.rb', line 245

def properties
  @properties
end

Instance Method Details

#as_typespecObject



306
307
308
309
310
311
312
313
314
# File 'lib/typespec_from_serializers/generator.rb', line 306

def as_typespec
  indent = TypeSpecFromSerializers.config.namespace ? 2 : 1
  doc_decorator = doc ? "@doc(\"#{escape_doc(doc)}\")\n#{"  " * (indent - 1)}" : ""
  "    \#{doc_decorator}model \#{name} {\n    \#{\"  \" * indent}\#{properties.index_by(&:name).values.map(&:as_typespec).join(\"\\n\#{\"  \" * indent}\")}\n    \#{\"  \" * (indent - 1)}}\n  TSP\nend\n".gsub(/\n$/, "")

#inspectObject



254
255
256
# File 'lib/typespec_from_serializers/generator.rb', line 254

def inspect
  to_h.inspect
end

#serializer_model_exists?(type_name) ⇒ Boolean

Returns:

  • (Boolean)


299
300
301
302
303
304
# File 'lib/typespec_from_serializers/generator.rb', line 299

def serializer_model_exists?(type_name)
  # Check if any loaded serializer generates a model with this name
  TypeSpecFromSerializers.loaded_serializers.any? { |ser| ser.tsp_model.name == type_name }
rescue
  false
end

#used_importsObject

Internal: Returns a list of imports for types used in this model.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/typespec_from_serializers/generator.rb', line 259

def used_imports
  association_serializers, attribute_types = properties.map(&:type).compact.uniq
    .partition { |type| type.respond_to?(:tsp_model) }

  serializer_type_imports = association_serializers.map(&:tsp_model)
    .map { |type| [type.name, relative_path(type.pathname, pathname)] }

  # Extract type names from attribute types (strings like "Task[]" or "string | null")
  type_names = attribute_types
    .flat_map { |type|
      # Extract base type name, removing array notation and taking first part of unions
      type.to_s.delete_suffix("[]").split(/\s*[|.]\s*/)
    }
    .uniq
    .reject { |type| global_type?(type) }

  # Partition into serializer models vs custom types
  serializer_models, custom_types = type_names.partition { |type_name|
    serializer_model_exists?(type_name)
  }

  # Import serializer models from models/ directory
  serializer_model_imports = serializer_models.map { |type_name|
    # Find the serializer that generates this model
    serializer = TypeSpecFromSerializers.loaded_serializers.find { |ser| ser.tsp_model.name == type_name }
    next unless serializer

    [type_name, relative_path(serializer.tsp_model.pathname, pathname)]
  }.compact

  # Import custom types from custom directory
  custom_type_imports = custom_types.map { |type|
    type_path = TypeSpecFromSerializers.config.relative_custom_typespec_dir.join(type)
    [type, relative_path(type_path, pathname)]
  }

  (custom_type_imports + serializer_type_imports + serializer_model_imports)
    .map { |model, filename| %(import "#{filename}.tsp";\n) }
end