mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16:15 -08:00
feat(playlist-import): add clear actions to import forms
Entire-Checkpoint: 6719280e397b
This commit is contained in:
1 parent
472ac66185
commit
42bbbe71d8
16 files changed
+434
-94
No files matched your search
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
displayName: 'playlist-import-feature',
|
||||
preset: '../../../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
coverageDirectory: '../../../../coverage/libs/playlist/import/feature',
|
||||
transform: {
|
||||
'^.+\\.(ts|mjs|js|html)$': [
|
||||
'jest-preset-angular',
|
||||
{
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
},
|
||||
],
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
@@ -6,6 +6,14 @@
|
||||
"projectType": "library",
|
||||
"tags": ["scope:playlist", "domain:playlist-import", "type:feature"],
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/playlist/import/feature/jest.config.ts",
|
||||
"tsConfig": "libs/playlist/import/feature/tsconfig.spec.json"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
|
||||
+103
-68
@@ -4,7 +4,11 @@
|
||||
</h2>
|
||||
|
||||
<mat-dialog-content>
|
||||
<div class="apd-segmented" role="tablist" aria-label="Playlist category">
|
||||
<div
|
||||
class="apd-segmented"
|
||||
role="tablist"
|
||||
aria-label="Playlist category"
|
||||
>
|
||||
@for (opt of categoryOptions; track opt.value) {
|
||||
<button
|
||||
type="button"
|
||||
@@ -65,81 +69,112 @@
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button type="button" (click)="closeDialog()">
|
||||
{{ 'CANCEL' | translate }}
|
||||
</button>
|
||||
<mat-dialog-actions class="apd-actions">
|
||||
<div class="apd-actions__reset">
|
||||
<button
|
||||
mat-button
|
||||
type="button"
|
||||
[disabled]="isClearDisabled()"
|
||||
(click)="clearCurrentForm()"
|
||||
>
|
||||
{{ 'CLEAR' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@switch (playlistType()) {
|
||||
@case ('url') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!urlUpload()?.form?.valid"
|
||||
(click)="submitUrlPlaylist()"
|
||||
>
|
||||
{{ 'HOME.URL_UPLOAD.ADD_PLAYLIST' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('file') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!fileUpload()?.selectedFile()"
|
||||
(click)="fileUpload()?.confirm()"
|
||||
>
|
||||
{{ 'HOME.URL_UPLOAD.ADD_PLAYLIST' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('text') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!textImport()?.textForm?.valid"
|
||||
(click)="textImport()?.textAdded?.emit(textImport()?.textForm?.value?.text)"
|
||||
>
|
||||
{{ 'HOME.TEXT_IMPORT.BUTTON_LABEL' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('xtream') {
|
||||
<button
|
||||
mat-stroked-button
|
||||
type="button"
|
||||
[disabled]="!xtreamImport()?.form?.valid || xtreamImport()?.isTestingConnection"
|
||||
(click)="xtreamImport()?.testConnection()"
|
||||
>
|
||||
{{ xtreamImport()?.isTestingConnection ? 'Testing...' : 'Test Connection' }}
|
||||
</button>
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!xtreamImport()?.form?.valid"
|
||||
(click)="xtreamImport()?.addPlaylist()"
|
||||
>
|
||||
{{ 'HOME.XTREAM_PLAYLIST.ADD' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('stalker') {
|
||||
@if (stalkerImport()?.isLoading()) {
|
||||
<button mat-flat-button color="accent" type="button" disabled>
|
||||
{{ 'HOME.STALKER_PORTAL.VALIDATING' | translate }}...
|
||||
</button>
|
||||
} @else {
|
||||
<div class="apd-actions__decision">
|
||||
<button mat-button type="button" (click)="closeDialog()">
|
||||
{{ 'CANCEL' | translate }}
|
||||
</button>
|
||||
|
||||
@switch (playlistType()) {
|
||||
@case ('url') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!stalkerImport()?.form?.valid"
|
||||
(click)="stalkerImport()?.addPlaylist()"
|
||||
[disabled]="!urlUpload()?.form?.valid"
|
||||
(click)="submitUrlPlaylist()"
|
||||
>
|
||||
{{ 'HOME.STALKER_PORTAL.ADD' | translate }}
|
||||
{{ 'HOME.URL_UPLOAD.ADD_PLAYLIST' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('file') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!fileUpload()?.selectedFile()"
|
||||
(click)="fileUpload()?.confirm()"
|
||||
>
|
||||
{{ 'HOME.URL_UPLOAD.ADD_PLAYLIST' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('text') {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!textImport()?.textForm?.valid"
|
||||
(click)="
|
||||
textImport()?.textAdded?.emit(
|
||||
textImport()?.textForm?.value?.text
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ 'HOME.TEXT_IMPORT.BUTTON_LABEL' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('xtream') {
|
||||
<button
|
||||
mat-stroked-button
|
||||
type="button"
|
||||
[disabled]="
|
||||
!xtreamImport()?.form?.valid ||
|
||||
xtreamImport()?.isTestingConnection
|
||||
"
|
||||
(click)="xtreamImport()?.testConnection()"
|
||||
>
|
||||
{{
|
||||
xtreamImport()?.isTestingConnection
|
||||
? 'Testing...'
|
||||
: 'Test Connection'
|
||||
}}
|
||||
</button>
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!xtreamImport()?.form?.valid"
|
||||
(click)="xtreamImport()?.addPlaylist()"
|
||||
>
|
||||
{{ 'HOME.XTREAM_PLAYLIST.ADD' | translate }}
|
||||
</button>
|
||||
}
|
||||
@case ('stalker') {
|
||||
@if (stalkerImport()?.isLoading()) {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
disabled
|
||||
>
|
||||
{{
|
||||
'HOME.STALKER_PORTAL.VALIDATING' | translate
|
||||
}}...
|
||||
</button>
|
||||
} @else {
|
||||
<button
|
||||
mat-flat-button
|
||||
color="accent"
|
||||
type="button"
|
||||
[disabled]="!stalkerImport()?.form?.valid"
|
||||
(click)="stalkerImport()?.addPlaylist()"
|
||||
>
|
||||
{{ 'HOME.STALKER_PORTAL.ADD' | translate }}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
||||
+57
-4
@@ -5,7 +5,11 @@
|
||||
--apd-muted: var(--app-muted-color);
|
||||
--apd-surface-raised: var(--app-widget-header-bg);
|
||||
--apd-accent: var(--app-selection-color);
|
||||
--apd-segment-track: color-mix(in srgb, var(--app-shell-bg) 70%, transparent);
|
||||
--apd-segment-track: color-mix(
|
||||
in srgb,
|
||||
var(--app-shell-bg) 70%,
|
||||
transparent
|
||||
);
|
||||
--apd-segment-active: color-mix(
|
||||
in srgb,
|
||||
var(--app-widget-header-bg) 70%,
|
||||
@@ -25,7 +29,11 @@
|
||||
margin-bottom: 14px;
|
||||
|
||||
&--sub {
|
||||
background: color-mix(in srgb, var(--apd-segment-track) 85%, transparent);
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--apd-segment-track) 85%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,17 +105,62 @@
|
||||
margin: 6px 0 0;
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
background: color-mix(in srgb, var(--apd-surface-raised) 50%, transparent);
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--apd-surface-raised) 50%,
|
||||
transparent
|
||||
);
|
||||
color: var(--apd-muted);
|
||||
font-size: 11.5px;
|
||||
line-height: 1.45;
|
||||
}
|
||||
}
|
||||
|
||||
.apd-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 8px 12px;
|
||||
|
||||
&__reset,
|
||||
&__decision {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&__decision {
|
||||
justify-content: flex-end;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.apd-actions {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
|
||||
&__reset,
|
||||
&__decision {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__decision {
|
||||
justify-content: flex-end;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Light-theme segmented control tweak ────────────────────────────────────
|
||||
// `.dark-theme` is on <body>, so target light mode via `body:not(...)`.
|
||||
body:not(.dark-theme) .apd {
|
||||
--apd-segment-track: color-mix(in srgb, var(--app-content-bg) 70%, transparent);
|
||||
--apd-segment-track: color-mix(
|
||||
in srgb,
|
||||
var(--app-content-bg) 70%,
|
||||
transparent
|
||||
);
|
||||
--apd-segment-active: #ffffff;
|
||||
|
||||
.apd-segment.active {
|
||||
|
||||
+78
-15
@@ -6,6 +6,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { PlaylistActions } from 'm3u-state';
|
||||
import { DataService } from 'services';
|
||||
import { PLAYLIST_PARSE_BY_URL } from 'shared-interfaces';
|
||||
import { PlaylistType } from '@iptvnator/playlist/shared/ui';
|
||||
import { AddPlaylistDialogComponent } from './add-playlist-dialog.component';
|
||||
|
||||
describe('AddPlaylistDialogComponent', () => {
|
||||
@@ -106,27 +107,89 @@ describe('AddPlaylistDialogComponent', () => {
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('strips playlist extensions from uploaded file titles', () => {
|
||||
component.handlePlaylist({
|
||||
uploadEvent: {
|
||||
target: {
|
||||
result: '#EXTM3U',
|
||||
},
|
||||
} as unknown as Event,
|
||||
file: {
|
||||
name: 'Local Source.m3u',
|
||||
path: '/tmp/Local Source.m3u',
|
||||
} as File,
|
||||
});
|
||||
it('dispatches imported text and closes the dialog', () => {
|
||||
component.uploadAsText('#EXTM3U');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
PlaylistActions.parsePlaylist({
|
||||
uploadType: 'FILE',
|
||||
uploadType: 'TEXT',
|
||||
playlist: '#EXTM3U',
|
||||
title: 'Local Source',
|
||||
path: '/tmp/Local Source.m3u',
|
||||
title: 'HOME.IMPORTED_AS_TEXT',
|
||||
})
|
||||
);
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('closes the dialog after a successful file import', () => {
|
||||
component.onFileImported();
|
||||
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
type: 'url',
|
||||
childAccessor: 'urlUpload',
|
||||
clearMethod: 'clearForm',
|
||||
},
|
||||
{
|
||||
type: 'file',
|
||||
childAccessor: 'fileUpload',
|
||||
clearMethod: 'clearSelection',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
childAccessor: 'textImport',
|
||||
clearMethod: 'clearForm',
|
||||
},
|
||||
{
|
||||
type: 'xtream',
|
||||
childAccessor: 'xtreamImport',
|
||||
clearMethod: 'clearForm',
|
||||
},
|
||||
{
|
||||
type: 'stalker',
|
||||
childAccessor: 'stalkerImport',
|
||||
clearMethod: 'clearForm',
|
||||
},
|
||||
] as const)(
|
||||
'clears the current $type import surface',
|
||||
({ type, childAccessor, clearMethod }) => {
|
||||
const clear = jest.fn();
|
||||
(component as unknown as Record<string, jest.Mock>)[childAccessor] =
|
||||
jest.fn(() => ({
|
||||
[clearMethod]: clear,
|
||||
}));
|
||||
selectType(type);
|
||||
|
||||
component.clearCurrentForm();
|
||||
|
||||
expect(clear).toHaveBeenCalledTimes(1);
|
||||
}
|
||||
);
|
||||
|
||||
it('disables clear when a file upload has no selection', () => {
|
||||
(component as { fileUpload: jest.Mock }).fileUpload = jest.fn(() => ({
|
||||
isImporting: () => false,
|
||||
selectedFile: () => null,
|
||||
}));
|
||||
selectType('file');
|
||||
|
||||
expect(component.isClearDisabled()).toBeTruthy();
|
||||
});
|
||||
|
||||
function selectType(type: PlaylistType): void {
|
||||
if (type === 'xtream') {
|
||||
component.category.set('xtream');
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'stalker') {
|
||||
component.category.set('stalker');
|
||||
return;
|
||||
}
|
||||
|
||||
component.category.set('m3u');
|
||||
component.m3uSubType.set(type);
|
||||
}
|
||||
});
|
||||
+42
-5
@@ -16,10 +16,6 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { PlaylistType } from '@iptvnator/playlist/shared/ui';
|
||||
import {
|
||||
M3uSubType,
|
||||
PlaylistCategory,
|
||||
} from '@iptvnator/workspace/shell/util';
|
||||
import { PlaylistActions } from 'm3u-state';
|
||||
import { DataService } from 'services';
|
||||
import { PLAYLIST_PARSE_BY_URL } from 'shared-interfaces';
|
||||
@@ -29,6 +25,9 @@ import { TextImportComponent } from '../text-import/text-import.component';
|
||||
import { UrlUploadComponent } from '../url-upload/url-upload.component';
|
||||
import { XtreamCodeImportComponent } from '../xtream-code-import/xtream-code-import.component';
|
||||
|
||||
type PlaylistCategory = 'm3u' | Extract<PlaylistType, 'xtream' | 'stalker'>;
|
||||
type M3uSubType = Extract<PlaylistType, 'url' | 'file' | 'text'>;
|
||||
|
||||
interface CategoryOption {
|
||||
value: PlaylistCategory;
|
||||
label: string;
|
||||
@@ -139,7 +138,9 @@ export class AddPlaylistDialogComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
const playlistName = this.normalizeOptionalValue(formValue?.playlistName);
|
||||
const playlistName = this.normalizeOptionalValue(
|
||||
formValue?.playlistName
|
||||
);
|
||||
|
||||
this.dataService.sendIpcEvent(PLAYLIST_PARSE_BY_URL, {
|
||||
url: playlistUrl,
|
||||
@@ -163,6 +164,42 @@ export class AddPlaylistDialogComponent {
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
clearCurrentForm(): void {
|
||||
switch (this.playlistType()) {
|
||||
case 'url':
|
||||
this.urlUpload()?.clearForm();
|
||||
break;
|
||||
case 'file':
|
||||
this.fileUpload()?.clearSelection();
|
||||
break;
|
||||
case 'text':
|
||||
this.textImport()?.clearForm();
|
||||
break;
|
||||
case 'xtream':
|
||||
this.xtreamImport()?.clearForm();
|
||||
break;
|
||||
case 'stalker':
|
||||
this.stalkerImport()?.clearForm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isClearDisabled(): boolean {
|
||||
switch (this.playlistType()) {
|
||||
case 'file':
|
||||
return (
|
||||
!this.fileUpload()?.selectedFile() ||
|
||||
!!this.fileUpload()?.isImporting()
|
||||
);
|
||||
case 'xtream':
|
||||
return !!this.xtreamImport()?.isTestingConnection;
|
||||
case 'stalker':
|
||||
return !!this.stalkerImport()?.isLoading();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
closeDialog(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
+18
@@ -79,6 +79,24 @@ export class StalkerPortalImportComponent {
|
||||
|
||||
readonly isLoading = signal(false);
|
||||
|
||||
clearForm(): void {
|
||||
this.form.reset({
|
||||
_id: uuid(),
|
||||
title: '',
|
||||
macAddress: '',
|
||||
serialNumber: '',
|
||||
deviceId1: '',
|
||||
deviceId2: '',
|
||||
signature1: '',
|
||||
signature2: '',
|
||||
password: '',
|
||||
username: '',
|
||||
portalUrl: '',
|
||||
importDate: new Date().toISOString(),
|
||||
userAgent: '',
|
||||
});
|
||||
}
|
||||
|
||||
async addPlaylist() {
|
||||
if (!this.form.valid || this.isLoading()) {
|
||||
return;
|
||||
|
||||
@@ -31,4 +31,18 @@ describe('TextImportComponent', () => {
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('clears the text import form', () => {
|
||||
component.textForm.setValue({
|
||||
text: '#EXTM3U',
|
||||
});
|
||||
component.textForm.markAsDirty();
|
||||
|
||||
component.clearForm();
|
||||
|
||||
expect(component.textForm.value).toEqual({
|
||||
text: '',
|
||||
});
|
||||
expect(component.textForm.pristine).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -20,4 +20,10 @@ export class TextImportComponent {
|
||||
textForm = new FormGroup({
|
||||
text: new FormControl('', Validators.required),
|
||||
});
|
||||
|
||||
clearForm(): void {
|
||||
this.textForm.reset({
|
||||
text: '',
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -57,4 +57,20 @@ describe('UrlUploadComponent', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.form.valid).toBeTruthy();
|
||||
});
|
||||
|
||||
it('clears the url playlist form', () => {
|
||||
component.form.setValue({
|
||||
playlistName: 'News',
|
||||
playlistUrl: 'http://example.org/playlist.m3u',
|
||||
});
|
||||
component.form.markAsDirty();
|
||||
|
||||
component.clearForm();
|
||||
|
||||
expect(component.form.getRawValue()).toEqual({
|
||||
playlistName: '',
|
||||
playlistUrl: '',
|
||||
});
|
||||
expect(component.form.pristine).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -39,4 +39,11 @@ export class UrlUploadComponent implements OnInit {
|
||||
playlistName: [''],
|
||||
});
|
||||
}
|
||||
|
||||
clearForm(): void {
|
||||
this.form.reset({
|
||||
playlistName: '',
|
||||
playlistUrl: '',
|
||||
});
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -61,7 +61,6 @@ import { v4 as uuid } from 'uuid';
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
`,
|
||||
],
|
||||
})
|
||||
@@ -121,7 +120,7 @@ export class XtreamCodeImportComponent {
|
||||
return this.portalStatusService.getStatusIcon(this.connectionStatus);
|
||||
}
|
||||
|
||||
clearForm() {
|
||||
clearForm(): void {
|
||||
this.form.reset({
|
||||
_id: uuid(),
|
||||
title: '',
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
|
||||
|
||||
setupZoneTestEnv({
|
||||
errorOnUnknownElements: true,
|
||||
errorOnUnknownProperties: true,
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"isolatedModules": true,
|
||||
"target": "es2022",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"],
|
||||
"moduleResolution": "node10"
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": [
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user