Module: ArSync::TypeScript

Defined in:
lib/ar_sync/type_script.rb

Class Method Summary collapse

Class Method Details



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

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

.generate_api_scriptObject



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

def self.generate_api_script
  "    import { TypeRequest } from './types'\n    import DataTypeFromRequest from './DataTypeFromRequest'\n    import ArSyncApi from 'ar_sync/core/ArSyncApi'\n    export function fetch<R extends TypeRequest>(request: R) {\n      return ArSyncApi.fetch(request) as Promise<DataTypeFromRequest<R>>\n    }\n  CODE\nend\n"

.generate_hooks_scriptObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ar_sync/type_script.rb', line 86

def self.generate_hooks_script
  "    import { useState, useEffect, useMemo } from 'react'\n    import { TypeRequest } from './types'\n    import DataTypeFromRequest from './DataTypeFromRequest'\n    import { initializeHooks, useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/core/hooks'\n    initializeHooks({ useState, useEffect, useMemo })\n    export function useArSyncModel<R extends TypeRequest>(request: R | null) {\n      return useArSyncModelBase<DataTypeFromRequest<R>>(request)\n    }\n    export function useArSyncFetch<R extends TypeRequest>(request: R | null) {\n      return useArSyncFetchBase<DataTypeFromRequest<R>>(request)\n    }\n  CODE\nend\n"

.generate_model_scriptObject



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

def self.generate_model_script
  "    import { TypeRequest } from './types'\n    import DataTypeFromRequest from './DataTypeFromRequest'\n    import { default as ArSyncModelBase } from 'ar_sync/core/ArSyncModel'\n    declare class ArSyncModel<R extends TypeRequest> extends ArSyncModelBase<DataTypeFromRequest<R>> {\n      constructor(r: R, option?: { immutable: boolean })\n    }\n    export default ArSyncModelBase as typeof ArSyncModel\n  CODE\nend\n"

.generate_type_definition(api_class) ⇒ Object



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

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_type_util_scriptObject



77
78
79
80
81
82
83
84
# File 'lib/ar_sync/type_script.rb', line 77

def self.generate_type_util_script
  "    import { TypeRequest, ApiNameRequests } from './types'\n    import { DataTypeFromRequest as DataTypeFromRequestPair } from 'ar_sync/core/DataType'\n    type DataTypeFromRequest<R extends TypeRequest> = DataTypeFromRequestPair<ApiNameRequests[R['api']], R>\n    export default DataTypeFromRequest\n  CODE\nend\n"

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



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

def self.generate_typed_files(api_class, dir:, comment: nil)
  {
    'types.ts' => generate_type_definition(api_class),
    'ArSyncModel.ts' => generate_model_script,
    'ArSyncApi.ts' => generate_api_script,
    'hooks.ts' => generate_hooks_script,
    'DataTypeFromRequest.ts' => generate_type_util_script
  }.each { |file, code| File.write File.join(dir, file), "#{comment}#{code}" }
end

.request_type_definition(api_class) ⇒ Object



24
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
# File 'lib/ar_sync/type_script.rb', line 24

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"