https://github.com/flex-development/decorator-regex
Decorator regex
https://github.com/flex-development/decorator-regex
decorators regex typescript
Last synced: 4 months ago
JSON representation
Decorator regex
- Host: GitHub
- URL: https://github.com/flex-development/decorator-regex
- Owner: flex-development
- License: bsd-3-clause
- Created: 2023-02-14T01:18:07.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-15T03:29:43.000Z (over 1 year ago)
- Last Synced: 2025-02-09T11:48:07.389Z (5 months ago)
- Topics: decorators, regex, typescript
- Language: JavaScript
- Homepage: https://github.com/flex-development/decorator-regex
- Size: 1.84 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/funding.yml
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# decorator-regex
[](https://github.com/flex-development/decorator-regex/releases/latest)
[](https://npmjs.com/package/@flex-development/decorator-regex)
[](https://codecov.io/github/flex-development/decorator-regex)
[](https://github.com/voxpelli/badges-cjs-esm)
[](LICENSE.md)
[](https://conventionalcommits.org/)
[](https://typescriptlang.org/)
[](https://vitest.dev/)
[](https://yarnpkg.com/)[Decorator][1] regex
## Contents
- [What is this?](#what-is-this)
- [When should I use this?](#when-should-i-use-this)
- [Install](#install)
- [Use](#use)
- [API](#api)
- [`DECORATOR_REGEX`](#decorator-regex)
- [Types](#types)
- [Related](#related)
- [Contribute](#contribute)## What is this?
This package exports a regular expression for matching [decorators][1]. Decorators are functions called on classes,
class accessors, class fields, class methods, and/or class method parameters.## When should I use this?
The regular expression exported from this package can be used to match multi and single-line decorators in JavaScript
and TypeScript source code.Note:
- Decorators in comments (`/** */`, `/* */`, `//`) are ignored
- Regular expression is ECMAScript-compatible. It has **not** been tested with other flavors (PCRE, PCRE2, etc)## Install
This package is [ESM only][2].
```sh
yarn add @flex-development/decorator-regex
```From Git:
```sh
yarn add @flex-development/decorator-regex@flex-development/decorator-regex
```
See Git - Protocols | Yarn
for details on requesting a specific branch, commit, or tag.
## Use
Suppose we have the following module:
```typescript
import { DECORATOR_REGEX } from '@flex-development/decorator-regex'
import { omit } from '@flex-development/tutils'
import { dedent } from 'ts-dedent'const code: string = dedent`
/**
* [Data access object][1] for the {@linkcode DatabaseTable.USERS} table.
*
* [1]: https://en.wikipedia.org/wiki/Data_access_object
*
* @extends {Entity}
* @implements {IUser}
*/
@Table({
defaultScope: {
attributes: ['created_at', 'email', 'id', 'provider'],
order: [['id', OrderDirection.ASC]],
raw: false
},
deletedAt: false,
hooks: {
/**
* Normalizes data before a user is persisted to the database.
*
* This includes:
*
* - Trimming and lowercasing string fields
*
* @param {User} instance - Current user instance
* @return {void} Nothing when complete
*/
beforeSave(instance: User): void {
trimmedLowercasedFields(instance.dataValues)
}
},
omitNull: false,
paranoid: false,
tableName: DatabaseTable.USERS,
timestamps: true
})
class User
extends Entity implements IUser {
@ApiProperty({ description: 'When user was created', type: Number })
@Column({
allowNull: false,
defaultValue: User.CURRENT_TIMESTAMP,
type: DataType.BIGINT,
validate: { isUnixTimestamp: User.isUnixTimestamp }
})
declare created_at: IUser['created_at']@ApiProperty({
description: 'Email address',
maxLength: 254,
minLength: 3,
type: String
})
@Column({
allowNull: false,
type: DataType.STRING(254),
unique: true,
validate: { isEmail: true, len: [3, 254] }
})
declare email: IUser['email']@ApiProperty({ description: 'Unique identifier', type: Number })
@Column({
allowNull: false,
autoIncrementIdentity: true,
defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),
primaryKey: true,
type: 'NUMERIC',
unique: true,
validate: { notNull: true }
})
declare id: IUser['id']@ApiProperty({
description: 'Authentication provider',
enum: OAuthProvider,
enumName: 'OAuthProvider',
nullable: true
})
@Column({
allowNull: true,
defaultValue: null,
type: DataType.ENUM(...User.AUTH_PROVIDERS)
})
declare provider: IUser['provider']@HasMany(() => Token)
declare tokens: Token[]
}
`const print = (matches: IterableIterator): void => {
console.debug([...matches].map(match => omit(match, ['input'])))
}print(code.matchAll(DECORATOR_REGEX))
```...running that yields:
```sh
[
{
'0': '@Table({\n' +
' defaultScope: {\n' +
" attributes: ['created_at', 'email', 'id', 'provider'],\n" +
" order: [['id', OrderDirection.ASC]],\n" +
' raw: false\n' +
' },\n' +
' deletedAt: false,\n' +
' hooks: {\n' +
' /**\n' +
' * Normalizes data before a user is persisted to the database.\n' +
' *\n' +
' * This includes:\n' +
' *\n' +
' * - Trimming and lowercasing string fields\n' +
' *\n' +
' * @param {User} instance - Current user instance\n' +
' * @return {void} Nothing when complete\n' +
' */\n' +
' beforeSave(instance: User): void {\n' +
' trimmedLowercasedFields(instance.dataValues)\n' +
' }\n' +
' },\n' +
' omitNull: false,\n' +
' paranoid: false,\n' +
' tableName: DatabaseTable.USERS,\n' +
' timestamps: true\n' +
' })',
'1': 'Table',
'2': '({\n' +
' defaultScope: {\n' +
" attributes: ['created_at', 'email', 'id', 'provider'],\n" +
" order: [['id', OrderDirection.ASC]],\n" +
' raw: false\n' +
' },\n' +
' deletedAt: false,\n' +
' hooks: {\n' +
' /**\n' +
' * Normalizes data before a user is persisted to the database.\n' +
' *\n' +
' * This includes:\n' +
' *\n' +
' * - Trimming and lowercasing string fields\n' +
' *\n' +
' * @param {User} instance - Current user instance\n' +
' * @return {void} Nothing when complete\n' +
' */\n' +
' beforeSave(instance: User): void {\n' +
' trimmedLowercasedFields(instance.dataValues)\n' +
' }\n' +
' },\n' +
' omitNull: false,\n' +
' paranoid: false,\n' +
' tableName: DatabaseTable.USERS,\n' +
' timestamps: true\n' +
' })',
index: 227,
groups: [Object: null prototype] {
identifier: 'Table',
parameters: '({\n' +
' defaultScope: {\n' +
" attributes: ['created_at', 'email', 'id', 'provider'],\n" +
" order: [['id', OrderDirection.ASC]],\n" +
' raw: false\n' +
' },\n' +
' deletedAt: false,\n' +
' hooks: {\n' +
' /**\n' +
' * Normalizes data before a user is persisted to the database.\n' +
' *\n' +
' * This includes:\n' +
' *\n' +
' * - Trimming and lowercasing string fields\n' +
' *\n' +
' * @param {User} instance - Current user instance\n' +
' * @return {void} Nothing when complete\n' +
' */\n' +
' beforeSave(instance: User): void {\n' +
' trimmedLowercasedFields(instance.dataValues)\n' +
' }\n' +
' },\n' +
' omitNull: false,\n' +
' paranoid: false,\n' +
' tableName: DatabaseTable.USERS,\n' +
' timestamps: true\n' +
' })'
}
},
{
'0': "@ApiProperty({ description: 'When user was created', type: Number })",
'1': 'ApiProperty',
'2': "({ description: 'When user was created', type: Number })",
index: 994,
groups: [Object: null prototype] {
identifier: 'ApiProperty',
parameters: "({ description: 'When user was created', type: Number })"
}
},
{
'0': '@Column({\n' +
' allowNull: false,\n' +
' defaultValue: User.CURRENT_TIMESTAMP,\n' +
' type: DataType.BIGINT,\n' +
' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
' })',
'1': 'Column',
'2': '({\n' +
' allowNull: false,\n' +
' defaultValue: User.CURRENT_TIMESTAMP,\n' +
' type: DataType.BIGINT,\n' +
' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
' })',
index: 1068,
groups: [Object: null prototype] {
identifier: 'Column',
parameters: '({\n' +
' allowNull: false,\n' +
' defaultValue: User.CURRENT_TIMESTAMP,\n' +
' type: DataType.BIGINT,\n' +
' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
' })'
}
},
{
'0': '@ApiProperty({\n' +
" description: 'Email address',\n" +
' maxLength: 254,\n' +
' minLength: 3,\n' +
' type: String\n' +
' })',
'1': 'ApiProperty',
'2': '({\n' +
" description: 'Email address',\n" +
' maxLength: 254,\n' +
' minLength: 3,\n' +
' type: String\n' +
' })',
index: 1296,
groups: [Object: null prototype] {
identifier: 'ApiProperty',
parameters: '({\n' +
" description: 'Email address',\n" +
' maxLength: 254,\n' +
' minLength: 3,\n' +
' type: String\n' +
' })'
}
},
{
'0': '@Column({\n' +
' allowNull: false,\n' +
' type: DataType.STRING(254),\n' +
' unique: true,\n' +
' validate: { isEmail: true, len: [3, 254] }\n' +
' })',
'1': 'Column',
'2': '({\n' +
' allowNull: false,\n' +
' type: DataType.STRING(254),\n' +
' unique: true,\n' +
' validate: { isEmail: true, len: [3, 254] }\n' +
' })',
index: 1425,
groups: [Object: null prototype] {
identifier: 'Column',
parameters: '({\n' +
' allowNull: false,\n' +
' type: DataType.STRING(254),\n' +
' unique: true,\n' +
' validate: { isEmail: true, len: [3, 254] }\n' +
' })'
}
},
{
'0': "@ApiProperty({ description: 'Unique identifier', type: Number })",
'1': 'ApiProperty',
'2': "({ description: 'Unique identifier', type: Number })",
index: 1615,
groups: [Object: null prototype] {
identifier: 'ApiProperty',
parameters: "({ description: 'Unique identifier', type: Number })"
}
},
{
'0': '@Column({\n' +
' allowNull: false,\n' +
' autoIncrementIdentity: true,\n' +
" defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
' primaryKey: true,\n' +
" type: 'NUMERIC',\n" +
' unique: true,\n' +
' validate: { notNull: true }\n' +
' })',
'1': 'Column',
'2': '({\n' +
' allowNull: false,\n' +
' autoIncrementIdentity: true,\n' +
" defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
' primaryKey: true,\n' +
" type: 'NUMERIC',\n" +
' unique: true,\n' +
' validate: { notNull: true }\n' +
' })',
index: 1685,
groups: [Object: null prototype] {
identifier: 'Column',
parameters: '({\n' +
' allowNull: false,\n' +
' autoIncrementIdentity: true,\n' +
" defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
' primaryKey: true,\n' +
" type: 'NUMERIC',\n" +
' unique: true,\n' +
' validate: { notNull: true }\n' +
' })'
}
},
{
'0': '@ApiProperty({\n' +
" description: 'Authentication provider',\n" +
' enum: OAuthProvider,\n' +
" enumName: 'OAuthProvider',\n" +
' nullable: true\n' +
' })',
'1': 'ApiProperty',
'2': '({\n' +
" description: 'Authentication provider',\n" +
' enum: OAuthProvider,\n' +
" enumName: 'OAuthProvider',\n" +
' nullable: true\n' +
' })',
index: 1974,
groups: [Object: null prototype] {
identifier: 'ApiProperty',
parameters: '({\n' +
" description: 'Authentication provider',\n" +
' enum: OAuthProvider,\n' +
" enumName: 'OAuthProvider',\n" +
' nullable: true\n' +
' })'
}
},
{
'0': '@Column({\n' +
' allowNull: true,\n' +
' defaultValue: null,\n' +
' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
' })',
'1': 'Column',
'2': '({\n' +
' allowNull: true,\n' +
' defaultValue: null,\n' +
' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
' })',
index: 2133,
groups: [Object: null prototype] {
identifier: 'Column',
parameters: '({\n' +
' allowNull: true,\n' +
' defaultValue: null,\n' +
' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
' })'
}
},
{
'0': '@HasMany(() => Token)',
'1': 'HasMany',
'2': '(() => Token)',
index: 2300,
groups: [Object: null prototype] {
identifier: 'HasMany',
parameters: '(() => Token)'
}
}
]
```## API
This package exports the identifier [`DECORATOR_REGEX`](#decorator-regex).
There is no default export.
### `DECORATOR_REGEX`
Regular expression matching multi and single-line decorators.
Ignores matches in comments.
Required [flags][3]:
- `s`: dot all
- `u`: unicode> **Source**: [`src/decorator-regex.ts`](src/decorator-regex.ts)
## Types
This package is fully typed with [TypeScript][4].
## Related
- [`decorator-regex`][5] — `export` statement regex
- [`import-regex`][6] — `import` statement regex## Contribute
See [`CONTRIBUTING.md`](CONTRIBUTING.md).
[1]: https://github.com/tc39/proposal-decorators
[2]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[3]: https://codeguage.com/courses/regexp/flags
[4]: https://www.typescriptlang.org
[5]: https://github.com/flex-development/decorator-regex
[6]: https://github.com/flex-development/import-regex