Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ParseCodeString] Implements the ParseCodeString utilities #87

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Implements the ParseCodeString utilities",
"packageName": "@microsoft/arbutus.component-preview",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Implements the ParseCodeString utilities",
"packageName": "@microsoft/arbutus.parse-code-string",
"email": "[email protected]",
"dependentChangeType": "patch"
}
2 changes: 1 addition & 1 deletion docs/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,4 @@



window['STORIES'] = [{"titlePrefix":"","directory":"./components","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./components","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./hooks","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:hooks(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./hooks","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:hooks(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./utilities","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:utilities(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./utilities","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:utilities(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./styles","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:styles(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./styles","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:styles(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"}];</script><script src="runtime~main.05f7fa24.iframe.bundle.js"></script><script src="908.f52ea09c.iframe.bundle.js"></script><script src="main.f3ad67b8.iframe.bundle.js"></script></body></html>
window['STORIES'] = [{"titlePrefix":"","directory":"./components","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./components","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:components(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./hooks","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:hooks(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./hooks","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:hooks(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./utilities","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:utilities(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./utilities","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:utilities(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"},{"titlePrefix":"","directory":"./styles","files":"**/*.stories.mdx","importPathMatcher":"^\\.[\\\\/](?:styles(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.mdx)$"},{"titlePrefix":"","directory":"./styles","files":"**/*.stories.@(js|jsx|ts|tsx)","importPathMatcher":"^\\.[\\\\/](?:styles(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(js|jsx|ts|tsx))$"}];</script><script src="runtime~main.05f7fa24.iframe.bundle.js"></script><script src="908.f52ea09c.iframe.bundle.js"></script><script src="main.f0786e7f.iframe.bundle.js"></script></body></html>
1 change: 1 addition & 0 deletions docs/main.f0786e7f.iframe.bundle.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion docs/main.f3ad67b8.iframe.bundle.js

This file was deleted.

2 changes: 1 addition & 1 deletion docs/project.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"generatedAt":1678406000963,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":true,"hasStaticDirs":false,"hasStorybookEslint":false,"refCount":0,"monorepo":"Workspaces","packageManager":{"type":"npm","version":"8.19.2"},"storybookVersion":"6.5.15","language":"typescript","storybookPackages":{"@storybook/addon-actions":{"version":"6.5.15"},"@storybook/builder-webpack5":{"version":"6.5.15"},"@storybook/jest":{"version":"0.0.10"},"@storybook/manager-webpack5":{"version":"6.5.15"},"@storybook/react":{"version":"6.5.15"},"@storybook/testing-library":{"version":"0.0.13"}},"framework":{"name":"react"},"addons":{"@storybook/addon-links":{"version":"6.5.15"},"@storybook/addon-essentials":{"options":{"docs":false},"version":"6.5.15"},"@storybook/addon-interactions":{"version":"6.5.15"}}}
{"generatedAt":1678489849818,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":true,"hasStaticDirs":false,"hasStorybookEslint":false,"refCount":0,"monorepo":"Workspaces","packageManager":{"type":"npm","version":"8.19.2"},"storybookVersion":"6.5.15","language":"typescript","storybookPackages":{"@storybook/addon-actions":{"version":"6.5.15"},"@storybook/builder-webpack5":{"version":"6.5.15"},"@storybook/jest":{"version":"0.0.10"},"@storybook/manager-webpack5":{"version":"6.5.15"},"@storybook/react":{"version":"6.5.15"},"@storybook/testing-library":{"version":"0.0.13"}},"framework":{"name":"react"},"addons":{"@storybook/addon-links":{"version":"6.5.15"},"@storybook/addon-essentials":{"options":{"docs":false},"version":"6.5.15"},"@storybook/addon-interactions":{"version":"6.5.15"}}}
44 changes: 32 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 13 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,21 @@
"devDependencies": {
"@griffel/react": "^1.5.2",
"@microsoft/arbutus.aside-navigation": "0.0.10",
"@microsoft/arbutus.bookmark-tile": "0.0.11",
"@microsoft/arbutus.code-snippet": "^0.0.1-alpha.1",
"@microsoft/arbutus.command": "^0.0.6",
"@microsoft/arbutus.bookmark-tile": "0.0.12",
"@microsoft/arbutus.code-snippet": "0.0.1-alpha.2",
"@microsoft/arbutus.command": "0.0.7",
"@microsoft/arbutus.divider": "0.0.3",
"@microsoft/arbutus.file-to-string": "^0.0.1",
"@microsoft/arbutus.icon": "0.1.0",
"@microsoft/arbutus.icon-button": "0.0.8",
"@microsoft/arbutus.link": "0.0.11",
"@microsoft/arbutus.main-navigation": "0.2.1",
"@microsoft/arbutus.mark-list": "0.0.8",
"@microsoft/arbutus.recommendation-tile": "0.1.8",
"@microsoft/arbutus.tabs": "0.0.7",
"@microsoft/arbutus.file-to-string": "0.0.2",
"@microsoft/arbutus.icon": "0.1.1",
"@microsoft/arbutus.icon-button": "0.0.9",
"@microsoft/arbutus.link": "0.0.12",
"@microsoft/arbutus.main-navigation": "0.2.2",
"@microsoft/arbutus.mark-list": "0.0.9",
"@microsoft/arbutus.recommendation-tile": "0.1.9",
"@microsoft/arbutus.table-list": "^0.1.0",
"@microsoft/arbutus.tabs": "0.0.8",
"@microsoft/arbutus.text": "0.1.3",
"@microsoft/arbutus.theme-switch": "0.0.3",
"@microsoft/arbutus.theme-switch": "0.0.4",
"@microsoft/arbutus.theming": "0.0.6",
"@microsoft/arbutus.tile": "0.0.7",
"@microsoft/arbutus.ts": "0.0.2",
Expand Down
16 changes: 16 additions & 0 deletions utilities/parse-code-string/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# configs
just.config.js
**/.eslintrc.js
**/tsconfig.js
lage.config.js
**/*.config.js

# generated folders
__snapshots__
.cache
dist
lib
node_modules

# template files which actually follow a different language's formatting
_templates
8 changes: 8 additions & 0 deletions utilities/parse-code-string/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
__tests__
__dev__
.cache
node_modules
src
.eslintrc
.eslintignore
tsconfig.json
13 changes: 13 additions & 0 deletions utilities/parse-code-string/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Utility: Parse Code String

**Utility functions that receive code as a string and return information about it.**

## Get Started

```sh
npm i "@microsoft/arbutus.parse-code-string"
```

```ts
import { parseCodeString } from "@microsoft/arbutus.parse-code-string";
```
25 changes: 25 additions & 0 deletions utilities/parse-code-string/__dev__/example-component.raw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export default `import { mergeClasses } from '@griffel/react';
import { Text } from '@microsoft/arbutus.text';
import { Tile } from '@microsoft/arbutus.tile';
import { useSpaceStyles } from '@microsoft/arbutus.use-space-styles';
import * as React from 'react';

const ExampleComponent = () => {
const space = useSpaceStyles();

return (
<Tile variant="card" className={mergeClasses(space.py9, space.px7)}>
<Text variant="headline" className={space.mb7} block>
Example Component
</Text>
<Text variant="description" block>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Veniam sapiente voluptas
laudantium placeat aliquam eum nesciunt dolorem rerum, quasi ea quisquam natus
repellendus! Laudantium expedita laborum natus, earum tenetur quidem?
</Text>
</Tile>
);
};

export default ExampleComponent;
`;
113 changes: 113 additions & 0 deletions utilities/parse-code-string/__dev__/parse-code-string.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { makeStyles } from '@griffel/react';
import { CodeSnippet } from '@microsoft/arbutus.code-snippet';
import { Command } from '@microsoft/arbutus.command';
import { TableCell, TableList, TableRow } from '@microsoft/arbutus.table-list';
import { Text } from '@microsoft/arbutus.text';
import { useSpaceStyles } from '@microsoft/arbutus.use-space-styles';
import type { Meta, Story } from '@storybook/react';
import React from 'react';

import { Centered } from '../../../.storybook/decorators';
import { getDefaultExportName, getDependencies } from '../src/index';
import codeStr from './example-component.raw';

const useStyles = makeStyles({
root: {
maxWidth: '860px',
display: 'grid',
gridGap: '16px',
},
code: {
wordWrap: 'break-word',
maxWidth: '100%',
},
});

const codeExample = `import { getDefaultExportName, getDependencies } from '@microsoft/arbutus.parse-code-string';
import codeStr from './example-component.raw';

const dependencies = getDependencies(codeStr);
const defaultExportName = getDefaultExportName(codeStr);
`;

const DemoComponent = () => {
const classes = useStyles();
const space = useSpaceStyles();

const dependencies = getDependencies(codeStr);
const defaultExportName = getDefaultExportName(codeStr);

return (
<div className={classes.root}>
<Text as="h1" block variant="title">
Parse Code String utilities
</Text>
<Text as="h2" block variant="headline">
Usage
</Text>
<Command isCopyable command="npm i @microsoft/arbutus.parse-code-string" />
<CodeSnippet language="typescript" code={codeExample} />
<Text as="h2" block variant="headline">
Example file
</Text>
<CodeSnippet language="javascript" code={codeStr} />

<Text variant="description" block>
If you need to generate a string from a file, you can use the{' '}
<Text variant="code">fileToString()</Text> utility from the{' '}
<Text variant="code">@microsoft/arbutus.file-to-string</Text>
package.
</Text>
<Text as="h2" block variant="headline">
Result
</Text>
<TableList className={space.mb6}>
<TableRow>
<TableCell isHeader>Function</TableCell>
<TableCell isHeader>Output</TableCell>
</TableRow>
<TableRow>
<TableCell isHeader>
<Text
variant="code"
className={classes.code}
>{`getDependencies(codeStr: string)`}</Text>
</TableCell>
<TableCell>
<Text variant="code" className={classes.code}>
{JSON.stringify(dependencies)}
</Text>
</TableCell>
</TableRow>
<TableRow>
<TableCell isHeader>
<Text
variant="code"
className={classes.code}
>{`getDefaultExportName(codeStr: string)`}</Text>
</TableCell>
<TableCell>
<Text variant="code" className={classes.code}>
{JSON.stringify(defaultExportName, null, 2)}
</Text>
</TableCell>
</TableRow>
</TableList>
</div>
);
};

export default {
title: 'Utilities/ParseCodeString',
decorators: [
(Story) => (
<Centered>
<Story />
</Centered>
),
],
} as Meta;

const Template: Story = () => <DemoComponent />;

export const Demo = Template.bind({}) as Story;
23 changes: 23 additions & 0 deletions utilities/parse-code-string/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@microsoft/arbutus.parse-code-string",
"version": "0.0.1",
"description": "Utility functions that receive code as a string and return information about it.",
"main": "lib/index.js",
"module": "lib/index.js",
"typings": "lib/index.d.ts",
"exports": [
"./lib/index.js"
],
"files": [
"lib/**"
],
"sideEffects": false,
"scripts": {
"build": "tsc",
"lint": "eslint . --fix"
},
"devDependencies": {
"@microsoft/arbutus.ts": "0.0.2",
"typescript": "^4.9.4"
}
}
2 changes: 2 additions & 0 deletions utilities/parse-code-string/src/get-default-export-name.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const getDefaultExportName = (codeStr: string) =>
codeStr.match(/export\s+default\s+(\w+)/)?.[1];
6 changes: 6 additions & 0 deletions utilities/parse-code-string/src/get-dependencies.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const getDependencies = (codeStr: string) => {
const regex = /import\s.*\sfrom\s+['"](.*)['"]/g;
const dependencies = [...codeStr.matchAll(regex)].map(([_, result]) => result);

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data

This [regular expression](1) that depends on [library input](2) may run slow on strings starting with 'import ' and with many repetitions of 'import '.

return dependencies;
};
2 changes: 2 additions & 0 deletions utilities/parse-code-string/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { getDefaultExportName } from './get-default-export-name';
export { getDependencies } from './get-dependencies';
10 changes: 10 additions & 0 deletions utilities/parse-code-string/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@microsoft/arbutus.ts",
"include": ["src"],
"compilerOptions": {
"outDir": "lib",
"esModuleInterop": true,
"moduleResolution": "nodenext"
}
}