From 467e503306716cebd9e94198fe430e8d91e38133 Mon Sep 17 00:00:00 2001 From: ghostrider-05 Date: Fri, 18 Oct 2024 16:45:05 +0200 Subject: [PATCH] update format in schemas --- eslint.config.mjs | 8 ++++ src/schemas/v2/api/components/schemas.ts | 50 ++++----------------- src/schemas/v2/generated/openapi.json | 57 +++++++++++++++--------- src/schemas/v2/resources/address.ts | 6 ++- src/schemas/v2/resources/benefit.ts | 7 ++- src/schemas/v2/resources/campaign.ts | 10 ++++- src/schemas/v2/resources/deliverable.ts | 7 ++- src/schemas/v2/resources/media.ts | 11 ++++- src/schemas/v2/resources/member.ts | 9 +++- src/schemas/v2/resources/oauth_client.ts | 10 ++++- src/schemas/v2/resources/pledge_event.ts | 10 ++++- src/schemas/v2/resources/post.ts | 8 +++- src/schemas/v2/resources/tier.ts | 11 ++++- src/schemas/v2/resources/user.ts | 14 ++++-- src/schemas/v2/resources/webhook.ts | 10 ++++- src/schemas/v2/scripts/shared.ts | 6 +++ 16 files changed, 156 insertions(+), 78 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index ac799ce..38921af 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -32,6 +32,14 @@ export default [ jsdoc, }, rules: { + 'jsdoc/check-tag-names': [ + 'warn', + { + definedTags: [ + 'format', + ] + } + ], 'no-trailing-spaces': [ 'error' ], diff --git a/src/schemas/v2/api/components/schemas.ts b/src/schemas/v2/api/components/schemas.ts index f145a1e..36104a6 100644 --- a/src/schemas/v2/api/components/schemas.ts +++ b/src/schemas/v2/api/components/schemas.ts @@ -1,5 +1,5 @@ import { PatreonWebhookTrigger, Type } from '../../../../v2' -import { getJsDocDescription, getTypes } from '../../scripts/shared' +import { getJsDocDescription, getJsDocTags, getTypes } from '../../scripts/shared' interface ResourceSchemaOptions { schemas: T[] @@ -8,14 +8,13 @@ interface ResourceSchemaOptions { interfaceName: string fileName: string documentation: Record<'description' | 'url', string> - formatMap?: Record } } // eslint-disable-next-line jsdoc/require-jsdoc function createResourceSchemas (options: ResourceSchemaOptions) { return options.schemas.reduce((schemas, schema) => { - const { documentation, fileName, interfaceName, formatMap } = options.getDetails(schema) + const { documentation, fileName, interfaceName } = options.getDetails(schema) const declaration = getTypes(`${options.folder}${fileName}.ts`) .getInterfaceOrThrow(interfaceName) @@ -31,10 +30,8 @@ function createResourceSchemas (options: ResourceSchemaOption const type = property.getType().getNonNullableType(), nullType = 'null' const nullable = property.getType().isNullable() const baseType = type.getBaseTypeOfLiteralType().getText() - const format = formatMap?.[property.getName()] - const examples = property.getJsDocs().at(0)?.getTags() - .filter(tag => tag.getTagName() === 'example') - .map(tag => tag.getCommentText()) + const format = getJsDocTags(property, 'format')?.at(0) + const examples = getJsDocTags(property, 'example') return { ...properties, @@ -55,7 +52,10 @@ function createResourceSchemas (options: ResourceSchemaOption ), ...(format != undefined ? { format } : {}), description: getJsDocDescription(property), - ...(examples != undefined && examples.length ? { examples: examples } : {}), + ...(examples != undefined && examples.length + ? { examples: baseType === 'number' ? examples.map(Number) : examples } + : {} + ), } } }, {}) @@ -83,40 +83,6 @@ export default { description: `Official documentation for the ${interfaceName} resource`, url: `https://docs.patreon.com/#${header}` }, - // TODO: temperary solution to use this map - formatMap: { - 'created_at': 'date-time', - 'next_deliverable_due_date': 'date-time', - 'completed_at': 'date-time', - 'due_at': 'date-time', - 'reached_at': 'date-time', - 'upload_expires_at': 'date-time', - 'last_charge_date': 'date-time', - 'next_charge_date': 'date-time', - 'pledge_relationship_start': 'date-time', - 'published_at': 'date-time', - 'edited_at': 'date-time', - 'date': 'date-time', - 'unpublished_at': 'date-time', - 'created': 'date-time', - 'last_attempted_at': 'date-time', - 'image_small_url': 'uri', - 'image_url': 'uri', - 'main_video_url': 'uri', - // Campaign.pledge_url is relative, so not typed as uri - 'rss_artwork_url': 'uri', - 'thanks_video_url': 'uri', - 'download_url': 'uri', - 'upload_url': 'uri', - 'icon_url': 'uri', - 'privacy_policy_url': 'uri', - // 'redirect_uris': 'uri', - 'tos_url': 'uri', - 'embed_url': 'uri', - 'url': 'uri', - 'thumb_url': 'uri', - 'uri': 'uri', - } } } }), diff --git a/src/schemas/v2/generated/openapi.json b/src/schemas/v2/generated/openapi.json index 0056fc5..4cfada4 100644 --- a/src/schemas/v2/generated/openapi.json +++ b/src/schemas/v2/generated/openapi.json @@ -2503,7 +2503,7 @@ "address": { "type": "object", "title": "Address", - "description": "", + "description": "A patron's shipping address.", "externalDocs": { "description": "Official documentation for the Address resource", "url": "https://docs.patreon.com/#address" @@ -2569,7 +2569,7 @@ "benefit": { "type": "object", "title": "Benefit", - "description": "", + "description": "A benefit added to the campaign, which can be added to a tier to be delivered to the patron.", "externalDocs": { "description": "Official documentation for the Benefit resource", "url": "https://docs.patreon.com/#benefit" @@ -2832,7 +2832,7 @@ "client": { "type": "object", "title": "OauthClient", - "description": "", + "description": "A client created by a developer, used for getting OAuth2 access tokens.", "externalDocs": { "description": "Official documentation for the OauthClient resource", "url": "https://docs.patreon.com/#oauthclient" @@ -2862,6 +2862,7 @@ "string", "null" ], + "format": "uri", "description": "The domain provided during client setup." }, "icon_url": { @@ -2895,14 +2896,17 @@ }, "version": { "type": "number", - "description": "The Patreon API version the client is targeting." + "description": "The Patreon API version the client is targeting.", + "examples": [ + 2 + ] } } }, "deliverable": { "type": "object", "title": "Deliverable", - "description": "", + "description": "The record of whether or not a patron has been delivered the benefit they are owed because of their member tier.", "externalDocs": { "description": "Official documentation for the Deliverable resource", "url": "https://docs.patreon.com/#deliverable" @@ -2945,7 +2949,7 @@ "media": { "type": "object", "title": "Media", - "description": "", + "description": "A file uploaded to patreon.com, usually an image.", "externalDocs": { "description": "Official documentation for the Media resource", "url": "https://docs.patreon.com/#media" @@ -2963,7 +2967,7 @@ }, "file_name": { "type": "string", - "description": "" + "description": "File name." }, "image_urls": { "type": "object", @@ -3019,7 +3023,7 @@ "member": { "type": "object", "title": "Member", - "description": "", + "description": "The record of a user's membership to a campaign.\nRemains consistent across months of pledging.", "externalDocs": { "description": "Official documentation for the Member resource", "url": "https://docs.patreon.com/#member" @@ -3104,7 +3108,7 @@ "type": "number", "description": "Number of months between charges\n\nNote: this will be `1` if Campaign.is_monthly is `true`", "examples": [ - "1" + 1 ] }, "pledge_relationship_start": { @@ -3119,7 +3123,7 @@ "type": "number", "description": "The amount in cents the user will pay at the next pay cycle", "examples": [ - "500" + 500 ] } } @@ -3127,7 +3131,7 @@ "post": { "type": "object", "title": "Post", - "description": "", + "description": "Content posted by a creator on a campaign page.", "externalDocs": { "description": "Official documentation for the Post resource", "url": "https://docs.patreon.com/#post-v2" @@ -3215,7 +3219,7 @@ "pledge-event": { "type": "object", "title": "PledgeEvent", - "description": "", + "description": "The record of a pledging action taken by the user, or that action's failure.", "externalDocs": { "description": "Official documentation for the PledgeEvent resource", "url": "https://docs.patreon.com/#pledge-event" @@ -3223,7 +3227,10 @@ "properties": { "amount_cents": { "type": "number", - "description": "Amount (in the currency in which the patron paid) of the underlying event" + "description": "Amount (in the currency in which the patron paid) of the underlying event", + "examples": [ + 500 + ] }, "currency_code": { "type": "string", @@ -3269,14 +3276,14 @@ "pledge_delete", "subscription" ], - "description": "" + "description": "Event type." } } }, "tier": { "type": "object", "title": "Tier", - "description": "", + "description": "A membership level on a campaign, which can have benefits attached to it.", "externalDocs": { "description": "Official documentation for the Tier resource", "url": "https://docs.patreon.com/#tier" @@ -3375,7 +3382,7 @@ "user": { "type": "object", "title": "User", - "description": "", + "description": "The Patreon user, which can be both patron and creator.", "externalDocs": { "description": "Official documentation for the User resource", "url": "https://docs.patreon.com/#user-v2" @@ -3402,6 +3409,7 @@ }, "email": { "type": "string", + "format": "email", "description": "The user's email address.\nRequires certain scopes to access.\nSee the scopes section of the documentation" }, "first_name": { @@ -3409,7 +3417,7 @@ "string", "null" ], - "description": "" + "description": "First name." }, "full_name": { "type": "string", @@ -3436,7 +3444,7 @@ "string", "null" ], - "description": "" + "description": "Last name." }, "like_count": { "type": "number", @@ -3468,7 +3476,7 @@ "webhook": { "type": "object", "title": "Webhook", - "description": "", + "description": "Webhooks are fired based on events happening on a particular campaign.", "externalDocs": { "description": "Official documentation for the Webhook resource", "url": "https://docs.patreon.com/#webhook" @@ -3481,7 +3489,11 @@ }, "num_consecutive_times_failed": { "type": "number", - "description": "Number of times the webhook has failed consecutively, when in an error state." + "description": "Number of times the webhook has failed consecutively, when in an error state.", + "examples": [ + 0, + 2 + ] }, "paused": { "type": "boolean", @@ -3501,7 +3513,10 @@ "uri": { "type": "string", "format": "uri", - "description": "Fully qualified uri where webhook will be sent (e.g. https://www.example.com/webhooks/incoming)." + "description": "Fully qualified uri where webhook will be sent", + "examples": [ + "'https://www.example.com/webhooks/incoming'" + ] } } }, diff --git a/src/schemas/v2/resources/address.ts b/src/schemas/v2/resources/address.ts index 60136a9..93a6f7d 100644 --- a/src/schemas/v2/resources/address.ts +++ b/src/schemas/v2/resources/address.ts @@ -1,3 +1,6 @@ +/** + * A patron's shipping address. + */ export interface Address { /** * Full recipient name @@ -16,6 +19,7 @@ export interface Address { /** * Datetime address was first created + * @format date-time */ created_at: string @@ -43,4 +47,4 @@ export interface Address { * State or province name */ state: string | null -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/benefit.ts b/src/schemas/v2/resources/benefit.ts index 5c945db..2f185a9 100644 --- a/src/schemas/v2/resources/benefit.ts +++ b/src/schemas/v2/resources/benefit.ts @@ -1,3 +1,6 @@ +/** + * A benefit added to the campaign, which can be added to a tier to be delivered to the patron. + */ export interface Benefit { /** * The third-party external ID this reward is associated with @@ -16,6 +19,7 @@ export interface Benefit { /** * Datetime this benefit was created + * @format date-time */ created_at: string @@ -51,6 +55,7 @@ export interface Benefit { /** * The next due date (after EOD today) for this benefit + * @format date-time */ next_deliverable_due_date: string | null @@ -73,4 +78,4 @@ export interface Benefit { * Display title */ title: string -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/campaign.ts b/src/schemas/v2/resources/campaign.ts index aa4d3b6..5d32be1 100644 --- a/src/schemas/v2/resources/campaign.ts +++ b/src/schemas/v2/resources/campaign.ts @@ -10,11 +10,13 @@ export interface Campaign { /** * The url to visit this campaign + * @format uri */ url: string /** * The URL of the video that is shown to patrons after pledging + * @format uri */ thanks_video_url: string | null @@ -47,12 +49,14 @@ export interface Campaign { /** * The url for the rss album artwork + * @format uri */ rss_artwork_url: string | null /** * Datetime that the creator most recently published (made publicly visible) the campaign. * Null when the campaign has not been public. + * @format date-time */ published_at: string | null @@ -78,7 +82,7 @@ export interface Campaign { // TODO: no documentation /** - * + * @format uri */ main_video_url: string | null @@ -105,11 +109,13 @@ export interface Campaign { /** * Banner image URL for the campaign + * @format uri */ image_url: string /** * Profile image URL for the campaign + * @format uri */ image_small_url: string @@ -140,8 +146,10 @@ export interface Campaign { /** * Datetime that the creator first began the campaign creation process + * @format date-time */ created_at: string } +/** @deprecated use keyof Campaign */ export type CampaignFields = keyof Campaign diff --git a/src/schemas/v2/resources/deliverable.ts b/src/schemas/v2/resources/deliverable.ts index edf5baa..897cdb1 100644 --- a/src/schemas/v2/resources/deliverable.ts +++ b/src/schemas/v2/resources/deliverable.ts @@ -1,6 +1,10 @@ +/** + * The record of whether or not a patron has been delivered the benefit they are owed because of their member tier. + */ export interface Deliverable { /** * When the creator marked the deliverable as completed or fulfilled to the patron + * @format date-time */ completed_at: string | null @@ -11,6 +15,7 @@ export interface Deliverable { /** * When the deliverable is due to the patron + * @format date-time */ due_at: string -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/media.ts b/src/schemas/v2/resources/media.ts index 25ea242..3859093 100644 --- a/src/schemas/v2/resources/media.ts +++ b/src/schemas/v2/resources/media.ts @@ -1,16 +1,21 @@ +/** + * A file uploaded to patreon.com, usually an image. + */ export interface Media { /** * When the file was created + * @format date-time */ created_at: string /** * The URL to download this media. Valid for 24 hours. + * @format uri */ download_url: string /** - * + * File name. */ file_name: string @@ -56,6 +61,7 @@ export interface Media { /** * When the upload URL expires + * @format date-time */ upload_expires_at: string @@ -66,6 +72,7 @@ export interface Media { /** * The URL to perform a POST request to in order to upload the media file + * @format uri */ upload_url: string -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/member.ts b/src/schemas/v2/resources/member.ts index 3967617..e7655fc 100644 --- a/src/schemas/v2/resources/member.ts +++ b/src/schemas/v2/resources/member.ts @@ -1,3 +1,7 @@ +/** + * The record of a user's membership to a campaign. + * Remains consistent across months of pledging. + */ export interface Member { /** * The total amount that the member has ever paid to the campaign in campaign's currency. @@ -31,6 +35,7 @@ export interface Member { /** * Datetime of last attempted charge. * `null` if never charged + * @format date-time */ last_charge_date: string | null @@ -60,6 +65,7 @@ export interface Member { /** * Datetime of next charge. * `null` if annual pledge downgrade + * @format date-time */ next_charge_date: string | null @@ -88,6 +94,7 @@ export interface Member { /** * Datetime of beginning of most recent pledge chainfrom this member to the campaign. * Pledge updates do not change this value + * @format date-time */ pledge_relationship_start: string | null @@ -96,4 +103,4 @@ export interface Member { * @example 500 */ will_pay_amount_cents: number -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/oauth_client.ts b/src/schemas/v2/resources/oauth_client.ts index b4657a2..5de4a73 100644 --- a/src/schemas/v2/resources/oauth_client.ts +++ b/src/schemas/v2/resources/oauth_client.ts @@ -1,3 +1,6 @@ +/** + * A client created by a developer, used for getting OAuth2 access tokens. + */ export interface OauthClient { /** * The author name provided during client setup. @@ -22,11 +25,13 @@ export interface OauthClient { /** * The domain provided during client setup. + * @format uri */ domain: string | null /** * The URL of the icon used in the OAuth authorization flow. + * @format uri */ icon_url: string | null @@ -37,6 +42,7 @@ export interface OauthClient { /** * The URL of the privacy policy provided during client setup. + * @format uri */ privacy_policy_url: string | null @@ -47,11 +53,13 @@ export interface OauthClient { /** * The URL of the terms of service provided during client setup. + * @format uri */ tos_url: string /** * The Patreon API version the client is targeting. + * @example 2 */ version: number -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/pledge_event.ts b/src/schemas/v2/resources/pledge_event.ts index 0425aa4..f934d08 100644 --- a/src/schemas/v2/resources/pledge_event.ts +++ b/src/schemas/v2/resources/pledge_event.ts @@ -1,6 +1,10 @@ +/** + * The record of a pledging action taken by the user, or that action's failure. + */ export interface PledgeEvent { /** * Amount (in the currency in which the patron paid) of the underlying event + * @example 500 */ amount_cents: number @@ -11,6 +15,7 @@ export interface PledgeEvent { /** * The date which this event occurred + * @format date-time */ date: string @@ -35,10 +40,13 @@ export interface PledgeEvent { */ tier_title: string | null + /** + * Event type. + */ type: | 'pledge_start' | 'pledge_upgrade' | 'pledge_downgrade' | 'pledge_delete' | 'subscription' -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/post.ts b/src/schemas/v2/resources/post.ts index fce3ebf..ad080ee 100644 --- a/src/schemas/v2/resources/post.ts +++ b/src/schemas/v2/resources/post.ts @@ -1,3 +1,6 @@ +/** + * Content posted by a creator on a campaign page. + */ export interface Post { /** * Platform app id @@ -23,6 +26,7 @@ export interface Post { /** * Embed media url + * @format uri */ embed_url: string | null @@ -39,6 +43,7 @@ export interface Post { /** * Datetime that the creator most recently published (made publicly visible) the post + * @format date-time */ published_at: string | null @@ -57,6 +62,7 @@ export interface Post { /** * A URL to access this post on patreon.com + * @format uri */ url: string -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/tier.ts b/src/schemas/v2/resources/tier.ts index 5fa861a..c1b02af 100644 --- a/src/schemas/v2/resources/tier.ts +++ b/src/schemas/v2/resources/tier.ts @@ -1,3 +1,6 @@ +/** + * A membership level on a campaign, which can have benefits attached to it. + */ export interface Tier { /** * Monetary amount associated with this tier (in U.S. cents) @@ -6,6 +9,7 @@ export interface Tier { /** * Datetime this tier was created + * @format date-time */ created_at: string @@ -22,11 +26,13 @@ export interface Tier { /** * Datetime tier was last modified + * @format date-time */ edited_at: string /** * Full qualified image URL associated with this tier + * @format uri */ image_url: string | null @@ -47,6 +53,7 @@ export interface Tier { /** * Datetime this tier was last published + * @format date-time */ published_at: string | null @@ -67,11 +74,13 @@ export interface Tier { /** * Datetime tier was unpublished, while applicable + * @format date-time */ unpublished_at: string | null /** * Fully qualified URL associated with this tier + * @format uri */ url: string @@ -79,4 +88,4 @@ export interface Tier { * Maximum number of patrons this tier is limited to, if applicable */ user_limit: number | null -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/user.ts b/src/schemas/v2/resources/user.ts index 030141a..03c3e2e 100644 --- a/src/schemas/v2/resources/user.ts +++ b/src/schemas/v2/resources/user.ts @@ -23,6 +23,9 @@ export type SocialConnectionPlatform = keyof { 'youtube': null } +/** + * The Patreon user, which can be both patron and creator. + */ export interface User { /** * The user's about text, which appears on their profile @@ -36,6 +39,7 @@ export interface User { /** * Datetime of this user's account creation + * @format date-time */ created: string @@ -43,11 +47,12 @@ export interface User { * The user's email address. * Requires certain scopes to access. * See the scopes section of the documentation + * @format email */ email: string /** - * + * First name. */ first_name: string | null @@ -63,6 +68,7 @@ export interface User { /** * The user's profile picture URL, scaled to width 400px + * @format uri */ image_url: string @@ -72,7 +78,7 @@ export interface User { is_email_verified: boolean /** - * + * Last name. */ last_name: string | null @@ -100,11 +106,13 @@ export interface User { /** * The user's profile picture URL, scaled to a square of size 100x100px + * @format uri */ thumb_url: string /** * URL of this user's creator or patron profile + * @format uri */ url: string @@ -115,4 +123,4 @@ export interface User { * @deprecated use Campaign.vanity */ vanity: string | null -} \ No newline at end of file +} diff --git a/src/schemas/v2/resources/webhook.ts b/src/schemas/v2/resources/webhook.ts index b5bd491..e3f7d7a 100644 --- a/src/schemas/v2/resources/webhook.ts +++ b/src/schemas/v2/resources/webhook.ts @@ -1,11 +1,17 @@ +/** + * Webhooks are fired based on events happening on a particular campaign. + */ export interface Webhook { /** * Last date that the webhook was attempted or used. + * @format date-time */ last_attempted_at: string /** * Number of times the webhook has failed consecutively, when in an error state. + * @example 0 + * @example 2 */ num_consecutive_times_failed: number @@ -26,7 +32,9 @@ export interface Webhook { triggers: string[] /** - * Fully qualified uri where webhook will be sent (e.g. https://www.example.com/webhooks/incoming). + * Fully qualified uri where webhook will be sent + * @format uri + * @example 'https://www.example.com/webhooks/incoming' */ uri: string } diff --git a/src/schemas/v2/scripts/shared.ts b/src/schemas/v2/scripts/shared.ts index 19437a3..afe776f 100644 --- a/src/schemas/v2/scripts/shared.ts +++ b/src/schemas/v2/scripts/shared.ts @@ -52,3 +52,9 @@ export function getJsDocDescription (node: JSDocableNode): string { .replaceAll('\r\n', '\n') // Use LF line endings ?? '' } + +export function getJsDocTags (node: JSDocableNode, type: string): (string | undefined)[] | undefined { + return node.getJsDocs().at(0)?.getTags() + .filter(tag => tag.getTagName() === type) + .map(tag => tag.getCommentText()) +}