Module: ArSync::TypeScript

Defined in:
lib/ar_sync/type_script.rb

Class Method Summary collapse

Class Method Details



20
21
22
23
# File 'lib/ar_sync/type_script.rb', line 20

def self.api_related_classes(api_class)
  classes = ArSerializer::TypeScript.related_serializer_types([api_class]).map(&:type)
  classes - [api_class]
end

.generate_hooks_script(mode) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ar_sync/type_script.rb', line 67

def self.generate_hooks_script(mode)
  "    import { TypeRequest, ApiNameRequests } from './types'\n    import { DataTypeFromRequest } from 'ar_sync/core/DataType'\n    import { useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/\#{mode}/hooks'\n    export function useArSyncModel<R extends TypeRequest>(request: R | null) {\n      return useArSyncModelBase<DataTypeFromRequest<ApiNameRequests[R['api']], R>>(request)\n    }\n    export function useArSyncFetch<R extends TypeRequest>(request: R | null) {\n      return useArSyncFetchBase<DataTypeFromRequest<ApiNameRequests[R['api']], R>>(request)\n    }\n  CODE\nend\n"

.generate_model_script(mode) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ar_sync/type_script.rb', line 55

def self.generate_model_script(mode)
  "    import { TypeRequest, ApiNameRequests } from './types'\n    import { DataTypeFromRequest } from 'ar_sync/core/DataType'\n    import ArSyncModelBase from 'ar_sync/\#{mode}/ArSyncModel'\n    export default class ArSyncModel<R extends TypeRequest> extends ArSyncModelBase<{}> {\n      constructor(r: R) { super(r) }\n      data: DataTypeFromRequest<ApiNameRequests[R['api']], R> | null\n    }\n  CODE\nend\n"

.generate_type_definition(api_class) ⇒ Object



13
14
15
16
17
18
# File 'lib/ar_sync/type_script.rb', line 13

def self.generate_type_definition(api_class)
  [
    ArSerializer::TypeScript.generate_type_definition(api_related_classes(api_class)),
    request_type_definition(api_class)
  ].join "\n"
end

.generate_typed_files(api_class, dir:, mode: nil, comment: nil) ⇒ Object



2
3
4
5
6
7
8
9
10
11
# File 'lib/ar_sync/type_script.rb', line 2

def self.generate_typed_files(api_class, dir:, mode: nil, comment: nil)
  mode ||= :graph if ActiveRecord::Base.include? ArSync::GraphSync
  mode ||= :tree if ActiveRecord::Base.include? ArSync::TreeSync
  raise 'ar_sync mode: graph or tree, is not specified.' unless mode
  {
    'types.ts' => generate_type_definition(api_class),
    'ArSyncModel.ts' => generate_model_script(mode),
    'hooks.ts' => generate_hooks_script(mode)
  }.each { |file, code| File.write File.join(dir, file), "#{comment}#{code}" }
end

.request_type_definition(api_class) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ar_sync/type_script.rb', line 25

def self.request_type_definition(api_class)
  type = ArSerializer::GraphQL::TypeClass.from api_class
  definitions = []
  request_types = {}
  type.fields.each do |field|
    association_type = field.type.association_type
    next unless association_type
    prefix = 'Class' if field.name.match?(/\A[A-Z]/) # for class reload query
    request_type_name = "Type#{prefix}#{field.name.camelize}Request"
    request_types[field.name] = request_type_name
    multiple = field.type.is_a? ArSerializer::GraphQL::ListTypeClass
    definitions << "      export interface \#{request_type_name} {\n        api: '\#{field.name}'\n        params?: \#{field.args_ts_type}\n        query: Type\#{association_type.name}Query\n        _meta?: { data: Type\#{field.type.association_type.name}\#{'[]' if multiple} }\n      }\n    CODE\n  end\n  [\n    'export type TypeRequest = ',\n    request_types.values.map { |value| \"  | \#{value}\" },\n    'export type ApiNameRequests =  {',\n    request_types.map { |key, value| \"  \#{key}: \#{value}\" },\n    '}',\n    definitions\n  ].join(\"\\n\")\nend\n"