Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .changeset/thick-singers-pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### `createDomain()`

Creates a new domain.

Returns an [`OrganizationDomainResource`](/docs/reference/types/organization-domain-resource) object.

> [!WARNING]
> You must have [**Verified domains**](/docs/guides/organizations/add-members/verified-domains) enabled in your app's settings in the Clerk Dashboard.

```typescript
function createDomain(domainName: string, params?: Pick<CreateOrganizationDomainParams, "enrollmentMode">): Promise<OrganizationDomainResource>
```

#### Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `domainName` | `string` | The name of the domain to create. |
| `params?` | `Pick`\<`CreateOrganizationDomainParams`, `"enrollmentMode"`\> | Optional parameters, including the `enrollmentMode` to assign to the new domain. |
| `params?.enrollmentMode?` | <code>"manual_invitation" \| "automatic_invitation" \| "automatic_suggestion" \| "enterprise_sso"</code> | The enrollment mode that determines how matching users are added to the Organization. Defaults to `manual_invitation`. |
31 changes: 31 additions & 0 deletions .typedoc/__tests__/custom-theme.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ReflectionKind, type Type } from 'typedoc';
import { describe, expect, it } from 'vitest';

import { getParameterObjectShapeDeclaration } from '../custom-theme.mjs';

describe('getParameterObjectShapeDeclaration', () => {
it('does not resolve Pick sources whose declaration kind is unsupported', () => {
const sourceType = {
type: 'reference',
name: 'ExampleClass',
reflection: {
kind: ReflectionKind.Class,
children: [
{
name: 'someMethodName',
kind: ReflectionKind.Method,
signatures: [{}],
},
],
},
} as unknown as Type;
const pickType = {
type: 'reference',
name: 'Pick',
package: 'typescript',
typeArguments: [sourceType, { type: 'literal', value: 'someMethodName' }],
} as unknown as Type;

expect(getParameterObjectShapeDeclaration(pickType)).toBeUndefined();
});
});
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/sign-out.mdx` – simple zero-arg callable
* - `methods/handle-redirect-callback.mdx` – multi-param `parametersTable` with nested rows
* - `methods/handle-email-link-verification.mdx` – required parent (`params`) flattened to `.`
* - `methods/create-domain.mdx` – `Pick<T, K>` parameter flattened to only the selected property
* - `methods/join-waitlist.mdx` – single nominal-param section (`JoinWaitlistParams`)
* - `methods/create.mdx` (api-key) – another single-nominal-param case + warning callout
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
Expand Down Expand Up @@ -45,6 +46,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-methods-handle-email-link-verification.mdx');
});

it('Pick parameter includes only selected properties without linking the full type: organization.createDomain()', async () => {
const content = await readGenerated('shared/organization-resource/methods/create-domain.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/organization-resource-methods-create-domain.mdx');
});

it('single nominal-param section: clerk.joinWaitlist()', async () => {
const content = await readGenerated('shared/clerk/methods/join-waitlist.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-methods-join-waitlist.mdx');
Expand Down
103 changes: 100 additions & 3 deletions .typedoc/custom-theme.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,51 @@ function hasDefaultValuesForParameters(parameters) {
}

/**
* Object shape for a parameter: inline `{ … }`, optional-wrapped, or reference to a type alias / interface.
* Collects string literal members from a type used as `Pick`'s key argument.
*
* @param {import('typedoc').Type | undefined} t
* @returns {string[] | undefined}
*/
function getPickPropertyNames(t) {
const unwrapped = unwrapOptional(t);
if (!unwrapped || typeof unwrapped !== 'object') {
return undefined;
}
if (unwrapped.type === 'literal') {
const literal = /** @type {import('typedoc').LiteralType} */ (unwrapped);
if (typeof literal.value === 'string') {
return [literal.value];
}
return undefined;
}
if (!isUnionTypeDoc(unwrapped)) {
return undefined;
}
const names = [];
const union = /** @type {import('typedoc').UnionType} */ (unwrapped);
for (const type of union.types) {
const nestedNames = getPickPropertyNames(type);
if (!nestedNames) {
return undefined;
}
names.push(...nestedNames);
}
return names;
}

/**
* @param {import('typedoc').Type | undefined} t
* @returns {boolean}
*/
function isPickReferenceType(t) {
if (!isReferenceTypeDoc(t)) {
return false;
}
return t.name === 'Pick' && t.package === 'typescript' && t.typeArguments?.length === 2;
}

/**
* Object shape for a parameter: inline `{ … }`, optional-wrapped, reference to a type alias / interface, or `Pick<T, K>` with literal keys.
*
* @param {import('typedoc').Type | undefined} t
* @returns {import('typedoc').DeclarationReflection | undefined}
Expand All @@ -470,6 +514,37 @@ function getParameterObjectShapeDeclaration(t) {
}
if (o.type === 'reference') {
const ref = /** @type {import('typedoc').ReferenceType} */ (t);
if (isPickReferenceType(ref)) {
const [sourceType, keysType] = /** @type {[import('typedoc').Type, import('typedoc').Type]} */ (
ref.typeArguments
);
const propertyNames = getPickPropertyNames(keysType);
if (!propertyNames?.length) {
return undefined;
}
const sourceDecl = getParameterObjectShapeDeclaration(sourceType);
const sourceRef = sourceType.type === 'reference' ? sourceType.reflection : undefined;
const sourceWithChildren =
sourceDecl ??
(sourceRef &&
(sourceRef.kind === ReflectionKind.TypeAlias || sourceRef.kind === ReflectionKind.Interface) &&
'children' in sourceRef
? /** @type {import('typedoc').DeclarationReflection} */ (sourceRef)
: undefined);
if (!sourceWithChildren?.children?.length) {
return undefined;
}
const selected = new Set(propertyNames);
const children = sourceWithChildren.children.filter(child => selected.has(child.name));
if (children.length !== selected.size) {
return undefined;
}
return /** @type {import('typedoc').DeclarationReflection} */ ({
...sourceWithChildren,
kind: ReflectionKind.TypeLiteral,
children,
});
}
const sym = ref.reflection;
if (!sym) {
return undefined;
Expand Down Expand Up @@ -504,6 +579,27 @@ function shouldFlattenInlineObjectParameter(decl) {
return Boolean(only?.comment?.hasVisibleComponent());
}

/**
* Whether a parameter is a built-in `Pick<T, K>` that will be flattened into nested rows. Its source type should not
* link to the full unpicked declaration, which documents properties the parameter does not accept.
*
* @param {import('typedoc').Type | undefined} t
*/
function isFlattenedPickParameter(t) {
const unwrapped = unwrapOptional(t);
if (!isPickReferenceType(unwrapped)) {
return false;
}
return shouldFlattenInlineObjectParameter(getParameterObjectShapeDeclaration(t));
}

/**
* @param {string} value
*/
function stripMarkdownLinks(value) {
return value.replace(/\[([^\[\]]*)\]\((.*?)\)/gm, '$1');
}

/**
* Same as typedoc-plugin-markdown `member.parametersTable`, with `shouldFlattenInlineObjectParameter` and `getParameterObjectShapeDeclaration`.
*
Expand Down Expand Up @@ -581,12 +677,13 @@ function clerkParametersTable(model) {
const optional = isOptional ? '?' : '';
row.push(`${rest}${backTicks(`${parameter.name}${optional}`)}`);
if (parameter.type) {
const displayType =
const renderedType =
parameter.type instanceof ReflectionType
? this.partials.reflectionType(parameter.type, {
forceCollapse: true,
})
: this.partials.someType(parameter.type);
const displayType = isFlattenedPickParameter(parameter.type) ? stripMarkdownLinks(renderedType) : renderedType;
row.push(removeLineBreaks(displayType));
}
if (showDefaults) {
Expand Down Expand Up @@ -1954,4 +2051,4 @@ function isCallablePropertyValueType(t, helpers, seenReflectionIds) {
return false;
}

export { isCallableInterfaceProperty };
export { getParameterObjectShapeDeclaration, isCallableInterfaceProperty };
Loading