@adobe-commerce/elsie 1.0.0-alpha04071347
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.elsie.js +21 -0
- package/.eslintrc.js +18 -0
- package/README.md +52 -0
- package/__mocks__/svg.js +11 -0
- package/bin/builders/build/index.js +20 -0
- package/bin/builders/generate/api/index.js +65 -0
- package/bin/builders/generate/api/templates/function.js +9 -0
- package/bin/builders/generate/api/templates/index.js +7 -0
- package/bin/builders/generate/api/templates/story.js +23 -0
- package/bin/builders/generate/api/templates/unit-test.js +15 -0
- package/bin/builders/generate/component/index.js +87 -0
- package/bin/builders/generate/component/templates/Component.js +43 -0
- package/bin/builders/generate/component/templates/css.js +24 -0
- package/bin/builders/generate/component/templates/index.js +8 -0
- package/bin/builders/generate/component/templates/stories.js +46 -0
- package/bin/builders/generate/component/templates/unit-test.js +19 -0
- package/bin/builders/generate/config/index.js +54 -0
- package/bin/builders/generate/config/templates/elsie.js +29 -0
- package/bin/builders/generate/container/index.js +65 -0
- package/bin/builders/generate/container/templates/Component.js +18 -0
- package/bin/builders/generate/container/templates/index.js +8 -0
- package/bin/builders/generate/container/templates/stories.js +34 -0
- package/bin/builders/generate/container/templates/unit-test.js +19 -0
- package/bin/builders/generate/index.js +283 -0
- package/bin/builders/gql/createOrClearDirectory.js +33 -0
- package/bin/builders/gql/getSchemaRef.js +25 -0
- package/bin/builders/gql/index.js +71 -0
- package/bin/builders/lint/index.js +5 -0
- package/bin/builders/serve/index.js +44 -0
- package/bin/builders/storybook/index.js +5 -0
- package/bin/builders/test/index.js +5 -0
- package/bin/index.js +26 -0
- package/bin/lib/cli.js +8 -0
- package/bin/lib/config.js +12 -0
- package/bin/lib/log-message.js +11 -0
- package/bin/lib/string.js +26 -0
- package/bin/lib/validate-typeof.js +28 -0
- package/bin/lib/write-file.js +30 -0
- package/bin/lib/write-parent-index.js +45 -0
- package/config/eslint.js +113 -0
- package/config/jest.js +90 -0
- package/config/prettier.js +16 -0
- package/config/setEnvVars.js +14 -0
- package/config/storybook/addon.js +130 -0
- package/config/storybook/components/FileTree/FileTree.jsx +192 -0
- package/config/storybook/components/FileTree/index.js +10 -0
- package/config/storybook/components/Flex/Flex.jsx +21 -0
- package/config/storybook/components/Flex/Flex.module.css +29 -0
- package/config/storybook/components/Flex/index.js +10 -0
- package/config/storybook/components/OptionsTable/OptionsTable.jsx +88 -0
- package/config/storybook/components/OptionsTable/OptionsTable.module.css +104 -0
- package/config/storybook/components/OptionsTable/index.js +10 -0
- package/config/storybook/components/Panel/Panel.module.css +56 -0
- package/config/storybook/components/Panel/Panel.tsx +46 -0
- package/config/storybook/components/Panel/index.ts +10 -0
- package/config/storybook/components/Screenshot/Screenshot.jsx +23 -0
- package/config/storybook/components/Screenshot/Screenshot.module.css +28 -0
- package/config/storybook/components/Screenshot/index.js +10 -0
- package/config/storybook/components/Steps/Steps.jsx +21 -0
- package/config/storybook/components/Steps/Steps.module.css +43 -0
- package/config/storybook/components/Steps/index.js +10 -0
- package/config/storybook/components/StoryWrapper/StoryWrapper.jsx +18 -0
- package/config/storybook/components/StoryWrapper/StoryWrapper.module.css +22 -0
- package/config/storybook/components/StoryWrapper/index.js +10 -0
- package/config/storybook/components/Summary/Summary.jsx +19 -0
- package/config/storybook/components/Summary/Summary.module.css +20 -0
- package/config/storybook/components/Summary/index.js +10 -0
- package/config/storybook/components/Variants/Variants.js +57 -0
- package/config/storybook/components/Variants/docs.css +48 -0
- package/config/storybook/components/Variants/index.js +10 -0
- package/config/storybook/components/video/index.jsx +28 -0
- package/config/storybook/manager.js +23 -0
- package/config/storybook/preview.jsx +88 -0
- package/config/storybook/theming/fonts.css +68 -0
- package/config/storybook/theming/logo.svg +19 -0
- package/config/storybook/theming/manager.css +63 -0
- package/config/storybook/theming/preview.css +93 -0
- package/config/storybook/theming/theme.js +61 -0
- package/config/tsconfig-base.json +16 -0
- package/config/tsconfig-preact.json +15 -0
- package/config/vite.mjs +306 -0
- package/package.json +113 -0
- package/post-release.sh +5 -0
- package/src/components/Accordion/Accordion.css +88 -0
- package/src/components/Accordion/Accordion.stories.tsx +582 -0
- package/src/components/Accordion/Accordion.tsx +177 -0
- package/src/components/Accordion/index.ts +11 -0
- package/src/components/ActionButton/ActionButton.css +100 -0
- package/src/components/ActionButton/ActionButton.stories.tsx +169 -0
- package/src/components/ActionButton/ActionButton.tsx +53 -0
- package/src/components/ActionButton/index.ts +10 -0
- package/src/components/ActionButtonGroup/ActionButtonGroup.css +77 -0
- package/src/components/ActionButtonGroup/ActionButtonGroup.stories.tsx +97 -0
- package/src/components/ActionButtonGroup/ActionButtonGroup.tsx +91 -0
- package/src/components/ActionButtonGroup/index.ts +10 -0
- package/src/components/AlertBanner/AlertBanner.css +144 -0
- package/src/components/AlertBanner/AlertBanner.stories.tsx +165 -0
- package/src/components/AlertBanner/AlertBanner.tsx +90 -0
- package/src/components/AlertBanner/index.ts +11 -0
- package/src/components/Breadcrumbs/Breadcrumbs.css +60 -0
- package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +195 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +71 -0
- package/src/components/Breadcrumbs/index.ts +11 -0
- package/src/components/Button/Button.css +213 -0
- package/src/components/Button/Button.mdx +133 -0
- package/src/components/Button/Button.stories.tsx +398 -0
- package/src/components/Button/Button.tsx +121 -0
- package/src/components/Button/index.ts +11 -0
- package/src/components/Card/Card.css +34 -0
- package/src/components/Card/Card.stories.tsx +76 -0
- package/src/components/Card/Card.tsx +34 -0
- package/src/components/Card/index.ts +10 -0
- package/src/components/CartItem/CartItem.css +509 -0
- package/src/components/CartItem/CartItem.stories.tsx +628 -0
- package/src/components/CartItem/CartItem.tsx +467 -0
- package/src/components/CartItem/CartItemSkeleton.tsx +38 -0
- package/src/components/CartItem/index.ts +12 -0
- package/src/components/CartList/CartList.css +35 -0
- package/src/components/CartList/CartList.stories.tsx +111 -0
- package/src/components/CartList/CartList.tsx +40 -0
- package/src/components/CartList/index.ts +11 -0
- package/src/components/Checkbox/Checkbox.css +255 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +290 -0
- package/src/components/Checkbox/Checkbox.tsx +138 -0
- package/src/components/Checkbox/index.ts +10 -0
- package/src/components/ColorSwatch/ColorSwatch.css +132 -0
- package/src/components/ColorSwatch/ColorSwatch.stories.tsx +274 -0
- package/src/components/ColorSwatch/ColorSwatch.tsx +127 -0
- package/src/components/ColorSwatch/index.ts +11 -0
- package/src/components/ContentGrid/ContentGrid.css +54 -0
- package/src/components/ContentGrid/ContentGrid.stories.tsx +137 -0
- package/src/components/ContentGrid/ContentGrid.tsx +57 -0
- package/src/components/ContentGrid/index.ts +11 -0
- package/src/components/Divider/Divider.css +22 -0
- package/src/components/Divider/Divider.stories.tsx +62 -0
- package/src/components/Divider/Divider.tsx +33 -0
- package/src/components/Divider/index.ts +11 -0
- package/src/components/Field/Field.css +83 -0
- package/src/components/Field/Field.stories.tsx +238 -0
- package/src/components/Field/Field.tsx +84 -0
- package/src/components/Field/index.ts +10 -0
- package/src/components/Header/Header.css +56 -0
- package/src/components/Header/Header.stories.tsx +180 -0
- package/src/components/Header/Header.tsx +81 -0
- package/src/components/Header/index.ts +11 -0
- package/src/components/Icon/Icon.css +26 -0
- package/src/components/Icon/Icon.stories.helpers.jsx +21 -0
- package/src/components/Icon/Icon.stories.tsx +98 -0
- package/src/components/Icon/Icon.tsx +112 -0
- package/src/components/Icon/index.ts +10 -0
- package/src/components/IllustratedMessage/IllustratedMessage.css +61 -0
- package/src/components/IllustratedMessage/IllustratedMessage.stories.tsx +126 -0
- package/src/components/IllustratedMessage/IllustratedMessage.tsx +78 -0
- package/src/components/IllustratedMessage/index.ts +11 -0
- package/src/components/Image/Image.css +52 -0
- package/src/components/Image/Image.stories.tsx +89 -0
- package/src/components/Image/Image.tsx +66 -0
- package/src/components/Image/index.ts +10 -0
- package/src/components/ImageSwatch/ImageSwatch.css +154 -0
- package/src/components/ImageSwatch/ImageSwatch.stories.tsx +310 -0
- package/src/components/ImageSwatch/ImageSwatch.tsx +123 -0
- package/src/components/ImageSwatch/index.ts +11 -0
- package/src/components/InLineAlert/InLineAlert.css +116 -0
- package/src/components/InLineAlert/InLineAlert.stories.tsx +326 -0
- package/src/components/InLineAlert/InLineAlert.tsx +128 -0
- package/src/components/InLineAlert/index.ts +11 -0
- package/src/components/Incrementer/Incrementer.css +165 -0
- package/src/components/Incrementer/Incrementer.stories.tsx +172 -0
- package/src/components/Incrementer/Incrementer.tsx +192 -0
- package/src/components/Incrementer/index.ts +10 -0
- package/src/components/Input/Input.css +304 -0
- package/src/components/Input/Input.stories.tsx +155 -0
- package/src/components/Input/Input.tsx +166 -0
- package/src/components/Input/index.ts +11 -0
- package/src/components/InputDate/InputDate.css +56 -0
- package/src/components/InputDate/InputDate.stories.tsx +117 -0
- package/src/components/InputDate/InputDate.tsx +120 -0
- package/src/components/InputDate/index.ts +11 -0
- package/src/components/InputPassword/InputPassword.css +31 -0
- package/src/components/InputPassword/InputPassword.stories.tsx +148 -0
- package/src/components/InputPassword/InputPassword.tsx +135 -0
- package/src/components/InputPassword/PasswordStatusIndicator/PasswordStatusIndicator.css +31 -0
- package/src/components/InputPassword/PasswordStatusIndicator/PasswordStatusIndicator.tsx +96 -0
- package/src/components/InputPassword/PasswordStatusIndicator/index.ts +11 -0
- package/src/components/InputPassword/index.ts +11 -0
- package/src/components/Modal/Modal.css +125 -0
- package/src/components/Modal/Modal.stories.tsx +250 -0
- package/src/components/Modal/Modal.tsx +157 -0
- package/src/components/Modal/index.ts +10 -0
- package/src/components/Pagination/Pagination.css +95 -0
- package/src/components/Pagination/Pagination.stories.tsx +117 -0
- package/src/components/Pagination/Pagination.tsx +149 -0
- package/src/components/Pagination/index.ts +11 -0
- package/src/components/Picker/Picker.css +220 -0
- package/src/components/Picker/Picker.stories.tsx +318 -0
- package/src/components/Picker/Picker.tsx +203 -0
- package/src/components/Picker/index.ts +10 -0
- package/src/components/Price/Price.css +57 -0
- package/src/components/Price/Price.stories.tsx +110 -0
- package/src/components/Price/Price.tsx +75 -0
- package/src/components/Price/index.ts +10 -0
- package/src/components/PriceRange/PriceRange.css +66 -0
- package/src/components/PriceRange/PriceRange.stories.tsx +240 -0
- package/src/components/PriceRange/PriceRange.tsx +248 -0
- package/src/components/PriceRange/index.ts +11 -0
- package/src/components/ProgressSpinner/ProgressSpinner.css +91 -0
- package/src/components/ProgressSpinner/ProgressSpinner.stories.tsx +300 -0
- package/src/components/ProgressSpinner/ProgressSpinner.tsx +86 -0
- package/src/components/ProgressSpinner/index.ts +11 -0
- package/src/components/RadioButton/RadioButton.css +134 -0
- package/src/components/RadioButton/RadioButton.stories.tsx +126 -0
- package/src/components/RadioButton/RadioButton.tsx +86 -0
- package/src/components/RadioButton/index.ts +11 -0
- package/src/components/Skeleton/Skeleton.css +145 -0
- package/src/components/Skeleton/Skeleton.stories.tsx +265 -0
- package/src/components/Skeleton/Skeleton.tsx +133 -0
- package/src/components/Skeleton/index.ts +10 -0
- package/src/components/Tag/Tag.css +26 -0
- package/src/components/Tag/Tag.stories.tsx +103 -0
- package/src/components/Tag/Tag.tsx +38 -0
- package/src/components/Tag/index.ts +11 -0
- package/src/components/TextArea/TextArea.css +140 -0
- package/src/components/TextArea/TextArea.stories.tsx +130 -0
- package/src/components/TextArea/TextArea.tsx +89 -0
- package/src/components/TextArea/index.ts +11 -0
- package/src/components/TextSwatch/TextSwatch.css +152 -0
- package/src/components/TextSwatch/TextSwatch.stories.tsx +277 -0
- package/src/components/TextSwatch/TextSwatch.tsx +131 -0
- package/src/components/TextSwatch/index.ts +11 -0
- package/src/components/ToggleButton/ToggleButton.css +95 -0
- package/src/components/ToggleButton/ToggleButton.stories.tsx +190 -0
- package/src/components/ToggleButton/ToggleButton.tsx +75 -0
- package/src/components/ToggleButton/index.ts +11 -0
- package/src/components/UIProvider/UIProvider.css +140 -0
- package/src/components/UIProvider/UIProvider.tsx +61 -0
- package/src/components/UIProvider/debugger.css +47 -0
- package/src/components/UIProvider/index.ts +10 -0
- package/src/components/UIProvider/normalize.css +26 -0
- package/src/components/index.ts +49 -0
- package/src/docs/API/event-bus.mdx +52 -0
- package/src/docs/API/graphql.mdx +214 -0
- package/src/docs/API/initializer.mdx +119 -0
- package/src/docs/API/render.mdx +125 -0
- package/src/docs/Design/colors.mdx +202 -0
- package/src/docs/Design/designBlocks.jsx +87 -0
- package/src/docs/Design/getTokenData.ts +28 -0
- package/src/docs/Design/grid.mdx +365 -0
- package/src/docs/Design/overview.mdx +69 -0
- package/src/docs/Design/shapes.mdx +100 -0
- package/src/docs/Design/spacing.mdx +22 -0
- package/src/docs/Design/typography.mdx +126 -0
- package/src/docs/Utilities/classList.mdx +52 -0
- package/src/docs/Utilities/debounce.mdx +49 -0
- package/src/docs/Utilities/deepmerge.mdx +12 -0
- package/src/docs/Utilities/getFormErrors.mdx +41 -0
- package/src/docs/Utilities/getFormValues.mdx +38 -0
- package/src/docs/assets/Banner.png +0 -0
- package/src/docs/assets/Colors.png +0 -0
- package/src/docs/assets/DropinBanner.png +0 -0
- package/src/docs/assets/ShapeStyles.png +0 -0
- package/src/docs/assets/Spacing.png +0 -0
- package/src/docs/assets/Typography.png +0 -0
- package/src/docs/cli-usage.mdx +181 -0
- package/src/docs/components/overview.mdx +124 -0
- package/src/docs/quick-start.mdx +245 -0
- package/src/docs/slots.mdx +211 -0
- package/src/docs/welcome.mdx +52 -0
- package/src/i18n/en_US.json +146 -0
- package/src/i18n/index.ts +26 -0
- package/src/icons/Add.svg +9 -0
- package/src/icons/AddressBook.svg +3 -0
- package/src/icons/Bulk.svg +24 -0
- package/src/icons/Burger.svg +5 -0
- package/src/icons/Card.svg +7 -0
- package/src/icons/Cart.svg +11 -0
- package/src/icons/Check.svg +8 -0
- package/src/icons/CheckWithCircle.svg +4 -0
- package/src/icons/ChevronDown.svg +3 -0
- package/src/icons/ChevronRight.svg +8 -0
- package/src/icons/ChevronUp.svg +3 -0
- package/src/icons/Close.svg +4 -0
- package/src/icons/Coupon.svg +3 -0
- package/src/icons/Date.svg +4 -0
- package/src/icons/Delivery.svg +11 -0
- package/src/icons/EmptyBox.svg +3 -0
- package/src/icons/Eye.svg +3 -0
- package/src/icons/EyeClose.svg +3 -0
- package/src/icons/Gift.svg +3 -0
- package/src/icons/GiftCard.svg +3 -0
- package/src/icons/Heart.svg +3 -0
- package/src/icons/HeartFilled.svg +3 -0
- package/src/icons/InfoFilled.svg +3 -0
- package/src/icons/Locker.svg +11 -0
- package/src/icons/Minus.svg +3 -0
- package/src/icons/Order.svg +6 -0
- package/src/icons/OrderError.svg +15 -0
- package/src/icons/OrderSuccess.svg +15 -0
- package/src/icons/PaymentError.svg +16 -0
- package/src/icons/Placeholder.svg +3 -0
- package/src/icons/PlaceholderFilled.svg +4 -0
- package/src/icons/Search.svg +9 -0
- package/src/icons/SearchFilled.svg +10 -0
- package/src/icons/Sort.svg +12 -0
- package/src/icons/Star.svg +8 -0
- package/src/icons/Trash.svg +7 -0
- package/src/icons/User.svg +5 -0
- package/src/icons/View.svg +14 -0
- package/src/icons/Wallet.svg +6 -0
- package/src/icons/Warning.svg +12 -0
- package/src/icons/WarningFilled.svg +3 -0
- package/src/icons/WarningWithCircle.svg +4 -0
- package/src/icons/index.ts +42 -0
- package/src/lib/classes.ts +34 -0
- package/src/lib/config.ts +24 -0
- package/src/lib/debounce.ts +16 -0
- package/src/lib/deepmerge.ts +45 -0
- package/src/lib/deviceUtils.ts +16 -0
- package/src/lib/form-values.ts +31 -0
- package/src/lib/i18n.ts +18 -0
- package/src/lib/image-params-keymap.ts +36 -0
- package/src/lib/index.ts +24 -0
- package/src/lib/initializer.ts +134 -0
- package/src/lib/is-number.ts +12 -0
- package/src/lib/render.tsx +138 -0
- package/src/lib/resolve-image.ts +101 -0
- package/src/lib/signals.ts +11 -0
- package/src/lib/slot.tsx +434 -0
- package/src/lib/tests.tsx +47 -0
- package/src/lib/types.ts +16 -0
- package/src/lib/vcomponent.tsx +42 -0
- package/static/assets/images/Card.png +0 -0
- package/static/assets/images/example.jpg +0 -0
- package/static/assets/images/index.ts +11 -0
- package/static/dropin.png +0 -0
- package/static/favicon.svg +14 -0
- package/storybook-stories.js +21 -0
- package/tests/__mocks__/browserMocks.ts +28 -0
- package/tests/__mocks__/fileMocks.ts +12 -0
- package/tests/__mocks__/styleMock.ts +0 -0
- package/types/icons.d.ts +18 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const { source } = require('common-tags');
|
|
2
|
+
|
|
3
|
+
module.exports = ({ pathname, basename, importPath = '.' }) => {
|
|
4
|
+
return `${source`
|
|
5
|
+
// https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
|
|
6
|
+
import type { Meta, StoryObj } from '@storybook/preact';
|
|
7
|
+
import { ${basename} as component, ${basename}Props } from '${importPath}';
|
|
8
|
+
|
|
9
|
+
const meta: Meta<${basename}Props> = {
|
|
10
|
+
title: 'Containers/${pathname}',
|
|
11
|
+
component,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: 'centered', // centered | fullscreen
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
|
|
20
|
+
type Story = StoryObj<${basename}Props>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* \`\`\`ts
|
|
24
|
+
* import { ${basename} } from '${importPath}';
|
|
25
|
+
* \`\`\`
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export const ${basename}: Story = {
|
|
29
|
+
args: {
|
|
30
|
+
children: "👋 Howdy, I'm Howdy!",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
`}\n`;
|
|
34
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const { source } = require('common-tags');
|
|
2
|
+
|
|
3
|
+
module.exports = ({ name, basename, pathname, importPath = '.' }) => {
|
|
4
|
+
return `${source`
|
|
5
|
+
/** https://preactjs.com/guide/v10/preact-testing-library/ */
|
|
6
|
+
|
|
7
|
+
import { render } from '@adobe-commerce/elsie/lib/tests';
|
|
8
|
+
|
|
9
|
+
import { ${basename} } from '${importPath}';
|
|
10
|
+
|
|
11
|
+
describe('${name}/Containers/${pathname}', () => {
|
|
12
|
+
test('renders', () => {
|
|
13
|
+
const { container } = render(<${basename} />);
|
|
14
|
+
|
|
15
|
+
expect(!!container).toEqual(true);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
`}\n`;
|
|
19
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { toPascalCase, toCamelCase } = require('../../lib/string');
|
|
3
|
+
const m = require('../../lib/log-message');
|
|
4
|
+
const validateTypeOf = require('../../lib/validate-typeof');
|
|
5
|
+
const config = require('../../lib/config')();
|
|
6
|
+
|
|
7
|
+
module.exports = function generateResourceBuilder(yargs) {
|
|
8
|
+
yargs
|
|
9
|
+
.usage('usage: $0 generate <resource> [options]')
|
|
10
|
+
|
|
11
|
+
// Configuration
|
|
12
|
+
.command(
|
|
13
|
+
'config',
|
|
14
|
+
'Generate configuration file',
|
|
15
|
+
(yargs) => {
|
|
16
|
+
return yargs.options({
|
|
17
|
+
name: {
|
|
18
|
+
alias: 'n',
|
|
19
|
+
decription: 'Namespace of the project',
|
|
20
|
+
type: 'string',
|
|
21
|
+
demandOption: m('Missing project name.', 'error'),
|
|
22
|
+
},
|
|
23
|
+
force: {
|
|
24
|
+
description: 'Rewrite existing file',
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
require('./config')
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
// New Api Function
|
|
33
|
+
.command(
|
|
34
|
+
'api',
|
|
35
|
+
'Generate a new API function',
|
|
36
|
+
(yargs) => {
|
|
37
|
+
return yargs
|
|
38
|
+
.options({
|
|
39
|
+
pathname: {
|
|
40
|
+
alias: 'n',
|
|
41
|
+
demandOption: true,
|
|
42
|
+
description: 'Resource pathname',
|
|
43
|
+
type: 'string',
|
|
44
|
+
},
|
|
45
|
+
force: {
|
|
46
|
+
description: 'Rewrite existing files',
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
.check((args) => {
|
|
51
|
+
if (!config) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
m(
|
|
54
|
+
'Configuration file ".elsie.js" not found. Make sure you are in the root directory of your project or generate a new one.',
|
|
55
|
+
'error'
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!config.name) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
m(`Missing \x1b[31mname\x1b[0m in "./.elsie.js".`, 'error')
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const basename = path.basename(args.pathname);
|
|
67
|
+
|
|
68
|
+
// Is the configuration valid
|
|
69
|
+
const errors = validateTypeOf(config.api, {
|
|
70
|
+
root: { required: true, type: 'string' },
|
|
71
|
+
importAliasRoot: { type: 'string' },
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (errors.length) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
errors
|
|
77
|
+
.map((e) =>
|
|
78
|
+
m(
|
|
79
|
+
`Invalid \x1b[31mapi.${e}\x1b[0m value "${config.api[e]}" in "./.elsie.js".`,
|
|
80
|
+
'error'
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
.join('\n')
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Check the basename is camelCase
|
|
88
|
+
if (!/^[a-z]+([A-Z]|[a-z]|[0-9]+)+$/.test(basename)) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
m(
|
|
91
|
+
`\x1b[4m${basename}\x1b[0m is not a valid API function name. Try naming your API function with camel case. i.e. \x1b[4m${toCamelCase(
|
|
92
|
+
basename
|
|
93
|
+
)}\x1b[0m`,
|
|
94
|
+
'error'
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return true;
|
|
100
|
+
}, false);
|
|
101
|
+
},
|
|
102
|
+
require('./api')
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
// New Component
|
|
106
|
+
.command(
|
|
107
|
+
'component',
|
|
108
|
+
'Generate a new UI Component',
|
|
109
|
+
(yargs) => {
|
|
110
|
+
return yargs
|
|
111
|
+
.options({
|
|
112
|
+
group: {
|
|
113
|
+
alias: 'g',
|
|
114
|
+
default: config?.components?.find((x) => x.default)?.id,
|
|
115
|
+
description: 'Components group',
|
|
116
|
+
choices: config?.components?.map((x) => x.id) || undefined,
|
|
117
|
+
},
|
|
118
|
+
pathname: {
|
|
119
|
+
alias: 'n',
|
|
120
|
+
demandOption: true,
|
|
121
|
+
description: 'Resource pathname',
|
|
122
|
+
type: 'string',
|
|
123
|
+
},
|
|
124
|
+
force: {
|
|
125
|
+
description: 'Rewrite existing files',
|
|
126
|
+
type: 'boolean',
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
.check((args) => {
|
|
130
|
+
if (!config) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
m(
|
|
133
|
+
'Configuration file ".elsie.js" not found. Make sure you are in the root directory of your project or generate a new one.',
|
|
134
|
+
'error'
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!args.group) {
|
|
140
|
+
throw new Error(m('Missing component group name.', 'error'));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!config.name) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
m(`Missing \x1b[31mname\x1b[0m in "./.elsie.js".`, 'error')
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const group = config.components.find((x) => x.id === args.group);
|
|
150
|
+
const basename = path.basename(args.pathname);
|
|
151
|
+
|
|
152
|
+
// Is the configuration valid
|
|
153
|
+
const errors = validateTypeOf(group, {
|
|
154
|
+
root: { required: true, type: 'string' },
|
|
155
|
+
importAliasRoot: { type: 'string' },
|
|
156
|
+
cssPrefix: {
|
|
157
|
+
required: !group.skipCSS,
|
|
158
|
+
type: 'string',
|
|
159
|
+
},
|
|
160
|
+
skipCSS: { type: 'boolean' },
|
|
161
|
+
default: { type: 'boolean' },
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
if (errors.length) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
errors
|
|
167
|
+
.map((e) =>
|
|
168
|
+
m(
|
|
169
|
+
`Invalid \x1b[31mcomponents[${group.id}].${e}\x1b[0m value "${group[e]}" in "./.elsie.js".`,
|
|
170
|
+
'error'
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
.join('\n')
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Check the basename is PascalCase
|
|
178
|
+
if (!/^([A-Z][a-z0-9]+)*[A-Z][a-z0-9]*$/.test(basename)) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
m(
|
|
181
|
+
`\x1b[4m${basename}\x1b[0m is not a valid component name. Try naming your component with pascal case. i.e. \x1b[4m${toPascalCase(
|
|
182
|
+
basename
|
|
183
|
+
)}\x1b[0m`,
|
|
184
|
+
'error'
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return true;
|
|
190
|
+
}, false);
|
|
191
|
+
},
|
|
192
|
+
require('./component')
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
// New Container
|
|
196
|
+
.command(
|
|
197
|
+
'container',
|
|
198
|
+
'Generate a new Frontend Container',
|
|
199
|
+
(yargs) => {
|
|
200
|
+
return yargs
|
|
201
|
+
.options({
|
|
202
|
+
pathname: {
|
|
203
|
+
alias: 'n',
|
|
204
|
+
demandOption: true,
|
|
205
|
+
description: 'Resource pathname',
|
|
206
|
+
type: 'string',
|
|
207
|
+
},
|
|
208
|
+
force: {
|
|
209
|
+
description: 'Rewrite existing files',
|
|
210
|
+
type: 'boolean',
|
|
211
|
+
},
|
|
212
|
+
})
|
|
213
|
+
.check((args) => {
|
|
214
|
+
if (!config) {
|
|
215
|
+
throw new Error(
|
|
216
|
+
m(
|
|
217
|
+
'Configuration file ".elsie.js" not found. Make sure you are in the root directory of your project or generate a new one.',
|
|
218
|
+
'error'
|
|
219
|
+
)
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (!config.containers) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
m(
|
|
226
|
+
`Missing \x1b[31mcontainers\x1b[0m in "./.elsie.js".`,
|
|
227
|
+
'error'
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!config.name) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
m(`Missing \x1b[31mname\x1b[0m in "./.elsie.js".`, 'error')
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const basename = path.basename(args.pathname);
|
|
239
|
+
|
|
240
|
+
// Is the configuration valid
|
|
241
|
+
const errors = validateTypeOf(config.containers, {
|
|
242
|
+
root: { required: true, type: 'string' },
|
|
243
|
+
importAliasRoot: { type: 'string' },
|
|
244
|
+
default: { type: 'boolean' },
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (errors.length) {
|
|
248
|
+
throw new Error(
|
|
249
|
+
errors
|
|
250
|
+
.map((e) =>
|
|
251
|
+
m(
|
|
252
|
+
`Invalid \x1b[31mcontainers.${e}\x1b[0m value "${config.containers[e]}" in "./.elsie.js".`,
|
|
253
|
+
'error'
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
.join('\n')
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Check the basename is PascalCase
|
|
261
|
+
if (!/^([A-Z][a-z0-9]+)*[A-Z][a-z0-9]*$/.test(basename)) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
m(
|
|
264
|
+
`\x1b[4m${basename}\x1b[0m is not a valid container name. Try naming your container with pascal case. i.e. \x1b[4m${toPascalCase(
|
|
265
|
+
basename
|
|
266
|
+
)}\x1b[0m`,
|
|
267
|
+
'error'
|
|
268
|
+
)
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return true;
|
|
273
|
+
}, false);
|
|
274
|
+
},
|
|
275
|
+
require('./container')
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
//
|
|
279
|
+
.updateStrings({
|
|
280
|
+
'Commands:': 'Tools & Resources:',
|
|
281
|
+
})
|
|
282
|
+
.demandCommand();
|
|
283
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fsPromises = require('node:fs/promises');
|
|
3
|
+
|
|
4
|
+
module.exports = async function createOrClearDirectory(fileName) {
|
|
5
|
+
const directoryPath = path.join(process.cwd(), 'src/__generated__');
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
// Check if the directory exists
|
|
9
|
+
const dirStats = await fsPromises.stat(directoryPath);
|
|
10
|
+
|
|
11
|
+
if (dirStats.isDirectory()) {
|
|
12
|
+
// If it's a directory, remove all files and subdirectories
|
|
13
|
+
const entries = await fsPromises.readdir(directoryPath);
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
// If fileName is provided and it matches the current entry, remove it
|
|
16
|
+
// If fileName is not provided, remove all entries
|
|
17
|
+
if (!fileName || fileName === entry) {
|
|
18
|
+
const entryPath = path.join(directoryPath, entry);
|
|
19
|
+
await fsPromises.rm(entryPath, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
await fsPromises.mkdir(directoryPath, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
// If the directory doesn't exist, create it
|
|
27
|
+
if (error.code === 'ENOENT') {
|
|
28
|
+
await fsPromises.mkdir(directoryPath, { recursive: true });
|
|
29
|
+
} else {
|
|
30
|
+
throw error; // Re-throw any unexpected errors
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the schema reference as defined in implementation's .elsie.js
|
|
3
|
+
*
|
|
4
|
+
* @see https://the-guild.dev/graphql/codegen/docs/config-reference/schema-field
|
|
5
|
+
* @returns [graphql-config.SchemaPointer] or [graphql-config.SchemaPointer[]]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const config = require('../../lib/config');
|
|
9
|
+
|
|
10
|
+
module.exports = function getSchemaRef() {
|
|
11
|
+
const { schema } = config();
|
|
12
|
+
if (!schema || !schema.endpoint) {
|
|
13
|
+
throw new Error('Missing schema.endpoint in .elsie.js');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
[schema.endpoint]: {
|
|
19
|
+
headers: {
|
|
20
|
+
...(schema.headers || {}),
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const createOrClearDirectory = require('./createOrClearDirectory');
|
|
3
|
+
const getSchemaRef = require('./getSchemaRef');
|
|
4
|
+
require('dotenv').config();
|
|
5
|
+
|
|
6
|
+
const generate = require('@graphql-codegen/cli').generate;
|
|
7
|
+
|
|
8
|
+
module.exports = async function generateResourceBuilder(yargs) {
|
|
9
|
+
yargs
|
|
10
|
+
.command('types', 'Generate types', async () => {
|
|
11
|
+
await createOrClearDirectory('types.ts');
|
|
12
|
+
await generate(
|
|
13
|
+
{
|
|
14
|
+
schema: getSchemaRef(),
|
|
15
|
+
ignoreNoDocuments: true,
|
|
16
|
+
documents: [
|
|
17
|
+
`${path.resolve(process.cwd(), './src/**/*.graphql.ts')}`,
|
|
18
|
+
`!${path.resolve(process.cwd(), './src/__generated__/**')}`,
|
|
19
|
+
],
|
|
20
|
+
generates: {
|
|
21
|
+
[`${path.resolve(process.cwd(), './src/__generated__/types.ts')}`]:
|
|
22
|
+
{
|
|
23
|
+
plugins: [
|
|
24
|
+
'@graphql-codegen/typescript',
|
|
25
|
+
'@graphql-codegen/typescript-operations',
|
|
26
|
+
],
|
|
27
|
+
hooks: { afterOneFileWrite: ['prettier --write'] },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
true
|
|
32
|
+
);
|
|
33
|
+
})
|
|
34
|
+
.command('mocks', 'Generate mocks and types', async () => {
|
|
35
|
+
await createOrClearDirectory();
|
|
36
|
+
await generate({
|
|
37
|
+
schema: getSchemaRef(),
|
|
38
|
+
ignoreNoDocuments: true,
|
|
39
|
+
documents: [
|
|
40
|
+
`${path.resolve(process.cwd(), './src/**/*.graphql.ts')}`,
|
|
41
|
+
`!${path.resolve(process.cwd(), './src/__generated__/**')}`,
|
|
42
|
+
],
|
|
43
|
+
generates: {
|
|
44
|
+
[`${path.resolve(process.cwd(), './src/__generated__/types.ts')}`]: {
|
|
45
|
+
plugins: [
|
|
46
|
+
'@graphql-codegen/typescript',
|
|
47
|
+
'@graphql-codegen/typescript-operations',
|
|
48
|
+
],
|
|
49
|
+
hooks: { afterOneFileWrite: ['prettier --write'] },
|
|
50
|
+
},
|
|
51
|
+
[`${path.resolve(process.cwd(), './src/__generated__/mocks.ts')}`]: {
|
|
52
|
+
plugins: [
|
|
53
|
+
{
|
|
54
|
+
'typescript-mock-data': {
|
|
55
|
+
addTypename: true,
|
|
56
|
+
prefix: 'mock',
|
|
57
|
+
scalars: {
|
|
58
|
+
Date: 'date',
|
|
59
|
+
},
|
|
60
|
+
// relative to the mocks.ts file
|
|
61
|
+
typesFile: './types.ts',
|
|
62
|
+
terminateCircularRelationships: true,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
})
|
|
70
|
+
.demandCommand(1, 1, 'choose a command: types or mocks');
|
|
71
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
module.exports = async function generateResourceBuilder({ argv }) {
|
|
5
|
+
const { build, preview } = await import('vite');
|
|
6
|
+
|
|
7
|
+
const configFile = argv?.config ?? path.resolve(__dirname, '../../../config/vite.mjs');
|
|
8
|
+
|
|
9
|
+
let built = false;
|
|
10
|
+
|
|
11
|
+
return build({
|
|
12
|
+
build: { watch: { buildDelay: 200 }, emptyOutDir: false },
|
|
13
|
+
logLevel: 'error',
|
|
14
|
+
clearScreen: true,
|
|
15
|
+
configFile,
|
|
16
|
+
})
|
|
17
|
+
.then((buildWatcher) => {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
buildWatcher.on('event', async ({ code }) => {
|
|
20
|
+
if (code === 'END') {
|
|
21
|
+
fs.writeFileSync(
|
|
22
|
+
path.resolve(process.cwd(), './dist/reload'),
|
|
23
|
+
JSON.stringify({
|
|
24
|
+
at: Date.now(),
|
|
25
|
+
})
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
console.log('\n📦 Dropin assets built\n');
|
|
29
|
+
|
|
30
|
+
if (!built) {
|
|
31
|
+
built = true;
|
|
32
|
+
resolve();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
})
|
|
38
|
+
.then(async () => {
|
|
39
|
+
const previewServer = await preview({ configFile });
|
|
40
|
+
console.log('\n📡 Serving dropin assets:');
|
|
41
|
+
previewServer.printUrls();
|
|
42
|
+
console.log('\n');
|
|
43
|
+
});
|
|
44
|
+
};
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require('yargs');
|
|
4
|
+
|
|
5
|
+
yargs
|
|
6
|
+
.usage('usage: $0 <command>')
|
|
7
|
+
.showHelpOnFail(true)
|
|
8
|
+
.command('storybook', 'Launch Storybook', require('./builders/storybook'))
|
|
9
|
+
.command('serve', 'Serve bundles', require('./builders/serve'))
|
|
10
|
+
.command(
|
|
11
|
+
'gql',
|
|
12
|
+
'Generates types or mocks for your API',
|
|
13
|
+
require('./builders/gql')
|
|
14
|
+
)
|
|
15
|
+
.command('build', 'Build bundles', require('./builders/build'))
|
|
16
|
+
.command('test', 'Run Jest tests', require('./builders/test'))
|
|
17
|
+
.command('lint', 'Run ESLint code analysis', require('./builders/lint'))
|
|
18
|
+
.command(
|
|
19
|
+
'generate',
|
|
20
|
+
'Generate a new <resource>',
|
|
21
|
+
require('./builders/generate')
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
.help('help')
|
|
25
|
+
|
|
26
|
+
.demandCommand().argv;
|
package/bin/lib/cli.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
module.exports = function getConfig() {
|
|
5
|
+
const configPath = path.resolve(process.cwd(), './.elsie.js');
|
|
6
|
+
|
|
7
|
+
if (!fs.existsSync(configPath)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return require(configPath);
|
|
12
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function toPascalCase(str) {
|
|
2
|
+
return str
|
|
3
|
+
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
|
4
|
+
.map((x) => x.charAt(0).toUpperCase() + x.slice(1).toLowerCase())
|
|
5
|
+
.join('');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function hyphenatedName(str) {
|
|
9
|
+
return str
|
|
10
|
+
.replace(/([A-Z])/g, (g) => `-${g.toLowerCase()}`)
|
|
11
|
+
.replace(/^-/, '');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function toCamelCase(str) {
|
|
15
|
+
return toPascalCase(str)
|
|
16
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
|
|
17
|
+
return index === 0 ? word.toLowerCase() : word.toUpperCase();
|
|
18
|
+
})
|
|
19
|
+
.replace(/\s+/g, '');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
toPascalCase,
|
|
24
|
+
hyphenatedName,
|
|
25
|
+
toCamelCase,
|
|
26
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* Copyright 2024 Adobe
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
|
+
*******************************************************************/
|
|
9
|
+
|
|
10
|
+
module.exports = function validateTypeOf(values, rules) {
|
|
11
|
+
if (!values || !rules) return null;
|
|
12
|
+
|
|
13
|
+
return Object.entries(rules).reduce((result, [key, itemRules]) => {
|
|
14
|
+
if (itemRules.required && typeof values[key] === 'undefined') {
|
|
15
|
+
return [...result, key];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (
|
|
19
|
+
itemRules.type &&
|
|
20
|
+
typeof values[key] !== 'undefined' &&
|
|
21
|
+
typeof values[key] !== itemRules.type
|
|
22
|
+
) {
|
|
23
|
+
return [...result, key];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [...result];
|
|
27
|
+
}, []);
|
|
28
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* Copyright 2024 Adobe
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
|
+
*******************************************************************/
|
|
9
|
+
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const m = require('./log-message');
|
|
13
|
+
|
|
14
|
+
module.exports = async function writeFile(filePath, content, force = false) {
|
|
15
|
+
const relativePath = path.relative('.', filePath);
|
|
16
|
+
|
|
17
|
+
if (force !== true && fs.existsSync(filePath)) {
|
|
18
|
+
console.error(m(`\x1b[31m${relativePath} \x1b[0malready exists`, 'error'));
|
|
19
|
+
return false;
|
|
20
|
+
} else {
|
|
21
|
+
await fs.promises.writeFile(filePath, content);
|
|
22
|
+
|
|
23
|
+
if (force) {
|
|
24
|
+
console.log(m(`\x1b[33m${relativePath} \x1b[0mupdated`, 'updated'));
|
|
25
|
+
} else {
|
|
26
|
+
console.log(m(`\x1b[33m${relativePath} \x1b[0mcreated`, 'created'));
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
};
|