diff --git a/code/addons/controls/src/ControlsPanel.tsx b/code/addons/controls/src/ControlsPanel.tsx index 09d3bc45e44e..1f1a90cce007 100644 --- a/code/addons/controls/src/ControlsPanel.tsx +++ b/code/addons/controls/src/ControlsPanel.tsx @@ -35,8 +35,10 @@ export const ControlsPanel: FC = () => { const hasControls = Object.values(rows).some((arg) => arg?.control); const withPresetColors = Object.entries(rows).reduce((acc, [key, arg]) => { - if (arg?.control?.type !== 'color' || arg?.control?.presetColors) acc[key] = arg; - else acc[key] = { ...arg, control: { ...arg.control, presetColors } }; + const control = arg?.control; + if (typeof control !== 'object' || control?.type !== 'color' || control?.presetColors) + acc[key] = arg; + else acc[key] = { ...arg, control: { ...control, presetColors } }; return acc; }, {} as ArgTypes); diff --git a/code/addons/links/package.json b/code/addons/links/package.json index bb5368c63666..c1d9bcbe1804 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -63,7 +63,7 @@ "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/addon-bundle.ts" }, "dependencies": { - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/global": "^5.0.0", "ts-dedent": "^2.0.0" }, diff --git a/code/frameworks/angular/src/client/docs/compodoc.ts b/code/frameworks/angular/src/client/docs/compodoc.ts index 9785842648d0..cc6425c6e545 100644 --- a/code/frameworks/angular/src/client/docs/compodoc.ts +++ b/code/frameworks/angular/src/client/docs/compodoc.ts @@ -200,7 +200,7 @@ const extractDefaultValueFromComments = (property: Property, value: any) => { const extractDefaultValue = (property: Property) => { try { - let value: string | boolean = property.defaultValue?.replace(/^'(.*)'$/, '$1'); + let value: string = property.defaultValue?.replace(/^'(.*)'$/, '$1'); value = castDefaultValue(property, value); if (value == null && property.jsdoctags?.length > 0) { diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 72c14e808905..52f6ec3919df 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -57,7 +57,7 @@ "@babel/core": "^7.23.2", "@babel/preset-env": "^7.23.2", "@babel/types": "^7.23.0", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/csf-tools": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/types": "workspace:*", diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 5e4c79620568..91df9969d547 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -62,7 +62,7 @@ "@storybook/channels": "workspace:*", "@storybook/core-common": "workspace:*", "@storybook/core-events": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/csf-tools": "workspace:*", "@storybook/docs-mdx": "3.0.0", "@storybook/global": "^5.0.0", diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index 37fb44d827c1..c9b3ddb86dd1 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -46,7 +46,7 @@ "@babel/parser": "^7.23.0", "@babel/traverse": "^7.23.2", "@babel/types": "^7.23.0", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/types": "workspace:*", "fs-extra": "^11.1.0", "recast": "^0.23.5", diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 1d740b2506d2..cbf126ec6025 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -47,7 +47,7 @@ "@storybook/channels": "workspace:*", "@storybook/client-logger": "workspace:*", "@storybook/core-events": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/global": "^5.0.0", "@storybook/icons": "^1.2.5", "@storybook/router": "workspace:*", diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index 418668bdb847..eacb7f9c9b3e 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -47,7 +47,7 @@ "@storybook/channels": "workspace:*", "@storybook/client-logger": "workspace:*", "@storybook/core-events": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/global": "^5.0.0", "@storybook/types": "workspace:*", "@types/qs": "^6.9.5", diff --git a/code/lib/preview-api/src/modules/store/args.test.ts b/code/lib/preview-api/src/modules/store/args.test.ts index 0d39874c766f..ed8ed42c483e 100644 --- a/code/lib/preview-api/src/modules/store/args.test.ts +++ b/code/lib/preview-api/src/modules/store/args.test.ts @@ -243,6 +243,7 @@ describe('validateOptions', () => { }); it('ignores options and logs an error if options is not an array', () => { + // @ts-expect-error This should give TS error indeed (finally!) expect(validateOptions({ a: 1 }, { a: { options: { 2: 'two' } } })).toStrictEqual({ a: 1 }); expect(once.error).toHaveBeenCalledWith( expect.stringContaining("Invalid argType: 'a.options' should be an array") diff --git a/code/lib/preview-api/src/modules/store/csf/prepareStory.ts b/code/lib/preview-api/src/modules/store/csf/prepareStory.ts index 0e5ea37500cd..d4613db8eb71 100644 --- a/code/lib/preview-api/src/modules/store/csf/prepareStory.ts +++ b/code/lib/preview-api/src/modules/store/csf/prepareStory.ts @@ -250,10 +250,10 @@ export function prepareContext< return acc; } - const mappingFn = (originalValue: any) => - originalValue in targetedContext.argTypes[key].mapping - ? targetedContext.argTypes[key].mapping[originalValue] - : originalValue; + const mappingFn = (originalValue: any) => { + const mapping = targetedContext.argTypes[key].mapping; + return mapping && originalValue in mapping ? mapping[originalValue] : originalValue; + }; acc[key] = Array.isArray(val) ? val.map(mappingFn) : mappingFn(val); diff --git a/code/lib/preview-api/src/modules/store/inferControls.test.ts b/code/lib/preview-api/src/modules/store/inferControls.test.ts index 8d754372439d..9293bf771e69 100644 --- a/code/lib/preview-api/src/modules/store/inferControls.test.ts +++ b/code/lib/preview-api/src/modules/store/inferControls.test.ts @@ -58,7 +58,8 @@ describe('inferControls', () => { }) ); - expect(inferredControls.background.control.type).toEqual('color'); + const control = inferredControls.background.control; + expect(typeof control === 'object' && control.type).toEqual('color'); }); it('should return inferred type when using color matcher but arg passed is not a string', () => { @@ -97,7 +98,8 @@ describe('inferControls', () => { ); expect(warnSpy).toHaveBeenCalled(); - expect(inferredControls.background.control.type).toEqual(type.name); + const control = inferredControls.background.control; + expect(typeof control === 'object' && control.type).toEqual(type.name); }); }); }); diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index 14461a03b100..490ea42cdd03 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -45,7 +45,7 @@ "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" }, "dependencies": { - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/types": "workspace:*", "estraverse": "^5.2.0", "lodash": "^4.17.21", diff --git a/code/lib/types/package.json b/code/lib/types/package.json index fa8db083a774..e0cd696e23c3 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -49,7 +49,7 @@ "file-system-cache": "2.3.0" }, "devDependencies": { - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@types/fs-extra": "^11.0.1", "@types/node": "^18.0.0", "typescript": "^5.3.2" diff --git a/code/package.json b/code/package.json index 9d8cdc6e786f..8e65cacdf08a 100644 --- a/code/package.json +++ b/code/package.json @@ -122,7 +122,7 @@ "@storybook/core-events": "workspace:*", "@storybook/core-server": "workspace:*", "@storybook/core-webpack": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/csf-plugin": "workspace:*", "@storybook/csf-tools": "workspace:*", "@storybook/docs-tools": "workspace:*", @@ -261,6 +261,7 @@ "type": "opencollective", "url": "https://opencollective.com/storybook" }, + "deferredNextVersion": "8.0.9", "pr-log": { "skipLabels": [ "cleanup" @@ -295,6 +296,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.0.9" + } } diff --git a/code/renderers/react/src/docs/extractArgTypes.ts b/code/renderers/react/src/docs/extractArgTypes.ts index 2da2e2724e7d..7c4c55911255 100644 --- a/code/renderers/react/src/docs/extractArgTypes.ts +++ b/code/renderers/react/src/docs/extractArgTypes.ts @@ -22,9 +22,9 @@ export const extractArgTypes: ArgTypesExtractor = (component) => { description, type: { required, ...sbType }, table: { - type, + type: type ?? undefined, jsDocTags, - defaultValue: defaultSummary, + defaultValue: defaultSummary ?? undefined, }, }; return acc; diff --git a/code/renderers/react/template/stories/docgen-components/10017-ts-union/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/10017-ts-union/argTypes.snapshot index a8f478974310..0b533788e837 100644 --- a/code/renderers/react/template/stories/docgen-components/10017-ts-union/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/10017-ts-union/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "specify icon="search" or icon={IconComponent}", "name": "icon", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/argTypes.snapshot index 78a50d36f3ca..82355abfb51b 100644 --- a/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "aProperty", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/8140-js-prop-types-oneof/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/8140-js-prop-types-oneof/argTypes.snapshot index 7b21f298a2b6..af4ea9528f45 100644 --- a/code/renderers/react/template/stories/docgen-components/8140-js-prop-types-oneof/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/8140-js-prop-types-oneof/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "No background or border if static alert", "name": "blank", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -25,7 +25,7 @@ "description": "Allows icon override, accepts material icon name", "name": "icon", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -44,7 +44,7 @@ "description": "", "name": "message", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/8143-ts-imported-types/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/8143-ts-imported-types/argTypes.snapshot index f95af2d02b91..ac64197be1b9 100644 --- a/code/renderers/react/template/stories/docgen-components/8143-ts-imported-types/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/8143-ts-imported-types/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "bar", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/8428-js-static-prop-types/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/8428-js-static-prop-types/argTypes.snapshot index 4e6031c33335..70cdd2d53019 100644 --- a/code/renderers/react/template/stories/docgen-components/8428-js-static-prop-types/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/8428-js-static-prop-types/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "Please work...", "name": "test", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9023-js-hoc/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9023-js-hoc/argTypes.snapshot index a243641da870..32718313fe4e 100644 --- a/code/renderers/react/template/stories/docgen-components/9023-js-hoc/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9023-js-hoc/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "classes", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -47,7 +47,7 @@ "description": "", "name": "icon", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9399-js-proptypes-shape/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9399-js-proptypes-shape/argTypes.snapshot index 619552956691..08e3d4d50f67 100644 --- a/code/renderers/react/template/stories/docgen-components/9399-js-proptypes-shape/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9399-js-proptypes-shape/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "areas", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": "[object]", diff --git a/code/renderers/react/template/stories/docgen-components/9493-ts-display-name/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9493-ts-display-name/argTypes.snapshot index 1937e2f0b929..5b86db7699ab 100644 --- a/code/renderers/react/template/stories/docgen-components/9493-ts-display-name/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9493-ts-display-name/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "A message alerting about Empire activities.", "name": "message", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9586-js-react-memo/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9586-js-react-memo/argTypes.snapshot index 08c5a1cadec0..927cda14fc96 100644 --- a/code/renderers/react/template/stories/docgen-components/9586-js-react-memo/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9586-js-react-memo/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "label", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -22,7 +22,7 @@ "description": "", "name": "onClick", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9591-ts-import-types/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9591-ts-import-types/argTypes.snapshot index d6450dd81aae..83d91924fb0c 100644 --- a/code/renderers/react/template/stories/docgen-components/9591-ts-import-types/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9591-ts-import-types/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "other", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9668-js-proptypes-no-jsdoc/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9668-js-proptypes-no-jsdoc/argTypes.snapshot index 42a58cd67545..590f3741b90b 100644 --- a/code/renderers/react/template/stories/docgen-components/9668-js-proptypes-no-jsdoc/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9668-js-proptypes-no-jsdoc/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "heads", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -23,7 +23,7 @@ "description": "", "name": "onAddClick", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9721-ts-deprecated-jsdoc/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9721-ts-deprecated-jsdoc/argTypes.snapshot index fbce25797699..e58f2727aefc 100644 --- a/code/renderers/react/template/stories/docgen-components/9721-ts-deprecated-jsdoc/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9721-ts-deprecated-jsdoc/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "The size (replaces width)", "name": "size", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9764-ts-extend-props/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9764-ts-extend-props/argTypes.snapshot index 61caa309227d..5c8758c8de31 100644 --- a/code/renderers/react/template/stories/docgen-components/9764-ts-extend-props/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9764-ts-extend-props/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "checked", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -25,7 +25,7 @@ "description": "", "name": "defaultChecked", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -44,7 +44,7 @@ "description": "The input content value", "name": "value", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9827-ts-default-values/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9827-ts-default-values/argTypes.snapshot index 78780fc49909..84a578fb287c 100644 --- a/code/renderers/react/template/stories/docgen-components/9827-ts-default-values/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9827-ts-default-values/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "bar", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -31,7 +31,7 @@ "description": "", "name": "foo", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/9922-ts-component-props/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/9922-ts-component-props/argTypes.snapshot index 222aace445d3..2d1174767e7b 100644 --- a/code/renderers/react/template/stories/docgen-components/9922-ts-component-props/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9922-ts-component-props/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "", "name": "spacing", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/react/template/stories/docgen-components/jsdoc/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/jsdoc/argTypes.snapshot index c37916b55746..492640c6e1be 100644 --- a/code/renderers/react/template/stories/docgen-components/jsdoc/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/jsdoc/argTypes.snapshot @@ -6,7 +6,7 @@ "description": "simple description.", "name": "case1", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -22,7 +22,7 @@ "description": "param with name", "name": "case10", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -48,7 +48,7 @@ "description": "param with name & type", "name": "case11", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -74,7 +74,7 @@ "description": "param with name, type & description", "name": "case12", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -100,7 +100,7 @@ "description": "param with type", "name": "case13", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -126,7 +126,7 @@ "description": "param with type & description", "name": "case14", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -142,7 +142,7 @@ "description": "param with name & description", "name": "case15", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -168,7 +168,7 @@ "description": "autofix event-", "name": "case16", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -194,7 +194,7 @@ "description": "autofix event.", "name": "case17", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -227,7 +227,7 @@ "description": "with an empty param.", "name": "case18", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -243,7 +243,7 @@ "description": "with multiple empty params.", "name": "case19", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -264,7 +264,7 @@ lines description", "name": "case2", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -280,7 +280,7 @@ description", "description": "with arg alias.", "name": "case20", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -306,7 +306,7 @@ description", "description": "with argument alias.", "name": "case21", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -332,7 +332,7 @@ description", "description": "with multiple params.", "name": "case22", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -366,7 +366,7 @@ description", "description": "with an empty returns", "name": "case23", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -382,7 +382,7 @@ description", "description": "with a returns with a type", "name": "case24", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -410,7 +410,7 @@ description", "description": "with a returns with a type & description", "name": "case25", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -438,7 +438,7 @@ description", "description": "single param and a returns", "name": "case26", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -471,7 +471,7 @@ description", "description": "multiple params and a returns", "name": "case27", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -508,7 +508,7 @@ description", "description": "multiple returns", "name": "case28", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -536,7 +536,7 @@ description", "description": "param with unsupported JSDoc tags", "name": "case29", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -565,7 +565,7 @@ description", "description": "*description* **with** `formatting`", "name": "case3", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -581,7 +581,7 @@ description", "description": "param record type", "name": "case30", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -607,7 +607,7 @@ description", "description": "param array type", "name": "case31", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -633,7 +633,7 @@ description", "description": "param union type", "name": "case32", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -659,7 +659,7 @@ description", "description": "param any type", "name": "case33", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -685,7 +685,7 @@ description", "description": "param repeatable type", "name": "case34", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -711,7 +711,7 @@ description", "description": "optional param", "name": "case35", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -737,7 +737,7 @@ description", "description": "optional param", "name": "case36", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -763,7 +763,7 @@ description", "description": "dot in param name", "name": "case37", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -789,7 +789,7 @@ description", "description": "returns record type", "name": "case38", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -834,7 +834,7 @@ description", "description": "returns array type", "name": "case39", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -874,7 +874,7 @@ description", "description": "simple description and dummy JSDoc tag.", "name": "case4", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -900,7 +900,7 @@ description", "description": "returns union type", "name": "case40", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -937,7 +937,7 @@ description", "description": "returns any type", "name": "case41", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -964,7 +964,7 @@ description", "description": "returns primitive", "name": "case42", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -992,7 +992,7 @@ description", "description": "returns void", "name": "case43", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -1023,7 +1023,7 @@ description", "description": "", "name": "case5", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, @@ -1052,7 +1052,7 @@ description", "description": "simple description with a @.", "name": "case6", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -1068,7 +1068,7 @@ description", "description": "", "name": "case7", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -1084,7 +1084,7 @@ description", "description": "func with a simple description.", "name": "case8", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, @@ -1100,7 +1100,7 @@ description", "description": "", "name": "case9", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": { "deprecated": null, "ignore": false, diff --git a/code/renderers/react/template/stories/docgen-components/ts-types/argTypes.snapshot b/code/renderers/react/template/stories/docgen-components/ts-types/argTypes.snapshot index 73094699e177..21ff1cd3a802 100644 --- a/code/renderers/react/template/stories/docgen-components/ts-types/argTypes.snapshot +++ b/code/renderers/react/template/stories/docgen-components/ts-types/argTypes.snapshot @@ -365,7 +365,7 @@ "description": undefined, "name": "nullableComplexTypeUndefinedDefaultValue", "table": { - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "detail": undefined, diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index b069f3d52408..80a42b303bc1 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -46,7 +46,7 @@ "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" }, "dependencies": { - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/csf-tools": "workspace:*", "@storybook/global": "^5.0.0", "@storybook/preview-api": "workspace:*", diff --git a/code/renderers/server/src/render.ts b/code/renderers/server/src/render.ts index 0a768647d740..0c910f7ba706 100644 --- a/code/renderers/server/src/render.ts +++ b/code/renderers/server/src/render.ts @@ -22,7 +22,8 @@ const buildStoryArgs = (args: Args, argTypes: ArgTypes) => { Object.keys(argTypes).forEach((key: string) => { const argType = argTypes[key]; const { control } = argType; - const controlType = control && control.type.toLowerCase(); + const controlType = + control && typeof control === 'object' && 'type' in control && control.type?.toLowerCase(); const argValue = storyArgs[key]; switch (controlType) { case 'date': diff --git a/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap b/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap index 164f338725e3..cbe74a47b7d6 100644 --- a/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap +++ b/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap @@ -66,7 +66,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract events for component "name": "bar", "table": { "category": "events", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "{ year: number; title?: any }", @@ -86,7 +86,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract events for component "name": "baz", "table": { "category": "events", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": undefined, }, @@ -109,7 +109,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract expose for component "name": "count", "table": { "category": "expose", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": undefined, }, @@ -126,7 +126,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract expose for component "name": "label", "table": { "category": "expose", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": undefined, }, @@ -510,7 +510,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "array", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedProps[]", @@ -527,7 +527,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "arrayOptional", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedProps[]", @@ -562,7 +562,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "baz", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "boolean", @@ -578,7 +578,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "enumValue", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyEnum", @@ -595,7 +595,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "foo", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "string", @@ -611,7 +611,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "inlined", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "{ foo: string }", @@ -628,7 +628,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "literalFromContext", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyCategories", @@ -645,7 +645,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "nested", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedProps", @@ -662,7 +662,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "nestedIntersection", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedProps & { @@ -684,7 +684,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "nestedOptional", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedProps | MyIgnoredNestedProps", @@ -710,7 +710,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "recursive", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "MyNestedRecursiveProps", @@ -746,7 +746,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "union", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "string | number", @@ -770,7 +770,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 2 "name": "unionOptional", "table": { "category": "props", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "string | number | boolean", @@ -802,7 +802,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract slots for component 1 "name": "default", "table": { "category": "slots", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "{ num: unknown }", @@ -819,7 +819,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract slots for component 1 "name": "named", "table": { "category": "slots", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "{ str: unknown }", @@ -836,7 +836,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract slots for component 1 "name": "no-bind", "table": { "category": "slots", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": undefined, }, @@ -851,7 +851,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract slots for component 1 "name": "vbind", "table": { "category": "slots", - "defaultValue": null, + "defaultValue": undefined, "jsDocTags": undefined, "type": { "summary": "{ num: unknown; str: unknown }", diff --git a/code/renderers/vue3/src/docs/extractArgTypes.ts b/code/renderers/vue3/src/docs/extractArgTypes.ts index d466cea2e1cd..66bc7efcf7da 100644 --- a/code/renderers/vue3/src/docs/extractArgTypes.ts +++ b/code/renderers/vue3/src/docs/extractArgTypes.ts @@ -127,7 +127,7 @@ export const extractFromVueDocgenApi = ( type: sbType ? { ...sbType, required } : { name: 'other', value: type ?? '' }, table: { type: type ? { summary: type } : undefined, - defaultValue: extractedProp?.propDef.defaultValue, + defaultValue: extractedProp?.propDef.defaultValue ?? undefined, jsDocTags: extractedProp?.propDef.jsDocTags, category: section, }, diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index 8a6d0e0b61dd..965991f5fcc4 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -48,7 +48,7 @@ "@storybook/client-logger": "workspace:*", "@storybook/components": "workspace:*", "@storybook/core-events": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/docs-tools": "workspace:*", "@storybook/global": "^5.0.0", "@storybook/icons": "^1.2.5", diff --git a/code/ui/blocks/src/components/ArgsTable/types.ts b/code/ui/blocks/src/components/ArgsTable/types.ts index a8f3dd1d453e..7efb484fe6a9 100644 --- a/code/ui/blocks/src/components/ArgsTable/types.ts +++ b/code/ui/blocks/src/components/ArgsTable/types.ts @@ -41,6 +41,21 @@ export interface ArgType { description?: string; defaultValue?: any; if?: Conditional; + table?: { + category?: string; + disable?: boolean; + subcategory?: string; + defaultValue?: { + summary?: string; + detail?: string; + }; + type?: { + summary?: string; + detail?: string; + }; + readonly?: boolean; + [key: string]: any; + }; [key: string]: any; } diff --git a/code/ui/blocks/src/controls/options/SelectOptions.stories.tsx b/code/ui/blocks/src/controls/options/SelectOptions.stories.tsx index 653b2574d4c8..635b33e22c3b 100644 --- a/code/ui/blocks/src/controls/options/SelectOptions.stories.tsx +++ b/code/ui/blocks/src/controls/options/SelectOptions.stories.tsx @@ -19,7 +19,7 @@ const argTypeMultiSelect = { options: arrayOptions, }, }, -}; +} as const; const meta = { title: 'Controls/Options/Select', diff --git a/code/ui/components/package.json b/code/ui/components/package.json index bf913ec4a208..e94b6e0e3313 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -61,7 +61,7 @@ "dependencies": { "@radix-ui/react-slot": "^1.0.2", "@storybook/client-logger": "workspace:*", - "@storybook/csf": "^0.1.2", + "@storybook/csf": "^0.1.4", "@storybook/global": "^5.0.0", "@storybook/icons": "^1.2.5", "@storybook/theming": "workspace:*", diff --git a/code/yarn.lock b/code/yarn.lock index 0fbe77568f07..cc6d00a61649 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -7008,7 +7008,7 @@ __metadata: dependencies: "@storybook/client-logger": "workspace:*" "@storybook/core-events": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/global": "npm:^5.0.0" "@storybook/manager-api": "workspace:*" "@storybook/preview-api": "workspace:*" @@ -7286,7 +7286,7 @@ __metadata: "@storybook/client-logger": "workspace:*" "@storybook/components": "workspace:*" "@storybook/core-events": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/docs-tools": "workspace:*" "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^1.2.5" @@ -7524,7 +7524,7 @@ __metadata: "@babel/core": "npm:^7.23.2" "@babel/preset-env": "npm:^7.23.2" "@babel/types": "npm:^7.23.0" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/csf-tools": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/types": "workspace:*" @@ -7561,7 +7561,7 @@ __metadata: "@radix-ui/react-scroll-area": "npm:^1.0.5" "@radix-ui/react-slot": "npm:^1.0.2" "@storybook/client-logger": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^1.2.5" "@storybook/test": "workspace:*" @@ -7657,7 +7657,7 @@ __metadata: "@storybook/channels": "workspace:*" "@storybook/core-common": "workspace:*" "@storybook/core-events": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/csf-tools": "workspace:*" "@storybook/docs-mdx": "npm:3.0.0" "@storybook/global": "npm:^5.0.0" @@ -7740,7 +7740,7 @@ __metadata: "@babel/parser": "npm:^7.23.0" "@babel/traverse": "npm:^7.23.2" "@babel/types": "npm:^7.23.0" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/types": "workspace:*" "@types/fs-extra": "npm:^11.0.1" "@types/js-yaml": "npm:^4.0.5" @@ -7762,12 +7762,12 @@ __metadata: languageName: node linkType: hard -"@storybook/csf@npm:^0.1.2": - version: 0.1.2 - resolution: "@storybook/csf@npm:0.1.2" +"@storybook/csf@npm:^0.1.4": + version: 0.1.4 + resolution: "@storybook/csf@npm:0.1.4" dependencies: type-fest: "npm:^2.19.0" - checksum: 10c0/b51a55292e5d2af8b1d135a28ecaa94f8860ddfedcb393adfa2cca1ee23853156066f737d8be1cb5412f572781aa525dc0b2f6e4a6f6ce805489f0149efe837c + checksum: 10c0/a988e37d5dd3e6fcd44c16b08f4778b1bf1f4b46491d1331afac9366852208b64214425331f1496c3666fd284ad42c14ef8b5f678ade94fe82534d1e631c4ae8 languageName: node linkType: hard @@ -7970,7 +7970,7 @@ __metadata: "@storybook/channels": "workspace:*" "@storybook/client-logger": "workspace:*" "@storybook/core-events": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^1.2.5" "@storybook/router": "workspace:*" @@ -8316,7 +8316,7 @@ __metadata: "@storybook/client-logger": "workspace:*" "@storybook/core-common": "workspace:*" "@storybook/core-events": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/global": "npm:^5.0.0" "@storybook/types": "workspace:*" "@types/qs": "npm:^6.9.5" @@ -8505,7 +8505,7 @@ __metadata: "@storybook/core-events": "workspace:*" "@storybook/core-server": "workspace:*" "@storybook/core-webpack": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/csf-plugin": "workspace:*" "@storybook/csf-tools": "workspace:*" "@storybook/docs-tools": "workspace:*" @@ -8665,7 +8665,7 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/server@workspace:renderers/server" dependencies: - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/csf-tools": "workspace:*" "@storybook/global": "npm:^5.0.0" "@storybook/preview-api": "workspace:*" @@ -8683,7 +8683,7 @@ __metadata: version: 0.0.0-use.local resolution: "@storybook/source-loader@workspace:lib/source-loader" dependencies: - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@storybook/types": "workspace:*" estraverse: "npm:^5.2.0" lodash: "npm:^4.17.21" @@ -8866,7 +8866,7 @@ __metadata: resolution: "@storybook/types@workspace:lib/types" dependencies: "@storybook/channels": "workspace:*" - "@storybook/csf": "npm:^0.1.2" + "@storybook/csf": "npm:^0.1.4" "@types/express": "npm:^4.7.0" "@types/fs-extra": "npm:^11.0.1" "@types/node": "npm:^18.0.0" @@ -33362,8 +33362,8 @@ __metadata: linkType: hard "webpack-dev-middleware@npm:^6.1.2": - version: 6.1.2 - resolution: "webpack-dev-middleware@npm:6.1.2" + version: 6.1.3 + resolution: "webpack-dev-middleware@npm:6.1.3" dependencies: colorette: "npm:^2.0.10" memfs: "npm:^3.4.12" @@ -33375,7 +33375,7 @@ __metadata: peerDependenciesMeta: webpack: optional: true - checksum: 10c0/90c415a770c7db493f4a7d8f3308d761ff63249f628fa8a133eac5a61e849cdf658398e189fc2d95ce0ea884641363f964db6b269c6cea877765321dd7f14b9a + checksum: 10c0/0f31670835f3c0f588392235a6183facf314c0dca312467254a56458142be6fee746f7f6b304f281c740364fd36f256c597ab37d87e5971633cee2f70a8cd5e7 languageName: node linkType: hard