@tehw0lf/wordlist-generator 0.0.2 → 0.0.6
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/LICENSE +2 -2
- package/README.md +57 -4
- package/esm2020/lib/wordlist-generator.component.mjs +8 -5
- package/fesm2015/tehw0lf-wordlist-generator.mjs +7 -4
- package/fesm2015/tehw0lf-wordlist-generator.mjs.map +1 -1
- package/fesm2020/tehw0lf-wordlist-generator.mjs +7 -4
- package/fesm2020/tehw0lf-wordlist-generator.mjs.map +1 -1
- package/lib/wordlist-generator.component.d.ts +3 -2
- package/package.json +8 -3
- package/schematics/collection.json +16 -0
- package/schematics/ng-add/index.d.ts +3 -0
- package/schematics/ng-add/index.js +35 -0
- package/schematics/ng-add/index.js.map +1 -0
- package/schematics/ng-add/index.spec.d.ts +1 -0
- package/schematics/ng-add/index.spec.js +103 -0
- package/schematics/ng-add/index.spec.js.map +1 -0
- package/schematics/ng-add/package-config.d.ts +12 -0
- package/schematics/ng-add/package-config.js +48 -0
- package/schematics/ng-add/package-config.js.map +1 -0
- package/schematics/ng-add/schema.d.ts +3 -0
- package/schematics/ng-add/schema.js +3 -0
- package/schematics/ng-add/schema.js.map +1 -0
- package/schematics/ng-add/schema.json +16 -0
- package/schematics/ng-add/setup.d.ts +3 -0
- package/schematics/ng-add/setup.js +48 -0
- package/schematics/ng-add/setup.js.map +1 -0
- package/schematics/testing/file-content.d.ts +10 -0
- package/schematics/testing/file-content.js +13 -0
- package/schematics/testing/file-content.js.map +1 -0
- package/schematics/testing/test-app.d.ts +12 -0
- package/schematics/testing/test-app.js +44 -0
- package/schematics/testing/test-app.js.map +1 -0
- package/schematics/testing/test-library.d.ts +11 -0
- package/schematics/testing/test-library.js +21 -0
- package/schematics/testing/test-library.js.map +1 -0
- package/schematics/testing/test-project.d.ts +11 -0
- package/schematics/testing/test-project.js +29 -0
- package/schematics/testing/test-project.js.map +1 -0
|
@@ -67,7 +67,8 @@ class WordlistGeneratorComponent {
|
|
|
67
67
|
constructor(formBuilder, wordlistGenerator) {
|
|
68
68
|
this.formBuilder = formBuilder;
|
|
69
69
|
this.wordlistGenerator = wordlistGenerator;
|
|
70
|
-
this.
|
|
70
|
+
this.buttonBackgroundColor = '#424242';
|
|
71
|
+
this.buttonTextColor = '#cc7832';
|
|
71
72
|
this.textColor = '#cc7832';
|
|
72
73
|
this.displayWordlist = false;
|
|
73
74
|
this.fileType = FileType.plaintext;
|
|
@@ -189,11 +190,13 @@ class WordlistGeneratorComponent {
|
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
WordlistGeneratorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: WordlistGeneratorComponent, deps: [{ token: i1.FormBuilder }, { token: WordlistGeneratorService }], target: i0.ɵɵFactoryTarget.Component });
|
|
192
|
-
WordlistGeneratorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: WordlistGeneratorComponent, selector: "wordlist-generator", inputs: { buttonColor: "buttonColor", textColor: "textColor" }, ngImport: i0, template: "<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n (click)=\"generateWordlist()\"\n >\n Generate wordlist\n </button>\n <button\n class=\"choose-format\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n [matMenuTriggerFor]=\"menu\"\n *ngIf=\"wordlist$\"\n >\n Choose format\n </button>\n <mat-menu #menu=\"matMenu\">\n <button\n [ngStyle]=\"{ color: buttonColor }\"\n mat-menu-item\n *ngFor=\"let type of fileTypes\"\n (click)=\"fileType = type\"\n >\n {{ type }}\n </button>\n </mat-menu>\n <button\n class=\"download-wordlist\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n *ngIf=\"wordlist$\"\n (click)=\"downloadWordlist()\"\n >\n Download as\n <ng-container *ngIf=\"this.fileType\">{{ this.fileType }}</ng-container>\n </button>\n </div>\n <form *ngIf=\"charsetForm\" [formGroup]=\"charsetForm\">\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >prefix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"prefix\"\n formControlName=\"prefix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n <div formArrayName=\"charsets\">\n <div class=\"charset\"></div>\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div\n class=\"charset-container\"\n cdkDrag\n *ngFor=\"let charset of charsets?.controls; let i = index\"\n >\n <mat-icon class=\"drag-indicator\" [ngStyle]=\"{ color: buttonColor }\"\n >drag_indicator</mat-icon\n >\n <mat-form-field class=\"charset\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\">\n character set for string position {{ i }}\n </mat-label>\n <input\n matInput\n type=\"text\"\n id=\"position-{{ i }}\"\n [formControlName]=\"i\"\n (keydown.enter)=\"$event.preventDefault()\"\n required\n />\n </mat-form-field>\n <button\n mat-raised-button\n class=\"clone-charset\"\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"cloneCharset(i)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-raised-button\n class=\"remove-charset\"\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"removeCharset(i)\"\n [disabled]=\"this.charsets?.value.length === 1\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n <button\n mat-raised-button\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"addCharset()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >suffix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"suffix\"\n formControlName=\"suffix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n </form>\n </div>\n <div class=\"wordlist-container\" *ngIf=\"wordlist$\" fxLayout=\"column\" fxFlex>\n <ng-container *ngIf=\"displayWordlist; else wordlistTooLarge\">\n <h3 class=\"wordlist-header\">Generated wordlist:</h3>\n <code class=\"wordlist\">\n {{ wordlist$ | async }}\n </code></ng-container\n >\n <ng-template #wordlistTooLarge>\n The generated wordlist is too large to be displayed. You can still\n download it.\n </ng-template>\n </div>\n</div>\n", styles: [".meta-container{max-width:100vw}.meta-container .form-container{float:left}.meta-container .form-container .charset-container .drag-indicator{margin-right:10px}.meta-container .form-container .charset-container .clone-charset{margin:0 10px}.meta-container .form-container .charset-container .remove-charset{margin-right:10px}.meta-container .form-container .charset{width:18.875em}.meta-container .form-container .charset-container:not(:last-child) .add-charset{display:none}.meta-container .form-container .choose-format{margin:0 34px 10px;width:150px}.meta-container .form-container .generate-wordlist,.meta-container .form-container .download-wordlist{margin:0 0 10px;width:150px}.meta-container .wordlist-container{max-height:80vh}.meta-container .wordlist-container .wordlist-header{margin-top:0}.meta-container .wordlist-container .wordlist{margin-left:1em;overflow-wrap:normal;width:1%}.mat-menu-panel{width:150px}.mat-form-field-appearance-outline .mat-form-field-infix{border:0;padding:1em 0 .5em}.mat-form-field-appearance-outline .mat-form-field-wrapper{padding-bottom:.25em}.mat-form-field-label{transition:none!important}.mat-form-field-should-float .mat-form-field-label-wrapper{top:-.1em;padding-top:.1em}.mat-form-field-should-float .mat-form-field-label{transition:none!important}.fix{width:21em}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.MatLabel, selector: "mat-label" }, { type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }], pipes: { "async": i7.AsyncPipe }, encapsulation: i0.ViewEncapsulation.None });
|
|
193
|
+
WordlistGeneratorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: WordlistGeneratorComponent, selector: "wordlist-generator", inputs: { buttonBackgroundColor: "buttonBackgroundColor", buttonTextColor: "buttonTextColor", textColor: "textColor" }, ngImport: i0, template: "<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n (click)=\"generateWordlist()\"\n >\n Generate wordlist\n </button>\n <button\n class=\"choose-format\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n [matMenuTriggerFor]=\"menu\"\n *ngIf=\"wordlist$\"\n >\n Choose format\n </button>\n <mat-menu #menu=\"matMenu\">\n <button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-menu-item\n *ngFor=\"let type of fileTypes\"\n (click)=\"fileType = type\"\n >\n {{ type }}\n </button>\n </mat-menu>\n <button\n class=\"download-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n *ngIf=\"wordlist$\"\n (click)=\"downloadWordlist()\"\n >\n Download as\n <ng-container *ngIf=\"this.fileType\">{{ this.fileType }}</ng-container>\n </button>\n </div>\n <form *ngIf=\"charsetForm\" [formGroup]=\"charsetForm\">\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >prefix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"prefix\"\n formControlName=\"prefix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n <div formArrayName=\"charsets\">\n <div class=\"charset\"></div>\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div\n class=\"charset-container\"\n cdkDrag\n *ngFor=\"let charset of charsets?.controls; let i = index\"\n >\n <mat-icon\n class=\"drag-indicator\"\n [ngStyle]=\"{\n color: buttonTextColor\n }\"\n >drag_indicator</mat-icon\n >\n <mat-form-field class=\"charset\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\">\n character set for string position {{ i }}\n </mat-label>\n <input\n matInput\n type=\"text\"\n id=\"position-{{ i }}\"\n [formControlName]=\"i\"\n (keydown.enter)=\"$event.preventDefault()\"\n required\n />\n </mat-form-field>\n <button\n mat-raised-button\n class=\"clone-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"cloneCharset(i)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-raised-button\n class=\"remove-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"removeCharset(i)\"\n [disabled]=\"this.charsets?.value.length === 1\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n <button\n mat-raised-button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"addCharset()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >suffix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"suffix\"\n formControlName=\"suffix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n </form>\n </div>\n <div class=\"wordlist-container\" *ngIf=\"wordlist$\" fxLayout=\"column\" fxFlex>\n <ng-container *ngIf=\"displayWordlist; else wordlistTooLarge\">\n <h3 class=\"wordlist-header\">Generated wordlist:</h3>\n <code class=\"wordlist\">\n {{ wordlist$ | async }}\n </code></ng-container\n >\n <ng-template #wordlistTooLarge>\n The generated wordlist is too large to be displayed. You can still\n download it.\n </ng-template>\n </div>\n</div>\n", styles: [".meta-container{max-width:100vw}.meta-container .form-container{float:left}.meta-container .form-container .charset-container .drag-indicator{margin-right:10px}.meta-container .form-container .charset-container .clone-charset{margin:0 10px}.meta-container .form-container .charset-container .remove-charset{margin-right:10px}.meta-container .form-container .charset{width:18.875em}.meta-container .form-container .charset-container:not(:last-child) .add-charset{display:none}.meta-container .form-container .choose-format{margin:0 34px 10px;width:150px}.meta-container .form-container .generate-wordlist,.meta-container .form-container .download-wordlist{margin:0 0 10px;width:150px}.meta-container .wordlist-container{max-height:80vh}.meta-container .wordlist-container .wordlist-header{margin-top:0}.meta-container .wordlist-container .wordlist{margin-left:1em;overflow-wrap:normal;width:1%}.mat-menu-panel{width:150px}.mat-form-field-appearance-outline .mat-form-field-infix{border:0;padding:1em 0 .5em}.mat-form-field-appearance-outline .mat-form-field-wrapper{padding-bottom:.25em}.mat-form-field-label{transition:none!important}.mat-form-field-should-float .mat-form-field-label-wrapper{top:-.1em;padding-top:.1em}.mat-form-field-should-float .mat-form-field-label{transition:none!important}.fix{width:21em}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.MatLabel, selector: "mat-label" }, { type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }], pipes: { "async": i7.AsyncPipe }, encapsulation: i0.ViewEncapsulation.None });
|
|
193
194
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: WordlistGeneratorComponent, decorators: [{
|
|
194
195
|
type: Component,
|
|
195
|
-
args: [{ selector: 'wordlist-generator', encapsulation: ViewEncapsulation.None, template: "<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{ color:
|
|
196
|
-
}], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: WordlistGeneratorService }]; }, propDecorators: {
|
|
196
|
+
args: [{ selector: 'wordlist-generator', encapsulation: ViewEncapsulation.None, template: "<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n (click)=\"generateWordlist()\"\n >\n Generate wordlist\n </button>\n <button\n class=\"choose-format\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n [matMenuTriggerFor]=\"menu\"\n *ngIf=\"wordlist$\"\n >\n Choose format\n </button>\n <mat-menu #menu=\"matMenu\">\n <button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-menu-item\n *ngFor=\"let type of fileTypes\"\n (click)=\"fileType = type\"\n >\n {{ type }}\n </button>\n </mat-menu>\n <button\n class=\"download-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n *ngIf=\"wordlist$\"\n (click)=\"downloadWordlist()\"\n >\n Download as\n <ng-container *ngIf=\"this.fileType\">{{ this.fileType }}</ng-container>\n </button>\n </div>\n <form *ngIf=\"charsetForm\" [formGroup]=\"charsetForm\">\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >prefix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"prefix\"\n formControlName=\"prefix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n <div formArrayName=\"charsets\">\n <div class=\"charset\"></div>\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div\n class=\"charset-container\"\n cdkDrag\n *ngFor=\"let charset of charsets?.controls; let i = index\"\n >\n <mat-icon\n class=\"drag-indicator\"\n [ngStyle]=\"{\n color: buttonTextColor\n }\"\n >drag_indicator</mat-icon\n >\n <mat-form-field class=\"charset\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\">\n character set for string position {{ i }}\n </mat-label>\n <input\n matInput\n type=\"text\"\n id=\"position-{{ i }}\"\n [formControlName]=\"i\"\n (keydown.enter)=\"$event.preventDefault()\"\n required\n />\n </mat-form-field>\n <button\n mat-raised-button\n class=\"clone-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"cloneCharset(i)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-raised-button\n class=\"remove-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"removeCharset(i)\"\n [disabled]=\"this.charsets?.value.length === 1\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n <button\n mat-raised-button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"addCharset()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >suffix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"suffix\"\n formControlName=\"suffix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n </form>\n </div>\n <div class=\"wordlist-container\" *ngIf=\"wordlist$\" fxLayout=\"column\" fxFlex>\n <ng-container *ngIf=\"displayWordlist; else wordlistTooLarge\">\n <h3 class=\"wordlist-header\">Generated wordlist:</h3>\n <code class=\"wordlist\">\n {{ wordlist$ | async }}\n </code></ng-container\n >\n <ng-template #wordlistTooLarge>\n The generated wordlist is too large to be displayed. You can still\n download it.\n </ng-template>\n </div>\n</div>\n", styles: [".meta-container{max-width:100vw}.meta-container .form-container{float:left}.meta-container .form-container .charset-container .drag-indicator{margin-right:10px}.meta-container .form-container .charset-container .clone-charset{margin:0 10px}.meta-container .form-container .charset-container .remove-charset{margin-right:10px}.meta-container .form-container .charset{width:18.875em}.meta-container .form-container .charset-container:not(:last-child) .add-charset{display:none}.meta-container .form-container .choose-format{margin:0 34px 10px;width:150px}.meta-container .form-container .generate-wordlist,.meta-container .form-container .download-wordlist{margin:0 0 10px;width:150px}.meta-container .wordlist-container{max-height:80vh}.meta-container .wordlist-container .wordlist-header{margin-top:0}.meta-container .wordlist-container .wordlist{margin-left:1em;overflow-wrap:normal;width:1%}.mat-menu-panel{width:150px}.mat-form-field-appearance-outline .mat-form-field-infix{border:0;padding:1em 0 .5em}.mat-form-field-appearance-outline .mat-form-field-wrapper{padding-bottom:.25em}.mat-form-field-label{transition:none!important}.mat-form-field-should-float .mat-form-field-label-wrapper{top:-.1em;padding-top:.1em}.mat-form-field-should-float .mat-form-field-label{transition:none!important}.fix{width:21em}\n"] }]
|
|
197
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: WordlistGeneratorService }]; }, propDecorators: { buttonBackgroundColor: [{
|
|
198
|
+
type: Input
|
|
199
|
+
}], buttonTextColor: [{
|
|
197
200
|
type: Input
|
|
198
201
|
}], textColor: [{
|
|
199
202
|
type: Input
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tehw0lf-wordlist-generator.mjs","sources":["../../../../libs/wordlist-generator/src/lib/filetypes.ts","../../../../libs/wordlist-generator/src/lib/parsers.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.service.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.component.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.component.html","../../../../libs/wordlist-generator/src/lib/wordlist-generator.module.ts","../../../../libs/wordlist-generator/src/tehw0lf-wordlist-generator.ts"],"sourcesContent":["/* eslint-disable no-shadow */\nexport enum FileType {\n plaintext = 'txt',\n xml = 'xml'\n}\n","export const toPlaintext = (\n wordlist: string\n): { wordlist: string; contentType: string } => ({\n wordlist,\n contentType: 'text/plain'\n});\n\nexport const toXML = (\n wordlist: string\n): { wordlist: string; contentType: string } => {\n const head = '<wordlist><word>';\n const glue = '</word><word>';\n const tail = '</word></wordlist>';\n return {\n wordlist: head + wordlist.replace(/\\n/g, glue) + tail,\n contentType: 'text/xml'\n };\n};\n","import { Injectable } from '@angular/core';\nimport { product } from 'cartesian-product-generator';\nimport { from, Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class WordlistGeneratorService {\n constructor() {\n //\n }\n\n generateWordlist(...charsets: string[]): Observable<string> {\n return from(product(...charsets)).pipe(\n map((word: string[]) => {\n return word.join('');\n })\n );\n }\n}\n","import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';\nimport { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Observable, Subject } from 'rxjs';\nimport { reduce, takeUntil, tap } from 'rxjs/operators';\n\nimport { FileType } from './filetypes';\nimport { toPlaintext, toXML } from './parsers';\nimport { WordlistGeneratorService } from './wordlist-generator.service';\n\n/* eslint-disable @angular-eslint/component-selector */\n@Component({\n selector: 'wordlist-generator',\n templateUrl: './wordlist-generator.component.html',\n styleUrls: ['./wordlist-generator.component.scss'],\n encapsulation: ViewEncapsulation.None\n})\nexport class WordlistGeneratorComponent implements OnInit, OnDestroy {\n @Input() buttonColor = '#cc7832';\n @Input() textColor = '#cc7832';\n\n charsetForm: FormGroup | undefined;\n wordsGenerated: number | undefined;\n wordlist$: Observable<string> | undefined;\n\n displayWordlist = false;\n fileType = FileType.plaintext;\n fileTypes = Object.values(FileType);\n filteredCharset: string[] = [];\n prefix = '';\n suffix = '';\n\n private unsubscribe$ = new Subject<void>();\n\n constructor(\n private formBuilder: FormBuilder,\n private wordlistGenerator: WordlistGeneratorService\n ) {}\n\n ngOnInit(): void {\n this.generateForm();\n }\n\n ngOnDestroy(): void {\n this.unsubscribe$.next();\n this.unsubscribe$.complete();\n }\n\n get charsets(): FormArray | undefined {\n if (this.charsetForm) {\n return this.charsetForm.get('charsets') as FormArray;\n }\n return undefined;\n }\n\n addCharset(): void {\n if (this.charsets) {\n this.charsets.push(this.formBuilder.control('', Validators.required));\n }\n }\n\n cloneCharset(index: number): void {\n if (this.charsets) {\n const charset = this.charsets.value[index];\n this.charsets.insert(\n index,\n this.formBuilder.control(charset, Validators.required)\n );\n }\n }\n\n downloadWordlist(): void {\n if (this.charsets) {\n if (this.filteredCharset !== this.filterCharset(this.charsets.value)) {\n this.generateWordlist();\n }\n const filename = `wordlist_${this.wordsGenerated}_words_${this.charsets.length}_positions.${this.fileType}`;\n this.getWordlist()\n .pipe(\n tap((wordlist: string) => {\n if (wordlist.length > 0) {\n const parsed = this.parseWordlist(wordlist);\n const file = new Blob([parsed.wordlist], {\n type: parsed.contentType\n });\n if ((window.navigator as any).msSaveOrOpenBlob) {\n (window.navigator as any).msSaveOrOpenBlob(file, filename);\n } else {\n const a = document.createElement('a');\n const url = URL.createObjectURL(file);\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n setTimeout(() => {\n document.body.removeChild(a);\n window.URL.revokeObjectURL(url);\n }, 0);\n }\n }\n })\n )\n .subscribe();\n }\n }\n\n drop(event: CdkDragDrop<string[]>): void {\n if (this.charsets) {\n moveItemInArray(\n this.charsets.controls,\n event.previousIndex,\n event.currentIndex\n );\n this.charsets.updateValueAndValidity();\n }\n }\n\n generateForm(): void {\n this.charsetForm = this.formBuilder.group({\n charsets: this.formBuilder.array([\n this.formBuilder.control('', Validators.required)\n ]),\n prefix: this.formBuilder.control(''),\n suffix: this.formBuilder.control('')\n });\n }\n\n generateWordlist(): void {\n if (this.charsetForm && this.charsets && this.charsets.valid) {\n this.filteredCharset = this.filterCharset(this.charsets.value);\n this.prefix = this.charsetForm.get('prefix')?.value\n ? this.charsetForm.get('prefix')?.value\n : '';\n this.suffix = this.charsetForm.get('suffix')?.value\n ? this.charsetForm.get('suffix')?.value\n : '';\n\n this.wordsGenerated = this.filteredCharset\n .map((charset: string) => charset.length)\n .reduce(\n (previousLength: number, currentLength: number) =>\n previousLength * currentLength\n );\n this.displayWordlist = this.wordsGenerated <= 100;\n this.wordlist$ = this.getWordlist();\n }\n }\n\n getWordlist(): Observable<string> {\n return this.wordlistGenerator\n .generateWordlist(...this.filteredCharset)\n .pipe(\n reduce(\n (wordlist: string, word: string) =>\n `${wordlist}${this.prefix}${word}${this.suffix}\\n`,\n ''\n ),\n takeUntil(this.unsubscribe$)\n );\n }\n\n filterCharset(charsets: string[]): string[] {\n return charsets.map((charset: string) => this.removeDuplicates(charset));\n }\n\n parseWordlist(wordlist: string): { wordlist: string; contentType: string } {\n switch (this.fileType) {\n case FileType.plaintext:\n return toPlaintext(wordlist);\n case FileType.xml:\n return toXML(wordlist);\n }\n }\n\n removeCharset(i: number): void {\n if (this.charsets && this.charsets.length > 1) {\n this.charsets.removeAt(i);\n }\n }\n\n removeDuplicates = (unfiltered: string): string =>\n [...new Set(unfiltered)].join('');\n}\n","<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n (click)=\"generateWordlist()\"\n >\n Generate wordlist\n </button>\n <button\n class=\"choose-format\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n [matMenuTriggerFor]=\"menu\"\n *ngIf=\"wordlist$\"\n >\n Choose format\n </button>\n <mat-menu #menu=\"matMenu\">\n <button\n [ngStyle]=\"{ color: buttonColor }\"\n mat-menu-item\n *ngFor=\"let type of fileTypes\"\n (click)=\"fileType = type\"\n >\n {{ type }}\n </button>\n </mat-menu>\n <button\n class=\"download-wordlist\"\n [ngStyle]=\"{ color: buttonColor }\"\n mat-raised-button\n *ngIf=\"wordlist$\"\n (click)=\"downloadWordlist()\"\n >\n Download as\n <ng-container *ngIf=\"this.fileType\">{{ this.fileType }}</ng-container>\n </button>\n </div>\n <form *ngIf=\"charsetForm\" [formGroup]=\"charsetForm\">\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >prefix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"prefix\"\n formControlName=\"prefix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n <div formArrayName=\"charsets\">\n <div class=\"charset\"></div>\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div\n class=\"charset-container\"\n cdkDrag\n *ngFor=\"let charset of charsets?.controls; let i = index\"\n >\n <mat-icon class=\"drag-indicator\" [ngStyle]=\"{ color: buttonColor }\"\n >drag_indicator</mat-icon\n >\n <mat-form-field class=\"charset\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\">\n character set for string position {{ i }}\n </mat-label>\n <input\n matInput\n type=\"text\"\n id=\"position-{{ i }}\"\n [formControlName]=\"i\"\n (keydown.enter)=\"$event.preventDefault()\"\n required\n />\n </mat-form-field>\n <button\n mat-raised-button\n class=\"clone-charset\"\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"cloneCharset(i)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-raised-button\n class=\"remove-charset\"\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"removeCharset(i)\"\n [disabled]=\"this.charsets?.value.length === 1\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n <button\n mat-raised-button\n [ngStyle]=\"{ color: buttonColor }\"\n (click)=\"addCharset()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >suffix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"suffix\"\n formControlName=\"suffix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n </form>\n </div>\n <div class=\"wordlist-container\" *ngIf=\"wordlist$\" fxLayout=\"column\" fxFlex>\n <ng-container *ngIf=\"displayWordlist; else wordlistTooLarge\">\n <h3 class=\"wordlist-header\">Generated wordlist:</h3>\n <code class=\"wordlist\">\n {{ wordlist$ | async }}\n </code></ng-container\n >\n <ng-template #wordlistTooLarge>\n The generated wordlist is too large to be displayed. You can still\n download it.\n </ng-template>\n </div>\n</div>\n","import { ClipboardModule } from '@angular/cdk/clipboard';\nimport { DragDropModule } from '@angular/cdk/drag-drop';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { BrowserModule } from '@angular/platform-browser';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\n\nimport { WordlistGeneratorComponent } from './wordlist-generator.component';\nimport { WordlistGeneratorService } from './wordlist-generator.service';\n\n@NgModule({\n declarations: [WordlistGeneratorComponent],\n imports: [\n CommonModule,\n BrowserModule,\n BrowserAnimationsModule,\n DragDropModule,\n ReactiveFormsModule,\n ClipboardModule,\n MatIconModule,\n MatInputModule,\n MatMenuModule,\n MatButtonModule\n ],\n exports: [WordlistGeneratorComponent],\n providers: [WordlistGeneratorService]\n})\nexport class WordlistGeneratorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tehw0lf-wordlist-generator.mjs","sources":["../../../../libs/wordlist-generator/src/lib/filetypes.ts","../../../../libs/wordlist-generator/src/lib/parsers.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.service.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.component.ts","../../../../libs/wordlist-generator/src/lib/wordlist-generator.component.html","../../../../libs/wordlist-generator/src/lib/wordlist-generator.module.ts","../../../../libs/wordlist-generator/src/tehw0lf-wordlist-generator.ts"],"sourcesContent":["/* eslint-disable no-shadow */\nexport enum FileType {\n plaintext = 'txt',\n xml = 'xml'\n}\n","export const toPlaintext = (\n wordlist: string\n): { wordlist: string; contentType: string } => ({\n wordlist,\n contentType: 'text/plain'\n});\n\nexport const toXML = (\n wordlist: string\n): { wordlist: string; contentType: string } => {\n const head = '<wordlist><word>';\n const glue = '</word><word>';\n const tail = '</word></wordlist>';\n return {\n wordlist: head + wordlist.replace(/\\n/g, glue) + tail,\n contentType: 'text/xml'\n };\n};\n","import { Injectable } from '@angular/core';\nimport { product } from 'cartesian-product-generator';\nimport { from, Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class WordlistGeneratorService {\n constructor() {\n //\n }\n\n generateWordlist(...charsets: string[]): Observable<string> {\n return from(product(...charsets)).pipe(\n map((word: string[]) => {\n return word.join('');\n })\n );\n }\n}\n","import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';\nimport { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { Observable, Subject } from 'rxjs';\nimport { reduce, takeUntil, tap } from 'rxjs/operators';\n\nimport { FileType } from './filetypes';\nimport { toPlaintext, toXML } from './parsers';\nimport { WordlistGeneratorService } from './wordlist-generator.service';\n\n/* eslint-disable @angular-eslint/component-selector */\n@Component({\n selector: 'wordlist-generator',\n templateUrl: './wordlist-generator.component.html',\n styleUrls: ['./wordlist-generator.component.scss'],\n encapsulation: ViewEncapsulation.None\n})\nexport class WordlistGeneratorComponent implements OnInit, OnDestroy {\n @Input() buttonBackgroundColor = '#424242';\n @Input() buttonTextColor = '#cc7832';\n @Input() textColor = '#cc7832';\n\n charsetForm: FormGroup | undefined;\n wordsGenerated: number | undefined;\n wordlist$: Observable<string> | undefined;\n\n displayWordlist = false;\n fileType = FileType.plaintext;\n fileTypes = Object.values(FileType);\n filteredCharset: string[] = [];\n prefix = '';\n suffix = '';\n\n private unsubscribe$ = new Subject<void>();\n\n constructor(\n private formBuilder: FormBuilder,\n private wordlistGenerator: WordlistGeneratorService\n ) {}\n\n ngOnInit(): void {\n this.generateForm();\n }\n\n ngOnDestroy(): void {\n this.unsubscribe$.next();\n this.unsubscribe$.complete();\n }\n\n get charsets(): FormArray | undefined {\n if (this.charsetForm) {\n return this.charsetForm.get('charsets') as FormArray;\n }\n return undefined;\n }\n\n addCharset(): void {\n if (this.charsets) {\n this.charsets.push(this.formBuilder.control('', Validators.required));\n }\n }\n\n cloneCharset(index: number): void {\n if (this.charsets) {\n const charset = this.charsets.value[index];\n this.charsets.insert(\n index,\n this.formBuilder.control(charset, Validators.required)\n );\n }\n }\n\n downloadWordlist(): void {\n if (this.charsets) {\n if (this.filteredCharset !== this.filterCharset(this.charsets.value)) {\n this.generateWordlist();\n }\n const filename = `wordlist_${this.wordsGenerated}_words_${this.charsets.length}_positions.${this.fileType}`;\n this.getWordlist()\n .pipe(\n tap((wordlist: string) => {\n if (wordlist.length > 0) {\n const parsed = this.parseWordlist(wordlist);\n const file = new Blob([parsed.wordlist], {\n type: parsed.contentType\n });\n if ((window.navigator as any).msSaveOrOpenBlob) {\n (window.navigator as any).msSaveOrOpenBlob(file, filename);\n } else {\n const a = document.createElement('a');\n const url = URL.createObjectURL(file);\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n setTimeout(() => {\n document.body.removeChild(a);\n window.URL.revokeObjectURL(url);\n }, 0);\n }\n }\n })\n )\n .subscribe();\n }\n }\n\n drop(event: CdkDragDrop<string[]>): void {\n if (this.charsets) {\n moveItemInArray(\n this.charsets.controls,\n event.previousIndex,\n event.currentIndex\n );\n this.charsets.updateValueAndValidity();\n }\n }\n\n generateForm(): void {\n this.charsetForm = this.formBuilder.group({\n charsets: this.formBuilder.array([\n this.formBuilder.control('', Validators.required)\n ]),\n prefix: this.formBuilder.control(''),\n suffix: this.formBuilder.control('')\n });\n }\n\n generateWordlist(): void {\n if (this.charsetForm && this.charsets && this.charsets.valid) {\n this.filteredCharset = this.filterCharset(this.charsets.value);\n this.prefix = this.charsetForm.get('prefix')?.value\n ? this.charsetForm.get('prefix')?.value\n : '';\n this.suffix = this.charsetForm.get('suffix')?.value\n ? this.charsetForm.get('suffix')?.value\n : '';\n\n this.wordsGenerated = this.filteredCharset\n .map((charset: string) => charset.length)\n .reduce(\n (previousLength: number, currentLength: number) =>\n previousLength * currentLength\n );\n this.displayWordlist = this.wordsGenerated <= 100;\n this.wordlist$ = this.getWordlist();\n }\n }\n\n getWordlist(): Observable<string> {\n return this.wordlistGenerator\n .generateWordlist(...this.filteredCharset)\n .pipe(\n reduce(\n (wordlist: string, word: string) =>\n `${wordlist}${this.prefix}${word}${this.suffix}\\n`,\n ''\n ),\n takeUntil(this.unsubscribe$)\n );\n }\n\n filterCharset(charsets: string[]): string[] {\n return charsets.map((charset: string) => this.removeDuplicates(charset));\n }\n\n parseWordlist(wordlist: string): { wordlist: string; contentType: string } {\n switch (this.fileType) {\n case FileType.plaintext:\n return toPlaintext(wordlist);\n case FileType.xml:\n return toXML(wordlist);\n }\n }\n\n removeCharset(i: number): void {\n if (this.charsets && this.charsets.length > 1) {\n this.charsets.removeAt(i);\n }\n }\n\n removeDuplicates = (unfiltered: string): string =>\n [...new Set(unfiltered)].join('');\n}\n","<div class=\"meta-container\" fxLayout=\"row wrap\">\n <div class=\"form-container\" fxLayout=\"column\" fxFlex>\n <div fxLayout=\"row wrap\">\n <button\n class=\"generate-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n (click)=\"generateWordlist()\"\n >\n Generate wordlist\n </button>\n <button\n class=\"choose-format\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n [matMenuTriggerFor]=\"menu\"\n *ngIf=\"wordlist$\"\n >\n Choose format\n </button>\n <mat-menu #menu=\"matMenu\">\n <button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-menu-item\n *ngFor=\"let type of fileTypes\"\n (click)=\"fileType = type\"\n >\n {{ type }}\n </button>\n </mat-menu>\n <button\n class=\"download-wordlist\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n mat-raised-button\n *ngIf=\"wordlist$\"\n (click)=\"downloadWordlist()\"\n >\n Download as\n <ng-container *ngIf=\"this.fileType\">{{ this.fileType }}</ng-container>\n </button>\n </div>\n <form *ngIf=\"charsetForm\" [formGroup]=\"charsetForm\">\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >prefix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"prefix\"\n formControlName=\"prefix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n <div formArrayName=\"charsets\">\n <div class=\"charset\"></div>\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div\n class=\"charset-container\"\n cdkDrag\n *ngFor=\"let charset of charsets?.controls; let i = index\"\n >\n <mat-icon\n class=\"drag-indicator\"\n [ngStyle]=\"{\n color: buttonTextColor\n }\"\n >drag_indicator</mat-icon\n >\n <mat-form-field class=\"charset\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\">\n character set for string position {{ i }}\n </mat-label>\n <input\n matInput\n type=\"text\"\n id=\"position-{{ i }}\"\n [formControlName]=\"i\"\n (keydown.enter)=\"$event.preventDefault()\"\n required\n />\n </mat-form-field>\n <button\n mat-raised-button\n class=\"clone-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"cloneCharset(i)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-raised-button\n class=\"remove-charset\"\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"removeCharset(i)\"\n [disabled]=\"this.charsets?.value.length === 1\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n <button\n mat-raised-button\n [ngStyle]=\"{\n background: buttonBackgroundColor,\n color: buttonTextColor\n }\"\n (click)=\"addCharset()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-form-field class=\"fix\" appearance=\"outline\">\n <mat-label [ngStyle]=\"{ color: textColor }\"\n >suffix (optional)</mat-label\n >\n <input\n matInput\n type=\"text\"\n id=\"suffix\"\n formControlName=\"suffix\"\n (keydown.enter)=\"$event.preventDefault()\"\n />\n </mat-form-field>\n </form>\n </div>\n <div class=\"wordlist-container\" *ngIf=\"wordlist$\" fxLayout=\"column\" fxFlex>\n <ng-container *ngIf=\"displayWordlist; else wordlistTooLarge\">\n <h3 class=\"wordlist-header\">Generated wordlist:</h3>\n <code class=\"wordlist\">\n {{ wordlist$ | async }}\n </code></ng-container\n >\n <ng-template #wordlistTooLarge>\n The generated wordlist is too large to be displayed. You can still\n download it.\n </ng-template>\n </div>\n</div>\n","import { ClipboardModule } from '@angular/cdk/clipboard';\nimport { DragDropModule } from '@angular/cdk/drag-drop';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { BrowserModule } from '@angular/platform-browser';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\n\nimport { WordlistGeneratorComponent } from './wordlist-generator.component';\nimport { WordlistGeneratorService } from './wordlist-generator.service';\n\n@NgModule({\n declarations: [WordlistGeneratorComponent],\n imports: [\n CommonModule,\n BrowserModule,\n BrowserAnimationsModule,\n DragDropModule,\n ReactiveFormsModule,\n ClipboardModule,\n MatIconModule,\n MatInputModule,\n MatMenuModule,\n MatButtonModule\n ],\n exports: [WordlistGeneratorComponent],\n providers: [WordlistGeneratorService]\n})\nexport class WordlistGeneratorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;AACb,CAAC,EAHW,QAAQ,KAAR,QAAQ;;ACDb,MAAM,WAAW,GAAG,CACzB,QAAgB,MAC+B;IAC/C,QAAQ;IACR,WAAW,EAAE,YAAY;CAC1B,CAAC,CAAC;AAEI,MAAM,KAAK,GAAG,CACnB,QAAgB;IAEhB,MAAM,IAAI,GAAG,kBAAkB,CAAC;IAChC,MAAM,IAAI,GAAG,eAAe,CAAC;IAC7B,MAAM,IAAI,GAAG,oBAAoB,CAAC;IAClC,OAAO;QACL,QAAQ,EAAE,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,IAAI;QACrD,WAAW,EAAE,UAAU;KACxB,CAAC;AACJ,CAAC;;MCTY,wBAAwB;IACnC;;KAEC;IAED,gBAAgB,CAAC,GAAG,QAAkB;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CACpC,GAAG,CAAC,CAAC,IAAc;YACjB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACtB,CAAC,CACH,CAAC;KACH;;qHAXU,wBAAwB;yHAAxB,wBAAwB,cAFvB,MAAM;2FAEP,wBAAwB;kBAHpC,UAAU;mBAAC;oBACV,UAAU,EAAE,MAAM;iBACnB;;;ACGD;MAOa,0BAA0B;IAkBrC,YACU,WAAwB,EACxB,iBAA2C;QAD3C,gBAAW,GAAX,WAAW,CAAa;QACxB,sBAAiB,GAAjB,iBAAiB,CAA0B;QAnB5C,0BAAqB,GAAG,SAAS,CAAC;QAClC,oBAAe,GAAG,SAAS,CAAC;QAC5B,cAAS,GAAG,SAAS,CAAC;QAM/B,oBAAe,GAAG,KAAK,CAAC;QACxB,aAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC9B,cAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,oBAAe,GAAa,EAAE,CAAC;QAC/B,WAAM,GAAG,EAAE,CAAC;QACZ,WAAM,GAAG,EAAE,CAAC;QAEJ,iBAAY,GAAG,IAAI,OAAO,EAAQ,CAAC;QAoJ3C,qBAAgB,GAAG,CAAC,UAAkB,KACpC,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KAhJhC;IAEJ,QAAQ;QACN,IAAI,CAAC,YAAY,EAAE,CAAC;KACrB;IAED,WAAW;QACT,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;KAC9B;IAED,IAAI,QAAQ;QACV,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAc,CAAC;SACtD;QACD,OAAO,SAAS,CAAC;KAClB;IAED,UAAU;QACR,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;SACvE;KACF;IAED,YAAY,CAAC,KAAa;QACxB,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAClB,KAAK,EACL,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,CACvD,CAAC;SACH;KACF;IAED,gBAAgB;QACd,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBACpE,IAAI,CAAC,gBAAgB,EAAE,CAAC;aACzB;YACD,MAAM,QAAQ,GAAG,YAAY,IAAI,CAAC,cAAc,UAAU,IAAI,CAAC,QAAQ,CAAC,MAAM,cAAc,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5G,IAAI,CAAC,WAAW,EAAE;iBACf,IAAI,CACH,GAAG,CAAC,CAAC,QAAgB;gBACnB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;oBACvB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;oBAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;wBACvC,IAAI,EAAE,MAAM,CAAC,WAAW;qBACzB,CAAC,CAAC;oBACH,IAAK,MAAM,CAAC,SAAiB,CAAC,gBAAgB,EAAE;wBAC7C,MAAM,CAAC,SAAiB,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;qBAC5D;yBAAM;wBACL,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;wBACtC,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;wBACtC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;wBACb,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;wBACtB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;wBAC7B,CAAC,CAAC,KAAK,EAAE,CAAC;wBACV,UAAU,CAAC;4BACT,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;4BAC7B,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;yBACjC,EAAE,CAAC,CAAC,CAAC;qBACP;iBACF;aACF,CAAC,CACH;iBACA,SAAS,EAAE,CAAC;SAChB;KACF;IAED,IAAI,CAAC,KAA4B;QAC/B,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,eAAe,CACb,IAAI,CAAC,QAAQ,CAAC,QAAQ,EACtB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,YAAY,CACnB,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC;SACxC;KACF;IAED,YAAY;QACV,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACxC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;gBAC/B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;aAClD,CAAC;YACF,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC;KACJ;IAED,gBAAgB;QACd,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;YAC5D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK;kBAC/C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK;kBACrC,EAAE,CAAC;YACP,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK;kBAC/C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK;kBACrC,EAAE,CAAC;YAEP,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe;iBACvC,GAAG,CAAC,CAAC,OAAe,KAAK,OAAO,CAAC,MAAM,CAAC;iBACxC,MAAM,CACL,CAAC,cAAsB,EAAE,aAAqB,KAC5C,cAAc,GAAG,aAAa,CACjC,CAAC;YACJ,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,cAAc,IAAI,GAAG,CAAC;YAClD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;SACrC;KACF;IAED,WAAW;QACT,OAAO,IAAI,CAAC,iBAAiB;aAC1B,gBAAgB,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;aACzC,IAAI,CACH,MAAM,CACJ,CAAC,QAAgB,EAAE,IAAY,KAC7B,GAAG,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,EACpD,EAAE,CACH,EACD,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAC7B,CAAC;KACL;IAED,aAAa,CAAC,QAAkB;QAC9B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAe,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;KAC1E;IAED,aAAa,CAAC,QAAgB;QAC5B,QAAQ,IAAI,CAAC,QAAQ;YACnB,KAAK,QAAQ,CAAC,SAAS;gBACrB,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC/B,KAAK,QAAQ,CAAC,GAAG;gBACf,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;SAC1B;KACF;IAED,aAAa,CAAC,CAAS;QACrB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SAC3B;KACF;;uHAlKU,0BAA0B;2GAA1B,0BAA0B,kLCjBvC,g6JA6JA;2FD5Ia,0BAA0B;kBANtC,SAAS;+BACE,oBAAoB,iBAGf,iBAAiB,CAAC,IAAI;sIAG5B,qBAAqB;sBAA7B,KAAK;gBACG,eAAe;sBAAvB,KAAK;gBACG,SAAS;sBAAjB,KAAK;;;MEYK,uBAAuB;;oHAAvB,uBAAuB;qHAAvB,uBAAuB,iBAhBnB,0BAA0B,aAEvC,YAAY;QACZ,aAAa;QACb,uBAAuB;QACvB,cAAc;QACd,mBAAmB;QACnB,eAAe;QACf,aAAa;QACb,cAAc;QACd,aAAa;QACb,eAAe,aAEP,0BAA0B;qHAGzB,uBAAuB,aAFvB,CAAC,wBAAwB,CAAC,YAb5B;YACP,YAAY;YACZ,aAAa;YACb,uBAAuB;YACvB,cAAc;YACd,mBAAmB;YACnB,eAAe;YACf,aAAa;YACb,cAAc;YACd,aAAa;YACb,eAAe;SAChB;2FAIU,uBAAuB;kBAjBnC,QAAQ;mBAAC;oBACR,YAAY,EAAE,CAAC,0BAA0B,CAAC;oBAC1C,OAAO,EAAE;wBACP,YAAY;wBACZ,aAAa;wBACb,uBAAuB;wBACvB,cAAc;wBACd,mBAAmB;wBACnB,eAAe;wBACf,aAAa;wBACb,cAAc;wBACd,aAAa;wBACb,eAAe;qBAChB;oBACD,OAAO,EAAE,CAAC,0BAA0B,CAAC;oBACrC,SAAS,EAAE,CAAC,wBAAwB,CAAC;iBACtC;;;AC/BD;;;;;;"}
|
|
@@ -8,7 +8,8 @@ import * as i0 from "@angular/core";
|
|
|
8
8
|
export declare class WordlistGeneratorComponent implements OnInit, OnDestroy {
|
|
9
9
|
private formBuilder;
|
|
10
10
|
private wordlistGenerator;
|
|
11
|
-
|
|
11
|
+
buttonBackgroundColor: string;
|
|
12
|
+
buttonTextColor: string;
|
|
12
13
|
textColor: string;
|
|
13
14
|
charsetForm: FormGroup | undefined;
|
|
14
15
|
wordsGenerated: number | undefined;
|
|
@@ -39,5 +40,5 @@ export declare class WordlistGeneratorComponent implements OnInit, OnDestroy {
|
|
|
39
40
|
removeCharset(i: number): void;
|
|
40
41
|
removeDuplicates: (unfiltered: string) => string;
|
|
41
42
|
static ɵfac: i0.ɵɵFactoryDeclaration<WordlistGeneratorComponent, never>;
|
|
42
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<WordlistGeneratorComponent, "wordlist-generator", never, { "
|
|
43
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<WordlistGeneratorComponent, "wordlist-generator", never, { "buttonBackgroundColor": "buttonBackgroundColor"; "buttonTextColor": "buttonTextColor"; "textColor": "textColor"; }, {}, never, never>;
|
|
43
44
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tehw0lf/wordlist-generator",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://github.com/tehw0lf/tehwol.fi.git",
|
|
6
6
|
"repository": {
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
"url": "https://github.com/tehw0lf/tehwol.fi.git"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
+
"@angular/animations": "^13.1.0",
|
|
12
|
+
"@angular/cdk": "^13.1.0",
|
|
11
13
|
"@angular/common": "^13.1.0",
|
|
12
14
|
"@angular/core": "^13.1.0",
|
|
13
|
-
"@angular/cdk": "^13.1.0",
|
|
14
15
|
"@angular/forms": "^13.1.0",
|
|
15
16
|
"@angular/material": "^13.1.0",
|
|
16
|
-
"@angular/platform-browser": "
|
|
17
|
+
"@angular/platform-browser": "13.1.0",
|
|
17
18
|
"rxjs": "~7.4.0",
|
|
18
19
|
"cartesian-product-generator": "^1.1.1",
|
|
19
20
|
"@angular/platform-browser-dynamic": "13.1.0"
|
|
@@ -21,6 +22,10 @@
|
|
|
21
22
|
"dependencies": {
|
|
22
23
|
"tslib": "^2.2.0"
|
|
23
24
|
},
|
|
25
|
+
"schematics": "./schematics/collection.json",
|
|
26
|
+
"ng-add": {
|
|
27
|
+
"save": "dependencies"
|
|
28
|
+
},
|
|
24
29
|
"module": "fesm2015/tehw0lf-wordlist-generator.mjs",
|
|
25
30
|
"es2020": "fesm2020/tehw0lf-wordlist-generator.mjs",
|
|
26
31
|
"esm2020": "esm2020/tehw0lf-wordlist-generator.mjs",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
|
|
3
|
+
"schematics": {
|
|
4
|
+
"ng-add": {
|
|
5
|
+
"description": "Add wordlist-generator library to the project if material is installed.",
|
|
6
|
+
"factory": "./ng-add/index",
|
|
7
|
+
"schema": "./ng-add/schema.json"
|
|
8
|
+
},
|
|
9
|
+
"ng-add-setup": {
|
|
10
|
+
"description": "Install dependencies and add the library to the project",
|
|
11
|
+
"private": true,
|
|
12
|
+
"factory": "./ng-add/setup",
|
|
13
|
+
"schema": "./ng-add/schema.json"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
13
|
+
const schematics_1 = require("@angular/cdk/schematics");
|
|
14
|
+
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
15
|
+
const workspace_models_1 = require("@schematics/angular/utility/workspace-models");
|
|
16
|
+
const package_config_1 = require("./package-config");
|
|
17
|
+
function default_1(options) {
|
|
18
|
+
return (host, context) => __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const materialVersion = (0, package_config_1.getPackageVersionFromPackageJson)(host, '@angular/material');
|
|
20
|
+
const workspace = yield (0, workspace_1.getWorkspace)(host);
|
|
21
|
+
const project = (0, schematics_1.getProjectFromWorkspace)(workspace, options.project);
|
|
22
|
+
if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
|
|
23
|
+
context.logger.error('This library needs to be added to an application project');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!materialVersion) {
|
|
27
|
+
context.logger.error(`@angular/material not found.
|
|
28
|
+
Please run 'ng add @angular/material' first`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
context.addTask(new tasks_1.RunSchematicTask('ng-add-setup', options));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.default = default_1;
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/wordlist-generator/schematics/ng-add/index.ts"],"names":[],"mappings":";;;;;;;;;;;AACA,4DAAoE;AACpE,wDAAkE;AAClE,qEAAqE;AACrE,mFAA2E;AAE3E,qDAAoE;AAGpE,mBAAyB,OAAe;IACtC,OAAO,CAAO,IAAU,EAAE,OAAyB,EAAE,EAAE;QACrD,MAAM,eAAe,GAAG,IAAA,iDAAgC,EACtD,IAAI,EACJ,mBAAmB,CACpB,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAY,EAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAA,oCAAuB,EAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAEpE,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,KAAK,8BAAW,CAAC,WAAW,EAAE;YAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0DAA0D,CAC3D,CAAC;YACF,OAAO;SACR;QAED,IAAI,CAAC,eAAe,EAAE;YACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;mDACwB,CAAC,CAAC;YAC/C,OAAO;SACR;QAED,OAAO,CAAC,OAAO,CAAC,IAAI,wBAAgB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IACjE,CAAC,CAAA,CAAC;AACJ,CAAC;AAxBD,4BAwBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const testing_1 = require("@angular-devkit/schematics/testing");
|
|
13
|
+
const file_content_1 = require("../testing/file-content");
|
|
14
|
+
const test_app_1 = require("../testing/test-app");
|
|
15
|
+
const test_library_1 = require("../testing/test-library");
|
|
16
|
+
describe('ng-add-setup schematic with material present', () => {
|
|
17
|
+
let runner;
|
|
18
|
+
let appTree;
|
|
19
|
+
let errorOutput;
|
|
20
|
+
let warnOutput;
|
|
21
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
runner = new testing_1.SchematicTestRunner('schematics', require.resolve('../collection.json'));
|
|
23
|
+
appTree = yield (0, test_app_1.createTestAppWithMaterial)(runner);
|
|
24
|
+
errorOutput = [];
|
|
25
|
+
warnOutput = [];
|
|
26
|
+
runner.logger.subscribe((e) => {
|
|
27
|
+
if (e.level === 'error') {
|
|
28
|
+
errorOutput.push(e.message);
|
|
29
|
+
}
|
|
30
|
+
else if (e.level === 'warn') {
|
|
31
|
+
warnOutput.push(e.message);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}));
|
|
35
|
+
describe('add module', () => {
|
|
36
|
+
it('should add the WordlistGeneratorModule to the project module', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
const tree = yield runner
|
|
38
|
+
.runSchematicAsync('ng-add-setup', {}, appTree)
|
|
39
|
+
.toPromise();
|
|
40
|
+
const fileContent = (0, file_content_1.getFileContent)(tree, '/projects/material/src/app/app.module.ts');
|
|
41
|
+
expect(fileContent).toContain('WordlistGeneratorModule');
|
|
42
|
+
}));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe('ng-add schematic without material present', () => {
|
|
46
|
+
let runner;
|
|
47
|
+
let appTree;
|
|
48
|
+
let errorOutput;
|
|
49
|
+
let warnOutput;
|
|
50
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
runner = new testing_1.SchematicTestRunner('schematics', require.resolve('../collection.json'));
|
|
52
|
+
appTree = yield (0, test_app_1.createTestApp)(runner);
|
|
53
|
+
errorOutput = [];
|
|
54
|
+
warnOutput = [];
|
|
55
|
+
runner.logger.subscribe((e) => {
|
|
56
|
+
if (e.level === 'error') {
|
|
57
|
+
errorOutput.push(e.message);
|
|
58
|
+
}
|
|
59
|
+
else if (e.level === 'warn') {
|
|
60
|
+
warnOutput.push(e.message);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}));
|
|
64
|
+
describe('fail to add module', () => {
|
|
65
|
+
it('should fail if material is missing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
const tree = yield runner
|
|
67
|
+
.runSchematicAsync('ng-add', {}, appTree)
|
|
68
|
+
.toPromise();
|
|
69
|
+
const fileContent = (0, file_content_1.getFileContent)(tree, '/projects/material/src/app/app.module.ts');
|
|
70
|
+
expect(fileContent).not.toContain('WordlistGeneratorModule');
|
|
71
|
+
expect(errorOutput.length).toBe(1);
|
|
72
|
+
expect(warnOutput.length).toBe(0);
|
|
73
|
+
expect(errorOutput[0]).toMatch(`@angular/material not found.
|
|
74
|
+
Please run 'ng add @angular/material' first`);
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe('ng-add schematic - library project', () => {
|
|
79
|
+
let runner;
|
|
80
|
+
let libraryTree;
|
|
81
|
+
let errorOutput;
|
|
82
|
+
let warnOutput;
|
|
83
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
runner = new testing_1.SchematicTestRunner('schematics', require.resolve('../collection.json'));
|
|
85
|
+
libraryTree = yield (0, test_library_1.createTestLibrary)(runner);
|
|
86
|
+
errorOutput = [];
|
|
87
|
+
warnOutput = [];
|
|
88
|
+
runner.logger.subscribe((e) => {
|
|
89
|
+
if (e.level === 'error') {
|
|
90
|
+
errorOutput.push(e.message);
|
|
91
|
+
}
|
|
92
|
+
else if (e.level === 'warn') {
|
|
93
|
+
warnOutput.push(e.message);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}));
|
|
97
|
+
it('should do nothing if a library project is targeted', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
+
yield runner.runSchematicAsync('ng-add', {}, libraryTree).toPromise();
|
|
99
|
+
expect(errorOutput.length).toBe(1);
|
|
100
|
+
expect(errorOutput[0]).toMatch('This library needs to be added to an application project');
|
|
101
|
+
}));
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=index.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../../../../libs/wordlist-generator/schematics/ng-add/index.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
9
|
+
/** Adds a package to the package.json in the given host tree. */
|
|
10
|
+
export declare function addPackageToPackageJson(host: Tree, pkg: string, version: string): Tree;
|
|
11
|
+
/** Gets the version of the specified package by looking at the package.json in the given tree. */
|
|
12
|
+
export declare function getPackageVersionFromPackageJson(tree: Tree, name: string): string | null;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPackageVersionFromPackageJson = exports.addPackageToPackageJson = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Sorts the keys of the given object.
|
|
6
|
+
* @returns A new object instance with sorted keys
|
|
7
|
+
*/
|
|
8
|
+
function sortObjectByKeys(obj) {
|
|
9
|
+
return Object.keys(obj)
|
|
10
|
+
.sort()
|
|
11
|
+
.reduce((result, key) => {
|
|
12
|
+
result[key] = obj[key];
|
|
13
|
+
return result;
|
|
14
|
+
}, {});
|
|
15
|
+
}
|
|
16
|
+
/** Adds a package to the package.json in the given host tree. */
|
|
17
|
+
function addPackageToPackageJson(host, pkg, version) {
|
|
18
|
+
if (host.exists('package.json')) {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20
|
+
const sourceText = host.read('package.json').toString('utf-8');
|
|
21
|
+
const json = JSON.parse(sourceText);
|
|
22
|
+
if (!json.dependencies) {
|
|
23
|
+
json.dependencies = {};
|
|
24
|
+
}
|
|
25
|
+
if (!json.dependencies[pkg]) {
|
|
26
|
+
json.dependencies[pkg] = version;
|
|
27
|
+
json.dependencies = sortObjectByKeys(json.dependencies);
|
|
28
|
+
}
|
|
29
|
+
host.overwrite('package.json', JSON.stringify(json, null, 2));
|
|
30
|
+
}
|
|
31
|
+
return host;
|
|
32
|
+
}
|
|
33
|
+
exports.addPackageToPackageJson = addPackageToPackageJson;
|
|
34
|
+
/** Gets the version of the specified package by looking at the package.json in the given tree. */
|
|
35
|
+
function getPackageVersionFromPackageJson(tree, name) {
|
|
36
|
+
if (!tree.exists('package.json')) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const packageJson = JSON.parse(
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
41
|
+
tree.read('package.json').toString('utf8'));
|
|
42
|
+
if (packageJson.dependencies && packageJson.dependencies[name]) {
|
|
43
|
+
return packageJson.dependencies[name];
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
exports.getPackageVersionFromPackageJson = getPackageVersionFromPackageJson;
|
|
48
|
+
//# sourceMappingURL=package-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-config.js","sourceRoot":"","sources":["../../../../../libs/wordlist-generator/schematics/ng-add/package-config.ts"],"names":[],"mappings":";;;AAaA;;;GAGG;AACH,SAAS,gBAAgB,CAAC,GAA2B;IACnD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAA4B,CAAC,CAAC;AACrC,CAAC;AAED,iEAAiE;AACjE,SAAgB,uBAAuB,CACrC,IAAU,EACV,GAAW,EACX,OAAe;IAEf,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;QAC/B,oEAAoE;QACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAgB,CAAC;QAEnD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;SACxB;QAED,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;YAC3B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SACzD;QAED,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;KAC/D;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAvBD,0DAuBC;AAED,kGAAkG;AAClG,SAAgB,gCAAgC,CAC9C,IAAU,EACV,IAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;QAChC,OAAO,IAAI,CAAC;KACb;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK;IAC5B,oEAAoE;IACpE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC7B,CAAC;IAEjB,IAAI,WAAW,CAAC,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;QAC9D,OAAO,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;KACvC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAlBD,4EAkBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../../libs/wordlist-generator/schematics/ng-add/schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema",
|
|
3
|
+
"$id": "angular-material-ng-add",
|
|
4
|
+
"title": "Angular Material ng-add schematic",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Name of the project.",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"required": []
|
|
16
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
13
|
+
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
14
|
+
const schematics_2 = require("@angular/cdk/schematics");
|
|
15
|
+
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
16
|
+
const package_config_1 = require("./package-config");
|
|
17
|
+
const wordlistGeneratorModuleName = 'WordlistGeneratorModule';
|
|
18
|
+
const wordlistGeneratorPackageName = '@tehw0lf/wordlist-generator';
|
|
19
|
+
const flexLayoutFallbackVersion = '^13.0.0-beta.36';
|
|
20
|
+
function default_1(options) {
|
|
21
|
+
return () => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return (0, schematics_1.chain)([addDependencies(), addWordlistGeneratorModule(options)]);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.default = default_1;
|
|
26
|
+
function addWordlistGeneratorModule(options) {
|
|
27
|
+
return (host, context) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const workspace = yield (0, workspace_1.getWorkspace)(host);
|
|
29
|
+
const project = (0, schematics_2.getProjectFromWorkspace)(workspace, options.project);
|
|
30
|
+
const appModulePath = (0, schematics_2.getAppModulePath)(host, (0, schematics_2.getProjectMainFile)(project));
|
|
31
|
+
if (!(0, schematics_2.hasNgModuleImport)(host, appModulePath, wordlistGeneratorModuleName)) {
|
|
32
|
+
(0, schematics_2.addModuleImportToRootModule)(host, wordlistGeneratorModuleName, wordlistGeneratorPackageName, project);
|
|
33
|
+
}
|
|
34
|
+
context.logger.warn('Library is already installed, nothing to do.');
|
|
35
|
+
return;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function addDependencies() {
|
|
39
|
+
return (host, context) => __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const flexLayoutVersion = (0, package_config_1.getPackageVersionFromPackageJson)(host, '@angular/flex-layout');
|
|
41
|
+
if (!flexLayoutVersion || flexLayoutVersion !== flexLayoutFallbackVersion) {
|
|
42
|
+
(0, package_config_1.addPackageToPackageJson)(host, '@angular/flex-layout', flexLayoutFallbackVersion);
|
|
43
|
+
context.logger.info(`@angular/flex-layout ${flexLayoutFallbackVersion} was added to dependencies.`);
|
|
44
|
+
}
|
|
45
|
+
context.addTask(new tasks_1.NodePackageInstallTask());
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../../libs/wordlist-generator/schematics/ng-add/setup.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,2DAAiF;AACjF,4DAA0E;AAC1E,wDAMiC;AACjC,qEAAqE;AAErE,qDAA6F;AAG7F,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AAC9D,MAAM,4BAA4B,GAAG,6BAA6B,CAAC;AACnE,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAEpD,mBAAyB,OAAe;IACtC,OAAO,GAAS,EAAE;QAChB,OAAO,IAAA,kBAAK,EAAC,CAAC,eAAe,EAAE,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC,CAAA,CAAC;AACJ,CAAC;AAJD,4BAIC;AAED,SAAS,0BAA0B,CAAC,OAAe;IACjD,OAAO,CAAO,IAAU,EAAE,OAAyB,EAAE,EAAE;QACrD,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAY,EAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAA,oCAAuB,EAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACpE,MAAM,aAAa,GAAG,IAAA,6BAAgB,EAAC,IAAI,EAAE,IAAA,+BAAkB,EAAC,OAAO,CAAC,CAAC,CAAC;QAE1E,IAAI,CAAC,IAAA,8BAAiB,EAAC,IAAI,EAAE,aAAa,EAAE,2BAA2B,CAAC,EAAE;YACxE,IAAA,wCAA2B,EACzB,IAAI,EACJ,2BAA2B,EAC3B,4BAA4B,EAC5B,OAAO,CACR,CAAC;SACH;QACD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QACpE,OAAO;IACT,CAAC,CAAA,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,CAAO,IAAU,EAAE,OAAyB,EAAE,EAAE;QACrD,MAAM,iBAAiB,GAAG,IAAA,iDAAgC,EACxD,IAAI,EACJ,sBAAsB,CACvB,CAAC;QAEF,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,KAAK,yBAAyB,EAAE;YACzE,IAAA,wCAAuB,EACrB,IAAI,EACJ,sBAAsB,EACtB,yBAAyB,CAC1B,CAAC;YAEF,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,wBAAwB,yBAAyB,6BAA6B,CAC/E,CAAC;SACH;QACD,OAAO,CAAC,OAAO,CAAC,IAAI,8BAAsB,EAAE,CAAC,CAAC;IAChD,CAAC,CAAA,CAAC;AACJ,CAAC"}
|