@codecanva/nest-auth 0.1.0 → 0.2.0
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/INSTALLATION.md +682 -0
- package/README.md +200 -164
- package/dist/auth.module.d.ts.map +1 -1
- package/dist/auth.module.js +6 -0
- package/dist/auth.module.js.map +1 -1
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +270 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/templates.d.ts +21 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +556 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/utils.d.ts +55 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +235 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/filters/auth-exception.filter.d.ts +20 -0
- package/dist/filters/auth-exception.filter.d.ts.map +1 -0
- package/dist/filters/auth-exception.filter.js +40 -0
- package/dist/filters/auth-exception.filter.js.map +1 -0
- package/dist/filters/index.d.ts +2 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/index.js +18 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +112 -107
package/README.md
CHANGED
|
@@ -1,164 +1,200 @@
|
|
|
1
|
-
# @codecanva/nest-auth
|
|
2
|
-
|
|
3
|
-
Reusable NestJS authentication module. JWT access + refresh-token rotation, multi-device sessions, replay detection, and pluggable persistence (no DB lock-in).
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Short-lived access JWT + long-lived refresh JWT
|
|
8
|
-
- Refresh-token rotation on every refresh (with replay detection → `revokeAllForUser`)
|
|
9
|
-
- Multi-device sessions (one row per session, hashed at rest)
|
|
10
|
-
- Pluggable `RefreshTokenStore` and `UserValidator` — bring your own DB
|
|
11
|
-
- `@CurrentUser()`, `@Public()` decorators
|
|
12
|
-
- `JwtAuthGuard` (honours `@Public()`) and `RefreshAuthGuard`
|
|
13
|
-
- Configurable issuer, audience, clock tolerance, optional hash pepper
|
|
14
|
-
|
|
15
|
-
## Install
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install @codecanva/nest-auth \
|
|
19
|
-
@nestjs/jwt @nestjs/passport passport passport-jwt \
|
|
20
|
-
class-validator class-transformer
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
1
|
+
# @codecanva/nest-auth
|
|
2
|
+
|
|
3
|
+
Reusable NestJS authentication module. JWT access + refresh-token rotation, multi-device sessions, replay detection, and pluggable persistence (no DB lock-in).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Short-lived access JWT + long-lived refresh JWT
|
|
8
|
+
- Refresh-token rotation on every refresh (with replay detection → `revokeAllForUser`)
|
|
9
|
+
- Multi-device sessions (one row per session, hashed at rest)
|
|
10
|
+
- Pluggable `RefreshTokenStore` and `UserValidator` — bring your own DB
|
|
11
|
+
- `@CurrentUser()`, `@Public()` decorators
|
|
12
|
+
- `JwtAuthGuard` (honours `@Public()`) and `RefreshAuthGuard`
|
|
13
|
+
- Configurable issuer, audience, clock tolerance, optional hash pepper
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @codecanva/nest-auth \
|
|
19
|
+
@nestjs/jwt @nestjs/passport passport passport-jwt \
|
|
20
|
+
class-validator class-transformer
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick install (CLI)
|
|
24
|
+
|
|
25
|
+
Scaffold everything into an existing NestJS project — user/auth files, env vars,
|
|
26
|
+
AppModule + `main.ts` wiring, and dependencies — in one command:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Mongoose persistence (default): generates user + refresh-token modules
|
|
30
|
+
npx @codecanva/nest-auth init
|
|
31
|
+
|
|
32
|
+
# In-memory store, no DB — great for a quick trial
|
|
33
|
+
npx @codecanva/nest-auth init --store memory
|
|
34
|
+
|
|
35
|
+
# Preview without writing anything
|
|
36
|
+
npx @codecanva/nest-auth init --dry-run
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The installer generates an `AuthIntegrationModule` (a single drop-in module that
|
|
40
|
+
bundles the store, validator, controller, and the global `JwtAuthGuard`), adds it
|
|
41
|
+
to your `AppModule`, and enables a global `ValidationPipe`. Existing files are
|
|
42
|
+
never overwritten without `--force`, and every edited file is backed up to
|
|
43
|
+
`<file>.bak`.
|
|
44
|
+
|
|
45
|
+
| Flag | Effect |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `--store <mongoose\|memory>` | Persistence to scaffold (default `mongoose`) |
|
|
48
|
+
| `--dir <path>` | Target project root (default: current directory) |
|
|
49
|
+
| `--no-wire` | Don't touch `app.module.ts` / `main.ts` |
|
|
50
|
+
| `--skip-install` | Don't install npm dependencies |
|
|
51
|
+
| `--force` | Overwrite files that already exist |
|
|
52
|
+
| `--dry-run` | Show planned changes, write nothing |
|
|
53
|
+
|
|
54
|
+
After running it, set real values for `JWT_ACCESS_SECRET`, `JWT_REFRESH_SECRET`,
|
|
55
|
+
and `TOKEN_HASH_PEPPER` in `.env` (and, for `--store mongoose`, make sure a
|
|
56
|
+
`MongooseModule.forRoot(...)` connection exists at the app root). For a fully
|
|
57
|
+
manual, step-by-step walkthrough see [INSTALLATION.md](./INSTALLATION.md).
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
### 1. Implement the two interfaces against your data layer
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// users/user.validator.ts
|
|
65
|
+
import { Injectable } from '@nestjs/common';
|
|
66
|
+
import { AuthUser, UserValidator } from '@codecanva/nest-auth';
|
|
67
|
+
|
|
68
|
+
@Injectable()
|
|
69
|
+
export class MyUserValidator implements UserValidator {
|
|
70
|
+
async validateCredentials(email: string, password: string): Promise<AuthUser | null> {
|
|
71
|
+
// load user, bcrypt.compare, return { id, email, roles } or null
|
|
72
|
+
}
|
|
73
|
+
async findById(userId: string | number): Promise<AuthUser | null> {
|
|
74
|
+
// load by id, return AuthUser or null
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
// auth/refresh-token.store.ts — example with TypeORM
|
|
81
|
+
import { Injectable } from '@nestjs/common';
|
|
82
|
+
import {
|
|
83
|
+
CreateRefreshTokenInput,
|
|
84
|
+
RefreshTokenStore,
|
|
85
|
+
StoredRefreshToken,
|
|
86
|
+
} from '@codecanva/nest-auth';
|
|
87
|
+
|
|
88
|
+
@Injectable()
|
|
89
|
+
export class MyRefreshTokenStore implements RefreshTokenStore {
|
|
90
|
+
// create / findById / consume / revokeById / revokeAllForUser
|
|
91
|
+
// IMPORTANT: `consume` must be atomic (single UPDATE ... WHERE revoked_at IS NULL
|
|
92
|
+
// AND token_hash = $hash RETURNING *). Non-atomic impls split sessions under load.
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Register the module
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { AuthModule } from '@codecanva/nest-auth';
|
|
100
|
+
|
|
101
|
+
@Module({
|
|
102
|
+
imports: [
|
|
103
|
+
AuthModule.forRootAsync({
|
|
104
|
+
imports: [ConfigModule],
|
|
105
|
+
useFactory: (cfg: ConfigService) => ({
|
|
106
|
+
accessSecret: cfg.getOrThrow('JWT_ACCESS_SECRET'),
|
|
107
|
+
refreshSecret: cfg.getOrThrow('JWT_REFRESH_SECRET'),
|
|
108
|
+
accessTtl: '15m',
|
|
109
|
+
refreshTtl: '30d',
|
|
110
|
+
tokenHashPepper: cfg.get('TOKEN_HASH_PEPPER'),
|
|
111
|
+
issuer: 'my-app',
|
|
112
|
+
}),
|
|
113
|
+
inject: [ConfigService],
|
|
114
|
+
store: { useClass: MyRefreshTokenStore },
|
|
115
|
+
validator: { useClass: MyUserValidator },
|
|
116
|
+
}),
|
|
117
|
+
],
|
|
118
|
+
})
|
|
119
|
+
export class AppModule {}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. Apply the guard globally (optional)
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { APP_GUARD } from '@nestjs/core';
|
|
126
|
+
import { JwtAuthGuard } from '@codecanva/nest-auth';
|
|
127
|
+
|
|
128
|
+
providers: [{ provide: APP_GUARD, useClass: JwtAuthGuard }],
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 4. Use in controllers
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import {
|
|
135
|
+
AuthService, CurrentUser, LoginDto, Public, RefreshTokenDto,
|
|
136
|
+
} from '@codecanva/nest-auth';
|
|
137
|
+
|
|
138
|
+
@Controller('auth')
|
|
139
|
+
export class AuthController {
|
|
140
|
+
constructor(private readonly auth: AuthService) {}
|
|
141
|
+
|
|
142
|
+
@Public() @Post('login')
|
|
143
|
+
login(@Body() dto: LoginDto) { return this.auth.login(dto.email, dto.password); }
|
|
144
|
+
|
|
145
|
+
@Public() @Post('refresh')
|
|
146
|
+
refresh(@Body() dto: RefreshTokenDto) { return this.auth.refresh(dto.refreshToken); }
|
|
147
|
+
|
|
148
|
+
@Post('logout')
|
|
149
|
+
logout(@Body() dto: RefreshTokenDto) { return this.auth.logout(dto.refreshToken); }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@Controller('me')
|
|
153
|
+
export class MeController {
|
|
154
|
+
@Get() me(@CurrentUser() user: AuthUser) { return user; }
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API surface
|
|
159
|
+
|
|
160
|
+
- `AuthModule.forRootAsync(opts)` — only entry point
|
|
161
|
+
- `AuthService` — `login` / `refresh` / `logout` / `logoutAll`
|
|
162
|
+
- Guards — `JwtAuthGuard`, `RefreshAuthGuard`
|
|
163
|
+
- Decorators — `@Public()`, `@CurrentUser()`
|
|
164
|
+
- DTOs — `LoginDto`, `RefreshTokenDto`
|
|
165
|
+
- Errors — `AuthError`, `InvalidCredentialsError`, `InvalidRefreshTokenError`, `RefreshTokenExpiredError`, `RefreshTokenReuseDetectedError`, `UserNotFoundError`
|
|
166
|
+
- Interfaces — `AuthModuleOptions`, `AuthModuleAsyncOptions`, `AuthUser`, `JwtPayload`, `RefreshTokenStore`, `StoredRefreshToken`, `CreateRefreshTokenInput`, `SessionMetadata`, `UserValidator`
|
|
167
|
+
|
|
168
|
+
## Local development / publishing
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm install # install deps
|
|
172
|
+
npm run start:dev # run the demo app at :3000 (uses in-memory store + validator)
|
|
173
|
+
npm run build:lib # compile lib → dist/
|
|
174
|
+
npm publish # publish (runs build:lib via prepublishOnly)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
To consume from a sibling project before publishing:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# in this repo
|
|
181
|
+
npm run build:lib && npm pack
|
|
182
|
+
# in the consumer
|
|
183
|
+
npm install /path/to/codecanva-nest-auth-0.1.0.tgz
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Demo endpoints (when running `start:dev`)
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
POST /auth/login { "email": "demo@example.com", "password": "password123" }
|
|
190
|
+
POST /auth/refresh { "refreshToken": "..." }
|
|
191
|
+
POST /auth/logout { "refreshToken": "..." } # 204
|
|
192
|
+
GET /me # bearer access token required
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Security notes
|
|
196
|
+
|
|
197
|
+
- Refresh tokens are JWTs; the **hash** of the JWT (sha256 + optional pepper) is stored, never the raw token.
|
|
198
|
+
- `consume` must be atomic — non-atomic impls split sessions under concurrent refresh.
|
|
199
|
+
- On replay (token hash mismatch or already-revoked row), every active session for that user is revoked.
|
|
200
|
+
- Always serve auth over HTTPS. Store the refresh token in an httpOnly cookie when possible.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../src/lib/auth.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../src/lib/auth.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AAWjE,OAAO,KAAK,EACV,sBAAsB,EAGvB,MAAM,4CAA4C,CAAC;AAKpD,qBACa,UAAU;IACrB,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,sBAAsB,GAAG,aAAa;CAwCpE"}
|
package/dist/auth.module.js
CHANGED
|
@@ -9,10 +9,12 @@ var AuthModule_1;
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.AuthModule = void 0;
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@nestjs/core");
|
|
12
13
|
const jwt_1 = require("@nestjs/jwt");
|
|
13
14
|
const passport_1 = require("@nestjs/passport");
|
|
14
15
|
const auth_constants_1 = require("./auth.constants");
|
|
15
16
|
const auth_service_1 = require("./auth.service");
|
|
17
|
+
const auth_exception_filter_1 = require("./filters/auth-exception.filter");
|
|
16
18
|
const token_service_1 = require("./services/token.service");
|
|
17
19
|
const jwt_strategy_1 = require("./strategies/jwt.strategy");
|
|
18
20
|
const refresh_strategy_1 = require("./strategies/refresh.strategy");
|
|
@@ -40,6 +42,10 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
40
42
|
jwt_strategy_1.JwtStrategy,
|
|
41
43
|
refresh_strategy_1.RefreshStrategy,
|
|
42
44
|
auth_service_1.AuthService,
|
|
45
|
+
// Globally maps AuthError domain errors → HTTP responses (e.g.
|
|
46
|
+
// InvalidCredentialsError → 401), so consumers don't need per-route
|
|
47
|
+
// try/catch to get correct status codes on auth failure.
|
|
48
|
+
{ provide: core_1.APP_FILTER, useClass: auth_exception_filter_1.AuthExceptionFilter },
|
|
43
49
|
],
|
|
44
50
|
exports: [
|
|
45
51
|
auth_service_1.AuthService,
|
package/dist/auth.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../src/lib/auth.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAiE;AACjE,qCAAwC;AACxC,+CAAkD;AAClD,qDAI0B;AAC1B,iDAA6C;
|
|
1
|
+
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../src/lib/auth.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAiE;AACjE,uCAA0C;AAC1C,qCAAwC;AACxC,+CAAkD;AAClD,qDAI0B;AAC1B,iDAA6C;AAC7C,2EAAsE;AAMtE,4DAAwD;AACxD,4DAAwD;AACxD,oEAAgE;AAGzD,IAAM,UAAU,kBAAhB,MAAM,UAAU;IACrB,MAAM,CAAC,YAAY,CAAC,OAA+B;QACjD,MAAM,eAAe,GAAa;YAChC,OAAO,EAAE,oCAAmB;YAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,MAAM,aAAa,GAAG,aAAa,CAAC,oCAAmB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACxE,MAAM,iBAAiB,GAAG,aAAa,CAAC,+BAAc,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3E,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,OAAO,EAAE;gBACP,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAC1B,yBAAc;gBACd,eAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;aACvB;YACD,SAAS,EAAE;gBACT,eAAe;gBACf,aAAa;gBACb,iBAAiB;gBACjB,4BAAY;gBACZ,0BAAW;gBACX,kCAAe;gBACf,0BAAW;gBACX,+DAA+D;gBAC/D,oEAAoE;gBACpE,yDAAyD;gBACzD,EAAE,OAAO,EAAE,iBAAU,EAAE,QAAQ,EAAE,2CAAmB,EAAE;aACvD;YACD,OAAO,EAAE;gBACP,0BAAW;gBACX,oCAAmB;gBACnB,oCAAmB;gBACnB,+BAAc;gBACd,eAAS;gBACT,yBAAc;aACf;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAzCY,gCAAU;qBAAV,UAAU;IADtB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,UAAU,CAyCtB;AAED,SAAS,aAAa,CACpB,KAAa,EACb,GAAsD;IAEtD,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;IAC1D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,KAAK,CACb,4BAA4B,KAAK,CAAC,QAAQ,EAAE,gDAAgD,CAC7F,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/cli/index.ts"],"names":[],"mappings":""}
|