Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/app router refs #28095

Merged
merged 35 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift click to select a range
677a50c
wip: convert js ref to app router
charislam Jul 4, 2024
b617397
wip create navigation menu
charislam Jul 4, 2024
ae1006b
wip
charislam Jul 5, 2024
db16b91
wip start adding sections to js ref
charislam Jul 5, 2024
5caa4b0
wip add more to the refs page display
charislam Jul 8, 2024
4daa7ee
feat: process type spec
charislam Jul 10, 2024
2467047
test: add snapshot
charislam Jul 11, 2024
b114791
feat: display params for ref functions
charislam Jul 19, 2024
43c1e79
feat: add return types
charislam Jul 19, 2024
22b99e9
feat: add code examples
charislam Jul 20, 2024
ecf8d94
feat: scroll behavior
charislam Jul 20, 2024
457957b
fix: vercel non-included files?
charislam Jul 20, 2024
381d5c3
fix: build
charislam Jul 20, 2024
3f0e573
fix: pregenerate root reference page for sdks
charislam Jul 20, 2024
a3e4627
fix: tiny ux fixes
charislam Jul 20, 2024
badc579
test: build time
charislam Jul 21, 2024
d3fcb26
feat: crawler pages
charislam Jul 21, 2024
67b0dc1
fix: typecheck
charislam Jul 22, 2024
2d9ad33
refactor: migrate all sdk libraries
charislam Jul 22, 2024
3719a69
fix: index paths for crawler pages
charislam Jul 22, 2024
89571fc
perf: get build times down
charislam Jul 23, 2024
635a6fd
perf: build timing issues
charislam Jul 23, 2024
35d9c0c
test: speed with more pre-calculated data
charislam Jul 23, 2024
73328d6
test: speed when caching actual component
charislam Jul 23, 2024
782c9a6
test: perf with simpler crawler pages
charislam Jul 23, 2024
7e40c8d
feat: crawler content served by api
charislam Jul 23, 2024
422aacf
test: outputFileTrackingIncludes
charislam Jul 23, 2024
1ce0576
test: try outputfiletracing again?
charislam Jul 23, 2024
c6feb8b
test: add smoke tests for docs crawler routes
charislam Jul 23, 2024
802406a
fix: restore other ref sections
charislam Jul 23, 2024
7eeb6d5
perf: shave bundle size
charislam Jul 23, 2024
416fc43
fix: jankiness
charislam Jul 23, 2024
7343f31
fix: og image and crawler tests
charislam Jul 23, 2024
6af1eff
fix: minor cleanup
charislam Jul 23, 2024
761d1d6
fix: minor cleanup and code review suggestions
charislam Aug 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: display params for ref functions
  • Loading branch information
charislam committed Aug 12, 2024
commit b1147916973243ef81e36b9cfdc3db7875b0e68a
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 203,7 @@ const menus: Menu[] = [
},
]

export function getMenuById(id: MenuId) {
function getMenuById(id: MenuId) {
return menus.find((menu) => menu.id === id)
}

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/features/docs/Reference.sdkPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 39,8 @@ function ClientSdkReferencePage({
}
>
<LayoutMainContent>
<article>
<ClientLibHeader menuData={menuData} className="mb-8" />
<article className="@container/article">
<ClientLibHeader menuData={menuData} className="mt-4 mb-8" />
<ClientLibIntroduction libPath={libPath} excludeName={libId} />
<ClientLibRefSections
libPath={libPath}
Expand Down
49 changes: 40 additions & 9 deletions apps/docs/features/docs/Reference.sections.tsx
Original file line number Diff line number Diff line change
@@ -1,13 1,16 @@
import type { AbbrevCommonClientLibSection } from '~/features/docs/Reference.utils'
import type { MethodTypes } from '~/features/docs/Reference.typeSpec'

import { Fragment } from 'react'

import { getRefMarkdown, MDXRemoteRefs } from '~/features/docs/Reference.mdx'
import type { MethodTypes } from '~/features/docs/Reference.typeSpec'
import { getTypeSpec } from '~/features/docs/Reference.typeSpec'
import { RefSubLayout } from '~/features/docs/Reference.ui'
import { FnParameterDetails, RefSubLayout } from '~/features/docs/Reference.ui'
import { StickyHeader } from './Reference.ui.client'
import { genClientSdkSectionTree, getSpecFnsCached } from '~/features/docs/Reference.utils'
import type { AbbrevCommonClientLibSection } from '~/features/docs/Reference.utils'
import {
genClientSdkSectionTree,
getSpecFnsCached,
normalizeMarkdown,
} from '~/features/docs/Reference.utils'

interface ClientLibRefSectionsProps {
libPath: string
Expand Down Expand Up @@ -137,11 140,39 @@ async function FunctionSection({ link, section, specFile, useTypeSpec }: Functio
types = await getTypeSpec(fn['$ref'] as string)
}

const fullDescription = [
types?.comment?.shortText,
'description' in fn && (fn.description as string),
'notes' in fn && (fn.notes as string),
]
.filter(Boolean)
.map(normalizeMarkdown)
.join('\n\n')

return (
<RefSubLayout.Section {...section}>
<StickyHeader {...section} link={link} scrollSpyHeader />
<pre>{JSON.stringify(fn, null, 2)}</pre>
<pre>{JSON.stringify(types, null, 2)}</pre>
<RefSubLayout.Section columns="double" {...section}>
<StickyHeader {...section} link={link} scrollSpyHeader className="col-[1_/_-1]" />
<div className="overflow-hidden flex flex-col gap-8">
<div className="prose break-words text-sm">
<MDXRemoteRefs source={fullDescription} />
</div>
<FnParameterDetails
parameters={
'overwriteParams' in fn
? (fn.overwriteParams as Array<object>).map((overwrittenParams) => ({
...overwrittenParams,
__overwritten: true,
}))
: types?.params
}
altParameters={types?.altSignatures?.map(({ params }) => params)}
className="max-w-[80ch]"
/>
<pre className="text-sm">{JSON.stringify(fn, null, 2)}</pre>
</div>
<div className="overflow-hidden">
<pre className="text-sm">{JSON.stringify(types, null, 2)}</pre>
</div>
</RefSubLayout.Section>
)
}
Expand Down
79 changes: 50 additions & 29 deletions apps/docs/features/docs/Reference.typeSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 37,33 @@ interface ModuleTypes {
export interface MethodTypes {
name: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
params: Array<ParamType>
params: Array<FunctionParameterType>
ret: ReturnType | undefined
altSignatures?: [
{
params: Array<FunctionParameterType>
ret: ReturnType | undefined
},
]
}

interface Comment {
shortText?: string
text?: string
}

interface ParamType {
export interface FunctionParameterType {
name: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
isOptional?: boolean
type: Type | undefined
type: TypeDetails | undefined
}

interface ReturnType {
type: Type | undefined
type: TypeDetails | undefined
}

type Type = IntrinsicType | LiteralType | CustomType
export type TypeDetails = IntrinsicType | LiteralType | CustomType

/**
* Type definition for an intrinsic (built-in) TypeScript type, for example,
Expand Down Expand Up @@ -91,65 97,65 @@ interface NameOnlyType {
}

interface CustomObjectType {
type: 'customObject'
type: 'object'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
properties: Array<PropertyType>
properties: Array<CustomTypePropertyType>
}

interface CustomUnionType {
type: 'customUnion'
export interface CustomUnionType {
type: 'union'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
subTypes: Array<Type>
subTypes: Array<TypeDetails>
}

interface CustomFunctionType {
type: 'function'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
params: Array<ParamType>
params: Array<FunctionParameterType>
ret: ReturnType | undefined
}

interface ArrayType {
type: 'array'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
elemType: Type | undefined
elemType: TypeDetails | undefined
}

interface RecordType {
type: 'record'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
keyType: Type | undefined
valueType: Type | undefined
keyType: TypeDetails | undefined
valueType: TypeDetails | undefined
}

interface IndexSignatureType {
type: 'index signature'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
keyType: Type | undefined
valueType: Type | undefined
keyType: TypeDetails | undefined
valueType: TypeDetails | undefined
}

interface PromiseType {
type: 'promise'
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
awaited: Type | undefined
awaited: TypeDetails | undefined
}

/**
* Type definition for a property on a custom type definition.
*/
interface PropertyType {
export interface CustomTypePropertyType {
name?: string | typeof TYPESPEC_NODE_ANONYMOUS
comment?: Comment
isOptional?: boolean
type: Type | undefined
type: TypeDetails | undefined
}

// The following is the API of this module, and the only externally exposed
Expand Down Expand Up @@ -316,17 322,23 @@ function parseMethod(
comment,
}

if (node.signatures.length > 1) {
types.altSignatures = node.signatures
.slice(1)
.map((signature) => parseSignature(signature, map))
}

res.methods.set($ref, types)
}

function parseSignature(
signature: any,
map: Map<number, any>
): { params: Array<ParamType>; ret: ReturnType; comment?: Comment } {
const params: Array<ParamType> = (signature.parameters ?? []).map((param: any) => {
): { params: Array<FunctionParameterType>; ret: ReturnType; comment?: Comment } {
const params: Array<FunctionParameterType> = (signature.parameters ?? []).map((param: any) => {
const type = parseType(param.type, map)

const res: ParamType = {
const res: FunctionParameterType = {
name: nameOrAnonymous(param),
type,
}
Expand Down Expand Up @@ -447,6 459,10 @@ function parseReferenceType(type: any, map: Map<number, any>) {
return parsePromiseType(type, map)
}

if (type.package === 'typescript' && type.qualifiedName === 'Extract') {
return parseExtractType(type, map)
}

if (type.package && type.qualifiedName) {
return {
type: 'nameOnly',
Expand Down Expand Up @@ -500,7 516,7 @@ function parseUnionType(type: any, map: Map<number, any>): CustomUnionType {
const subTypes = type.types.filter(Boolean).map((type) => parseType(type, map))

return {
type: 'customUnion',
type: 'union',
name: nameOrAnonymous(type),
subTypes,
}
Expand All @@ -525,10 541,15 @@ function parsePromiseType(type: any, map: Map<number, any>): PromiseType {
}
}

function parseExtractType(type: any, map: Map<number, any>): CustomUnionType {
const extractedUnion = parseUnionType(type.typeArguments[1], map)
return extractedUnion
}

function parseReflectionType(type: any, map: Map<number, any>) {
if (!type.declaration) return undefined

let res: Type
let res: TypeDetails
switch (type.declaration.kindString) {
case 'Type literal':
res = parseTypeLiteral(type, map)
Expand All @@ -540,14 561,14 @@ function parseReflectionType(type: any, map: Map<number, any>) {
return res
}

function parseTypeLiteral(type: any, map: Map<number, any>): Type {
function parseTypeLiteral(type: any, map: Map<number, any>): TypeDetails {
const name = nameOrAnonymous(type)

if ('children' in type.declaration) {
const properties = type.declaration.children.map((child: any) => parseTypeInternals(child, map))
return {
name,
type: 'customObject',
type: 'object',
properties,
} satisfies CustomObjectType
}
Expand Down Expand Up @@ -582,7 603,7 @@ function parseTypeLiteral(type: any, map: Map<number, any>): Type {
function parseIndexedAccessType(type: any, map: Map<number, any>) {
return {
type: 'nameOnly',
name: `${type.objectType?.name ?? ''}[${type.indexType.value ?? type.indexType.name ?? ''}]`,
name: `${type.objectType?.name ?? ''}['${type.indexType.value ?? type.indexType.name ?? ''}']`,
}
}

Expand All @@ -599,7 620,7 @@ function parseInterface(type: any, map: Map<number, any>): CustomObjectType {
const properties = (type.children ?? []).map((child) => parseTypeInternals(child, map))

return {
type: 'customObject',
type: 'object',
name: nameOrAnonymous(type),
properties,
}
Expand Down Expand Up @@ -641,7 662,7 @@ function parseInternalProperty(elem: any, map: Map<number, any>) {
const res = {
name,
type,
} as PropertyType
} as CustomTypePropertyType

if (elem.flags?.isOptional) {
res.isOptional = true
Expand Down
7 changes: 5 additions & 2 deletions apps/docs/features/docs/Reference.ui.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 12,7 @@ interface StickyHeaderProps {
*/
link?: string
monoFont?: boolean
className?: string
/**
* Whether the header updates the URL on scroll
*/
Expand All @@ -27,13 28,14 @@ function StickyHeader({
slug,
link,
monoFont = false,
className,
scrollSpyHeader = false,
crawlerPage = false,
}: StickyHeaderProps) {
const { ref } = useInView({
threshold: 1,
rootMargin: '0% 0% -50% 0%',
onChange: (inView, entry) => {
onChange: (inView) => {
if (inView && scrollSpyHeader) {
window.history.replaceState(null, '', link)
}
Expand All @@ -53,7 55,8 @@ function StickyHeader({
'text-2xl font-medium text-foreground',
'mt-0',
'scroll-mt-[calc(33px 2rem)] lg:scroll-mt-[calc(var(--header-height) 1px 4rem)]',
monoFont && 'font-mono'
monoFont && 'font-mono',
className
)}
>
{title}
Expand Down
Loading