Skip to content
Merged
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
4 changes: 2 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/",
"extract-api": "api-extractor run --local",
"generate-docs": "api-extractor run --local && yarn api-documenter markdown -i ./temp -o ./docs && yarn generate-snippets",
"generate:md-docs": "yarn api-documenter markdown -i ./temp -o ./docs",
"generate-snippets": "node ./scripts/generate-snippets.mjs",
"generate-snippets": "node ./scripts/generate-snippets.mjs && node ./scripts/generate-feature-snippets.mjs",
"build": "tsc && preconstruct build",
"e2e": "yarn test-ct",
"test-ct": "playwright test -c playwright-ct.config.ts"
Expand Down
165 changes: 165 additions & 0 deletions packages/react/scripts/generate-feature-snippets.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import {
TSDocParser,
DocExcerpt,
TSDocConfiguration,
TSDocTagSyntaxKind,
TSDocTagDefinition,
} from "@microsoft/tsdoc";
import fs from "fs";

/**
* This is a simplistic solution until we implement proper DocNode rendering APIs.
*/
export class Formatter {
static renderDocNode(docNode) {
let result = "";
if (docNode) {
if (docNode instanceof DocExcerpt) {
result += docNode.content.toString();
}
for (const childNode of docNode.getChildNodes()) {
result += Formatter.renderDocNode(childNode);
}
}
return result;
}

static renderDocNodes(docNodes) {
let result = "";
for (const docNode of docNodes) {
result += Formatter.renderDocNode(docNode);
}
return result;
}
}

const config = new TSDocConfiguration();
const tag = new TSDocTagDefinition({
tagName: "@twfeature",
allowMultiple: true,
syntaxKind: TSDocTagSyntaxKind.BlockTag,
});
config.addTagDefinition(tag);
config.setSupportForTag(tag, true);
const tsdocParser = new TSDocParser(config);

const json = JSON.parse(
fs.readFileSync(`${process.cwd()}/temp/react.api.json`, "utf8"),
);

function languageNameToKey(languageName) {
switch (languageName) {
case "js":
case "jsx":
return "javascript";
case "ts":
case "tsx":
return "tyepscript";
default:
return languageName;
}
}

// Get all the DetectableFeature classes
const classes = json.members[0].members;
const features = {};

function parseExampleTag(docComment) {
const exampleBlocks = docComment._customBlocks.filter(
(b) => b._blockTag._tagName === "@example",
);

const examplesString = Formatter.renderDocNodes(exampleBlocks);

const regex = /```([a-zA-Z]*)\n([\S\s]*?)\n```/g;

let matches;

const examples = {};

while ((matches = regex.exec(examplesString)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
examples[languageNameToKey(matches[1])] = matches[2];
}
return examples;
}

function parseTWFeatureTag(docComment) {
const featureBlocks = docComment._customBlocks.filter(
(b) => b._blockTag._tagName === "@twfeature",
);

const featuresString = Formatter.renderDocNodes(featureBlocks);
return featuresString.split(" | ").map((f) =>
f
.trim()
.replace(/\\n/g, "")
.replace("\n\n", "")
.replace(/`/g, "")
.replace(/@twfeature/g, ""),
);
}

const baseDocUrl = "https://docs.thirdweb.com/react/react.";

const extractReferenceLink = (m, kind, contractName) => {
if (kind === "Property") {
return m.excerptTokens
.filter((e) => e.kind === "Reference")
.map((e) => `${baseDocUrl}${e.text.toLowerCase()}`)[0];
}
if (kind === "Method") {
return `${baseDocUrl}${contractName}.${m.name}`.toLowerCase();
}
return `${baseDocUrl}${m.name}`.toLowerCase();
};

const parseMembers = (members, kind, contractName) => {
if (!members) {
return [];
}

members = [members];

const validMembers = members.filter((m) => m.kind === kind);
return validMembers
.map((m) => {
const parserContext = tsdocParser.parseString(m.docComment);
const docComment = parserContext.docComment;
const featureNames = parseTWFeatureTag(docComment);
if (featureNames.length > 0) {
for (const feature of featureNames) {
const examples = parseExampleTag(docComment);
if (Object.keys(examples).length > 0) {
const example = {
name: m.name,
summary: Formatter.renderDocNode(docComment.summarySection),
remarks: docComment.remarksBlock
? Formatter.renderDocNode(docComment.remarksBlock.content)
: null,
examples,
reference: {
javascript: extractReferenceLink(m, kind, contractName),
},
};
features[feature] = features[feature]
? features[feature].concat(example)
: [example];
}
}
}
})
.filter((m) => !!m);
};

classes.forEach((m) => {
parseMembers(m, "Function", m.name);
});

fs.writeFileSync(
`${process.cwd()}/docs/feature_snippets.json`,
JSON.stringify(features, null, 2),
);
8 changes: 5 additions & 3 deletions packages/react/src/hooks/async/claim-conditions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export type SetClaimConditionsParams = {
* @param contract - an instance of a contract that extends the ERC721 or ERC1155 spec and implements the `claimConditions` extension.
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
* @returns a response object with the currently active claim condition
*
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
* @beta
*/
export function useActiveClaimCondition(
Expand Down Expand Up @@ -113,7 +113,7 @@ export function useActiveClaimCondition(
* @param contract - an instance of a contract that extends the ERC721 or ERC1155 spec and implements the `claimConditions` extension.
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
* @returns a response object with the list of claim conditions
*
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
* @beta
*/
export function useClaimConditions(
Expand Down Expand Up @@ -166,7 +166,7 @@ export function useClaimConditions(
* @param eligibilityParams - the parameters for the eligibility check, see: {@link ClaimIneligibilityParams}
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
* @returns a response object with the resons for the claim ineligibility
*
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
* @beta
*/
export function useClaimIneligibilityReasons(
Expand Down Expand Up @@ -257,6 +257,7 @@ export function useClaimIneligibilityReasons(
*
* @param contract - an instance of a {@link DropContract}
* @returns a mutation object that can be used to set claim conditions
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
* @beta
*/
export function useSetClaimConditions(
Expand Down Expand Up @@ -327,6 +328,7 @@ export function useSetClaimConditions(
*
* @param contract - an instance of a {@link DropContract}
* @returns a mutation object that can be used to reset claim conditions
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
* @beta
*/
export function useResetClaimConditions(
Expand Down
8 changes: 8 additions & 0 deletions packages/react/src/hooks/async/contract-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import invariant from "tiny-invariant";
* Use this to get the primary sales recipient of your {@link SmartContract}
* @param contract - an instance of a {@link SmartContract}
* @returns the wallet address of the primary sales recipient
* @twfeature PrimarySale
* @beta
*/
export function usePrimarySaleRecipient(
Expand Down Expand Up @@ -73,6 +74,7 @@ export function usePrimarySaleRecipient(
*
* @param contract - an instance of a {@link SmartContract}
* @returns a mutation object that can be used to update the primary sales recipient
* @twfeature PrimarySale
* @beta
*/
export function useUpdatePrimarySaleRecipient(
Expand Down Expand Up @@ -115,6 +117,7 @@ export function useUpdatePrimarySaleRecipient(
*
* @param contract - an instance of a {@link SmartContract}
* @returns an object containing recipient address and the royalty basis points
* @twfeature Royalty
* @beta
*/
export function useRoyaltySettings(
Expand Down Expand Up @@ -164,6 +167,7 @@ export function useRoyaltySettings(
*
* @param contract - an instance of a {@link SmartContract}
* @returns a mutation object that can be used to update the royalty settings
* @twfeature Royalty
* @beta
*/
export function useUpdateRoyaltySettings(
Expand Down Expand Up @@ -209,6 +213,7 @@ export function useUpdateRoyaltySettings(
*
* @param contract - an instance of a {@link SmartContract}
* @returns an object containing the platform fee basis points and the fee recipient address
* @twfeature PlatformFee
* @beta
*/
export function usePlatformFees(
Expand Down Expand Up @@ -257,6 +262,7 @@ export function usePlatformFees(
* ```
* @param contract - an instance of a {@link SmartContract}
* @returns a mutation object that can be used to update the platform fees settings
* @twfeature PlatformFee
* @beta
*/
export function useUpdatePlatformFees(
Expand Down Expand Up @@ -302,6 +308,7 @@ export function useUpdatePlatformFees(
*
* @param contract - an instance of a {@link SmartContract}
* @returns a {@link CustomContractMetadata} object containing the metadata
* @twfeature ContractMetadata
* @beta
*/
export function useMetadata(contract: RequiredParam<ValidContractInstance>) {
Expand Down Expand Up @@ -347,6 +354,7 @@ export function useMetadata(contract: RequiredParam<ValidContractInstance>) {
* ```
* @param contract - an instance of a {@link SmartContract}
* @returns a mutation object that can be used to update the metadata
* @twfeature ContractMetadata
* @beta
*/
export function useUpdateMetadata(
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/hooks/async/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export function useContract<
*
* @param contract - the {@link ValidContractInstance} instance of the contract to get the metadata for
* @returns a response object that includes the contract metadata of the deployed contract
* @twfeature ContractMetadata
* @beta
*/
export function useContractMetadata(
Expand Down
11 changes: 11 additions & 0 deletions packages/react/src/hooks/async/drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import invariant from "tiny-invariant";
* @param contract - an instance of a contract that extends the Erc721 spec (nft drop, custom contract that follows the Erc721 & drop spec)
* @param queryParams - query params to pass to the query for the sake of pagination
* @returns a response object that includes an array of NFTs that are unclaimed
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
* @beta
*/
export function useUnclaimedNFTs(
Expand Down Expand Up @@ -75,6 +76,7 @@ export function useUnclaimedNFTs(
* @param contract - an instance of a {@link DropContract}
* @param queryParams - query params to pass to the query for the sake of pagination
* @returns a response object that includes an array of NFTs that are claimed
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
* @beta
*/
export function useClaimedNFTs(
Expand All @@ -83,10 +85,12 @@ export function useClaimedNFTs(
) {
return useNFTs(contract, queryParams);
}

/**
*
* @param contract - an instance of a {@link NFTDrop}
* @returns a response object that includes the number of NFTs that are unclaimed
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
*/
export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
const contractAddress = contract?.getAddress();
Expand All @@ -106,9 +110,11 @@ export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
}

/**

*
* @param contract - an instance of a {@link DropContract}
* @returns a response object that includes the number of NFTs that are claimed
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
*/
export function useClaimedNFTSupply(contract: RequiredParam<DropContract>) {
const contractAddress = contract?.getAddress();
Expand All @@ -131,6 +137,7 @@ export function useClaimedNFTSupply(contract: RequiredParam<DropContract>) {
*
* @param contract - an instance of a {@link RevealableContract}
* @returns a response object that gets the batches to still be revealed
* @twfeature ERC721Revealable | ERC1155Revealable
*/
export function useBatchesToReveal<TContract extends RevealableContract>(
contract: RequiredParam<TContract>,
Expand Down Expand Up @@ -185,6 +192,7 @@ export function useBatchesToReveal<TContract extends RevealableContract>(
*
* @param contract - an instance of a {@link DropContract}
* @returns a mutation object that can be used to claim a NFT to the wallet specificed in the params
* @twfeature ERC721Claimable | ERC1155Claimable
* @beta
*/
export function useClaimNFT<TContract extends DropContract>(
Expand Down Expand Up @@ -236,6 +244,7 @@ export function useClaimNFT<TContract extends DropContract>(
* @param contract - an instance of a {@link NFTContract} with the drop extension
* @param onProgress - an optional callback that will be called with the progress of the upload
* @returns a mutation object that can be used to lazy mint a batch of NFTs
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
* @beta
*/
export function useLazyMint<TContract extends DropContract>(
Expand Down Expand Up @@ -282,6 +291,7 @@ export function useLazyMint<TContract extends DropContract>(
* @param contract - an instance of a {@link DropContract}
* @param onProgress - an optional callback that will be called with the progress of the upload
* @returns a mutation object that can be used to lazy mint a batch of NFTs
* @twfeature ERC721Revealable | ERC1155Revealable
* @beta
*/
export function useDelayedRevealLazyMint<TContract extends RevealableContract>(
Expand Down Expand Up @@ -336,6 +346,7 @@ export function useDelayedRevealLazyMint<TContract extends RevealableContract>(
*
* @param contract - an instance of a {@link RevealableContract}
* @returns a mutation object that can be used to reveal a batch of delayed reveal NFTs
* @twfeature ERC721Revealable | ERC1155Revealable
* @beta
*/
export function useRevealLazyMint<TContract extends RevealableContract>(
Expand Down
Loading