From f2cba22e171000116b7ebf205bfd3706d6581434 Mon Sep 17 00:00:00 2001 From: Ryan Waskiewicz Date: Fri, 29 Mar 2024 16:39:39 -0400 Subject: [PATCH] feat(attr): honor deprecated jsdoc tags --- src/contributions/html-contributions.test.ts | 73 +++++++++++++++++++- src/contributions/html-contributions.ts | 6 +- src/index.ts | 2 + 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/contributions/html-contributions.test.ts b/src/contributions/html-contributions.test.ts index 7ee0987..e1a6952 100644 --- a/src/contributions/html-contributions.test.ts +++ b/src/contributions/html-contributions.test.ts @@ -9,6 +9,30 @@ describe('generateElementInfo', () => { expect([]).toEqual(generateElementInfo([])); }); + it.each(['deprecated', 'DEPRECATED', 'Deprecated'])('marks a component as deprecated', (deprecated: string) => { + const cmpMeta = stubComponentCompilerMeta({ + tagName: 'my-component', + docs: { + text: 'a simple component that shows us your name', + tags: [{ name: deprecated }], + }, + properties: [], + }); + + const expected: ElementInfo = { + name: 'my-component', + deprecated: true, + description: 'a simple component that shows us your name', + attributes: [], + slots: [], + }; + + const actual: ElementInfo[] = generateElementInfo([cmpMeta]); + + expect(actual).toHaveLength(1); + expect(actual[0]).toEqual(expected); + }); + describe('attributes', () => { let cmpMeta: ComponentCompilerMeta; @@ -26,6 +50,7 @@ describe('generateElementInfo', () => { it('handles a component with no attributes', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [], slots: [], @@ -41,10 +66,12 @@ describe('generateElementInfo', () => { it('parses the properties field into a well formed entry', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [ { default: 'Bob', + deprecated: false, description: 'this is the first name of the user', name: 'first-name', priority: 'high', @@ -76,6 +103,47 @@ describe('generateElementInfo', () => { expect(actual).toHaveLength(1); expect(actual[0]).toEqual(expected); }); + + it.each(['deprecated', 'DEPRECATED', 'Deprecated'])('marks an attribute as deprecated', (deprecated) => { + const expected: ElementInfo = { + name: 'my-component', + deprecated: false, + description: 'a simple component that shows us your name', + attributes: [ + { + default: 'Bob', + deprecated: true, + description: 'this is the first name of the user', + name: 'first-name', + priority: 'high', + required: false, + }, + ], + slots: [], + }; + + cmpMeta.properties = [ + { + attribute: 'first-name', + docs: { + text: 'this is the first name of the user', + tags: [{ name: deprecated, text: '' }], + }, + defaultValue: 'Bob', + required: false, + name: '', + internal: false, + mutable: false, + optional: false, + type: 'string', + complexType: { original: 'string', resolved: 'string', references: {} }, + }, + ]; + const actual: ElementInfo[] = generateElementInfo([cmpMeta]); + + expect(actual).toHaveLength(1); + expect(actual[0]).toEqual(expected); + }); }); describe('slots', () => { @@ -95,6 +163,7 @@ describe('generateElementInfo', () => { it('parses a component with no slots', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [], slots: [], @@ -115,6 +184,7 @@ describe('generateElementInfo', () => { it('parses the default slot', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [], slots: [ @@ -140,6 +210,7 @@ describe('generateElementInfo', () => { it('parses a named slot with no description', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [], slots: [ @@ -165,6 +236,7 @@ describe('generateElementInfo', () => { it('parses a slot with a name and description', () => { const expected: ElementInfo = { name: 'my-component', + deprecated: false, description: 'a simple component that shows us your name', attributes: [], slots: [ @@ -189,7 +261,6 @@ describe('generateElementInfo', () => { }); }); -// TODO(NOW): Need a better way to share this stub from Stencil Core /** * Generates a stub {@link ComponentCompilerMeta}. This function uses sensible defaults for the initial stub. However, * any field in the object may be overridden via the `overrides` argument. diff --git a/src/contributions/html-contributions.ts b/src/contributions/html-contributions.ts index 88a83f5..a6f7458 100644 --- a/src/contributions/html-contributions.ts +++ b/src/contributions/html-contributions.ts @@ -10,16 +10,18 @@ import { ElementInfo } from '../index'; * @param components the Stencil components to generate info for to contribute to the HTML namespace */ export const generateElementInfo = (components: ComponentCompilerMeta[]): ElementInfo[] => { - return components.map((cmpMeta: ComponentCompilerMeta) => { + return components.map((cmpMeta: ComponentCompilerMeta): ElementInfo => { return { name: cmpMeta.tagName, + deprecated: !!cmpMeta.docs.tags.find((tag) => tag.name.toLowerCase() === 'deprecated'), description: cmpMeta.docs.text, attributes: cmpMeta.properties.map((prop: ComponentCompilerProperty) => { return { name: prop.attribute as string, // TODO: I can be undefined + deprecated: !!prop.docs.tags.find((tag) => tag.name.toLowerCase() === 'deprecated'), description: prop.docs.text, required: prop.required, - default: prop.defaultValue ?? '', // TODO is | undefined valid? + default: prop.defaultValue ?? '', // TODO is | undefined valid? - Think about this in the context of Stencil `@Prop() first: boolean`; priority: 'high', }; }), diff --git a/src/index.ts b/src/index.ts index a03e4c6..bbbe76c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -54,6 +54,7 @@ type Contributions = { export type ElementInfo = { name: string; + deprecated: boolean; description: string; attributes: AttributeInfo[]; /** @@ -68,6 +69,7 @@ type AttributeInfo = { description: string; required: boolean; default: string; + deprecated: boolean; priority: 'lowest' | 'low' | 'normal' | 'high' | 'highest'; };