Module: ArSync::TypeScript
- Defined in:
- lib/ar_sync/type_script.rb
Class Method Summary collapse
- .data_type_definition(type) ⇒ Object
- .generate_api_script ⇒ Object
- .generate_hooks_script ⇒ Object
- .generate_model_script ⇒ Object
- .generate_type_definition(api_class) ⇒ Object
- .generate_type_util_script ⇒ Object
- .generate_typed_files(api_class, dir:, comment: nil) ⇒ Object
- .query_type_definition(type) ⇒ Object
- .request_type_definition(api_class) ⇒ Object
Class Method Details
.data_type_definition(type) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/ar_sync/type_script.rb', line 125 def self.data_type_definition(type) field_definitions = [] type.fields.each do |field| field_definitions << "#{field.name}: #{field.type.ts_type}" end field_definitions << "_meta?: { name: '#{type.name}'; query: Type#{type.name}QueryBase }" " export interface Type\#{type.name} {\n \#{field_definitions.map { |line| \" \#{line}\" }.join(\"\\n\")}\n }\n TYPE\nend\n" |
.generate_api_script ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ar_sync/type_script.rb', line 63 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_script ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ar_sync/type_script.rb', line 84 def self.generate_hooks_script " import { useState, useEffect, useMemo, useRef } from 'react'\n import { TypeRequest } from './types'\n import DataTypeFromRequest, { NeverMatchArgument } from './DataTypeFromRequest'\n import { initializeHooks, useArSyncModel as useArSyncModelBase, useArSyncFetch as useArSyncFetchBase } from 'ar_sync/core/hooks'\n initializeHooks({ useState, useEffect, useMemo, useRef })\n export function useArSyncModel<R extends TypeRequest | NeverMatchArgument>(request: R | null) {\n return useArSyncModelBase<DataTypeFromRequest<R>>(request as TypeRequest)\n }\n export function useArSyncFetch<R extends TypeRequest | NeverMatchArgument>(request: R | null) {\n return useArSyncFetchBase<DataTypeFromRequest<R>>(request as TypeRequest)\n }\n CODE\nend\n" |
.generate_model_script ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ar_sync/type_script.rb', line 51 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 18 19 |
# File 'lib/ar_sync/type_script.rb', line 12 def self.generate_type_definition(api_class) types = ArSerializer::TypeScript.([api_class]).reject { |t| t.type == api_class } [ types.map { |t| data_type_definition t }, types.map { |t| query_type_definition t }, request_type_definition(api_class) ].join "\n" end |
.generate_type_util_script ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/ar_sync/type_script.rb', line 74 def self.generate_type_util_script " import { TypeRequest, ApiNameRequests } from './types'\n import { DataTypeFromRequest as DataTypeFromRequestPair } from 'ar_sync/core/DataType'\n export type NeverMatchArgument = { __nevermatch: never }\n type DataTypeFromRequest<R extends TypeRequest | NeverMatchArgument> = NeverMatchArgument extends R ? never : R extends TypeRequest ? DataTypeFromRequestPair<ApiNameRequests[R['api']], R> : never\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 |
.query_type_definition(type) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/ar_sync/type_script.rb', line 100 def self.query_type_definition(type) field_definitions = type.fields.map do |field| association_type = field.type.association_type if association_type qname = "Type#{association_type.name}Query" if field.args.empty? "#{field.name}?: true | #{qname} | { attributes?: #{qname} }" else "#{field.name}?: true | #{qname} | { params: #{field.args_ts_type}; attributes?: #{qname} }" end else "#{field.name}?: true" end end field_definitions << "'*'?: true" query_type_name = "Type#{type.name}Query" base_query_type_name = "Type#{type.name}QueryBase" " export type \#{query_type_name} = keyof (\#{base_query_type_name}) | Readonly<(keyof (\#{base_query_type_name}))[]> | \#{base_query_type_name}\n export interface \#{base_query_type_name} {\n \#{field_definitions.map { |line| \" \#{line}\" }.join(\"\\n\")}\n }\n TYPE\nend\n" |
.request_type_definition(api_class) ⇒ Object
21 22 23 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 |
# File 'lib/ar_sync/type_script.rb', line 21 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" |