diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..5a19e8a
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+node_modules
+dist
+coverage
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..d679ba6
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,10 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint", "jest"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:jest/recommended"
+ ]
+}
diff --git a/.github/workflows/pr-devops.yml b/.github/workflows/pr-devops.yml
new file mode 100644
index 0000000..e2de146
--- /dev/null
+++ b/.github/workflows/pr-devops.yml
@@ -0,0 +1,21 @@
+name: Run Unit Tests
+
+on:
+ pull_request:
+ branches: [ main ]
+ workflow_dispatch:
+jobs:
+ DevOpsPRUnitTests:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Login to DockerHub Registry
+ run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
+ - name: Build Private Dependencies And Test
+ run: |
+ sudo apt install -y jq
+ echo "//npm.pkg.github.com/:_authToken=${{ secrets.GitHubToken }}" >> ~/.npmrc
+ npm install
+ npm run build
+ npm test -- -u
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fbf86d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+dist
+lib
+.env
+.DS_Store
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..15909e2
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,8 @@
+.vscode
+node_modules
+.env
+.idea
+lib
+build
+package-lock.json
+yarn-lock
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..e6936ab
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "printWidth": 120,
+ "trailingComma": "all",
+ "singleQuote": true,
+ "tabWidth": 2
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..982c261
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+ "terminal.integrated.shellArgs.linux": [
+ "-i"
+ ],
+ "terminal.integrated.shellArgs.windows": [
+ "-NoProfile"
+ ]
+}
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..dce86d2
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-present Pagar.me Pagamentos S/A
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e6c73c4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,102 @@
+# Razzle
+Razzle is an extensible, easy to understand, easy contribute, easy to use Codemod library. Razzle-dazzle your codebase like you've never before.
+
+# Novelty behind Razzle library
+
+What the Razzle library does that is unique, is that it creates a unified interface across different programming languages. It uses a simple object to make modifications. e.g.
+
+### Typescript
+```
+{
+ "import": '{ NgModule }',
+ "path": '@angular/core'
+}
+```
+
+### SCSS
+```
+{
+ "import": '',
+ "path": 'libs/common/styles/razroo-styles.scss'
+}
+```
+
+## Assumption Made
+Razzle is always used in an editing circumstance. There is no need to speicify that file is being editied. Razzle will update the string
+
+## Benefits of such
+1. This will be consumer facing. By allowing a singular object, we can simplify the frontend shown to users in the content management system.
+2. Developers don't have to dig into specifics for each programming language. They can simply keep an eye on the top level interface.
+
+# Further reading via Razroo blog(soon to be it's own documentation site)
+
+blog.razroo.com
+
+
+# APIS Available
+
+## Typescript
+
+1. `import`
+2. `editImport`
+3. `classDeclaration`
+4. `classMethod`
+5. `addNgModuleImport`
+6. `addNgModuleProvider`
+7. `addNgModuleImportToSpec`
+8. `addToVariableObject`
+9. `addConstructorMethod`
+```
+{
+ nodeType: 'addConstructorMethod',
+ codeBlock: 'userService',
+ type: 'UserService'
+}
+```
+10. addVariableDeclarationStatement
+```
+{
+ nodeType: 'addVariableDeclarationStatement',
+ codeBlock: 'gtag',
+ type: 'Function'
+}
+```
+
+## JSON
+
+1. `editJson`
+2. `addJsonKeyValue`
+
+## SCSS
+
+1. `addScssBlock`
+2. `import`
+
+
+## Angular HTML + HTML
+
+1. `editHtmlTag`
+```
+{
+ "nodeType": "editHtmlTag",
+ "codeBlock": "matSort",
+ "tagNameToModify": "mat-table"
+}
+```
+2. `addSiblingHtml`
+```
+{
+ "nodeType": "addSiblingHtml",
+ "codeBlock": "",
+ "tagNameToInsert": "script",
+ "siblingTagName": "link"
+},
+```
+3. `insertIntoHtmlTag`
+```
+{
+ "nodeType": "insertIntoHtmlTag",
+ "codeBlock": "
",
+ "tagNameToInsertInto": "mat-toolbar"
+}
+```
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..beeab6b
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,15 @@
+module.exports = {
+ preset: 'ts-jest/presets/default-esm',
+ testEnvironment: 'node',
+ transform: {
+ '^.+\\.(t|j)s$': 'ts-jest'
+ },
+ globals: {
+ 'ts-jest': {
+ diagnostics: false,
+ useESM: true
+ }
+ },
+ testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(t|j)s$',
+ moduleFileExtensions: ['ts', 'js', 'json', 'node'],
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..cafc129
--- /dev/null
+++ b/package.json
@@ -0,0 +1,99 @@
+{
+ "name": "@razroo/razzle",
+ "version": "1.0.0",
+ "description": "Razzle is an extensible, easy to understand, easy contribute, easy to use Codemod library.",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "build": "tsc",
+ "format": "prettier --write \"src/**/*.(js|ts)\"",
+ "lint": "eslint src --ext .js,.ts",
+ "lint:fix": "eslint src --fix --ext .js,.ts",
+ "test": "jest --config jest.config.js",
+ "publish": "npm publish"
+ },
+ "publishConfig": {
+ "registry": "https://npm.pkg.github.com"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/razroo/razzle"
+ },
+ "keywords": [
+ "razroo",
+ "codemod"
+ ],
+ "author": "Razroo",
+ "license": "RAZROO",
+ "bugs": {
+ "url": "https://github.com/razroo/razzle/issues"
+ },
+ "homepage": "https://github.com/razroo/razzle#readme",
+ "devDependencies": {
+ "@angular-devkit/build-angular": "~13.0.0",
+ "@angular-devkit/build-optimizer": "~0.1300.0",
+ "@angular-devkit/build-webpack": "~0.1300.0",
+ "@angular-devkit/schematics": "~13.0.0",
+ "@angular-eslint/eslint-plugin": "~13.0.1",
+ "@angular-eslint/eslint-plugin-template": "~13.0.1",
+ "@angular-eslint/template-parser": "~13.0.1",
+ "@angular/cli": "~13.0.0",
+ "@angular/common": "^13.0.0",
+ "@angular/compiler": "^13.0.0",
+ "@angular/compiler-cli": "^13.0.0",
+ "@angular/core": "^13.0.0",
+ "@angular/forms": "^13.0.0",
+ "@angular/platform-browser": "^13.0.0",
+ "@angular/platform-browser-dynamic": "^13.0.0",
+ "@angular/router": "^13.0.0",
+ "@angular/service-worker": "^13.0.0",
+ "@angular/upgrade": "^13.0.0",
+ "@angular-devkit/architect": "~0.1300.0",
+ "@angular-devkit/core": "~13.0.0",
+ "@types/jest": "^27.5.2",
+ "@types/tinycolor2": "^1.4.3",
+ "@typescript-eslint/eslint-plugin": "^4.5.0",
+ "@typescript-eslint/parser": "^4.5.0",
+ "babel-jest": "^27.4.6",
+ "eslint": "^7.11.0",
+ "eslint-plugin-jest": "^24.1.0",
+ "jest": "^27.0.7",
+ "ts-jest": "^27.1.5",
+ "tsup": "^6.2.3",
+ "typescript": "^4.0.3",
+ "yargs-parser": "20.0.0"
+ },
+ "dependencies": {
+ "@ctrl/tinycolor": "^3.4.1",
+ "chalk": "4.1.0",
+ "ejs": "^3.1.5",
+ "enquirer": "~2.3.6",
+ "fast-glob": "3.2.7",
+ "glob": "^8.0.3",
+ "hast-util-from-parse5": "6.0.1",
+ "hast-util-to-html": "7.1.3",
+ "ignore": "^5.0.4",
+ "json-pointer": "^0.6.2",
+ "json-to-ast": "^2.1.0",
+ "jsonc-parser": "3.0.0",
+ "jsonpath-plus": "^6.0.1",
+ "parse5": "^6.0.1",
+ "path": "^0.12.7",
+ "prettier": "^2.3.0",
+ "query-ast": "^1.0.4",
+ "rxjs": "^6.5.4",
+ "rxjs-for-await": "0.0.2",
+ "scss-parser": "^1.0.5",
+ "semver": "7.3.4",
+ "tmp": "~0.2.1",
+ "to-vfile": "^7.2.3",
+ "ts-morph": "^15.1.0",
+ "tslib": "^2.3.0",
+ "unist-util-visit": "2.0.3",
+ "unist-util-visit-parents": "3.1.1",
+ "yargs-parser": "20.0.0"
+ },
+ "files": [
+ "dist/**/*"
+ ]
+}
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..eaec4b8
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,27 @@
+// color related items
+export { getPalette, createColorVariables } from './rz/global-variables';
+
+// export { Blah as default } from './lib'
+export { replaceTagParameters, replaceCurlyBrace } from './replace';
+
+// general utils
+export { getVersionAndNameString, determineType, determineFilePathParameter, readPackageJson, extractProjectName,
+ getAllDirectoriesFromVsCodeFolder, getProjectDependencies, determineLanguagesUsed, replaceCodeModEditsTemplateVariables } from './rz/utils';
+
+// export typescript related edits
+export { EditInput, EditFile, morphCode, effects, communityPaths, types } from './rz/morph';
+
+// export typescript related edits
+export { getCodeModParams, getCodeModOptions } from './rz/params';
+
+// global variables
+export { names, codeCmsVariablesToIgnore, powerUpVariables, powerUpVariablesFlatData } from './rz/global-variables';
+
+// global variables interfaces
+export { CodeCmsVariablesToIgnore, PowerUpVariables } from './rz/global-variables/interfaces';
+
+// types for angular code generation side-effects
+export { angularTypes, AngularTypeNames, defaultAngularTechnologies } from './rz/angular';
+
+// types react code generation side-effects
+export { reactTypes, ReactTypeNames } from './rz/react';
\ No newline at end of file
diff --git a/src/replace.spec.ts b/src/replace.spec.ts
new file mode 100644
index 0000000..7facb55
--- /dev/null
+++ b/src/replace.spec.ts
@@ -0,0 +1,37 @@
+import { replaceCurlyBrace } from './replace';
+
+describe('replaceCurlyBrace', () => {
+ it('should replaceCurlyBrace with respective parameters', () => {
+ const mockParameters = {
+ name: 'test',
+ selector: 'test-two',
+ className: ''
+ };
+ const mockFileStringWithCurlyBrace = 'src/{selector}/{name}.component.html';
+
+ const result = replaceCurlyBrace(mockParameters, mockFileStringWithCurlyBrace);
+ const expected = 'src/test-two/test.component.html';
+
+ expect(result).toEqual(expected);
+ });
+
+ it('should replace with curly braces if curly brace values shows up more than once', () => {
+ const mockParameters = {
+ nameFilePath:"libs/common/ui/src/lib/{name}-dialog",
+ name:"blue",
+ projectName:"razroo-angular-starter",
+ className:"Blue",
+ propertyName:"blue",
+ constantName:"BLUE",
+ fileName:"blue",
+ titleName:"Blue"
+ };
+ const mockFileStringWithCurlyBrace = '{nameFilePath}/{name}-dialog.component.ts';
+
+ const result = replaceCurlyBrace(mockParameters, mockFileStringWithCurlyBrace);
+ const expected = 'libs/common/ui/src/lib/blue-dialog/blue-dialog.component.ts';
+
+ expect(result).toEqual(expected);
+ })
+
+});
\ No newline at end of file
diff --git a/src/replace.ts b/src/replace.ts
new file mode 100644
index 0000000..2c64d24
--- /dev/null
+++ b/src/replace.ts
@@ -0,0 +1,19 @@
+export const replaceTagParameters = (
+ parameters: Record,
+ toReplace: string
+ ): string => {
+ for (const [key, value] of Object.entries(parameters)) {
+ const keyString = `<%= ${key} %>`;
+ const keyStringRegex = new RegExp(keyString, 'g');
+ toReplace = toReplace.replace(keyStringRegex, value);
+ }
+ return toReplace;
+ };
+
+ export const replaceCurlyBrace = (mockParameters: object, mockFileStringWithCurlyBrace: string): string => {
+ let result = mockFileStringWithCurlyBrace;
+ for(let key in mockParameters) {
+ result = result.replaceAll('{' + key + '}', mockParameters[key]);
+ }
+ return result;
+}
\ No newline at end of file
diff --git a/src/rz/angular/add-sibling-html.ts b/src/rz/angular/add-sibling-html.ts
new file mode 100644
index 0000000..12ecebe
--- /dev/null
+++ b/src/rz/angular/add-sibling-html.ts
@@ -0,0 +1,22 @@
+import visitParents = require('unist-util-visit-parents');
+import visit = require('unist-util-visit');
+import { createUnifiedTree } from './morph-angular-html';
+import { EditHtmlFile } from './interfaces/edit-html.interface';
+
+// takes html tree of code we want to insert
+// and combines with html tree we want to insert into
+function combineTrees(fileToModifyTree: any, codeToAddTree: any, tagNameToInsert: string, siblingTagName: string ) {
+ visit(codeToAddTree, {type: 'element', tagName: tagNameToInsert}, (matPaginator: any) => {
+ visitParents(fileToModifyTree, {type: 'element', tagName: siblingTagName}, (_node, ancestors) => {
+ (ancestors[ancestors.length -1] as any).children.push(matPaginator);
+ });
+ });
+ return fileToModifyTree;
+}
+
+ // this is a unique function
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function insertCodeAfterElement(editFile: EditHtmlFile, fileToBeAddedToTree: any): any {
+ const stringToAddTree = createUnifiedTree(editFile.codeBlock as string);
+ return combineTrees(fileToBeAddedToTree, stringToAddTree, editFile.tagNameToInsert, editFile.siblingTagName);
+}
\ No newline at end of file
diff --git a/src/rz/angular/angular-effects.ts b/src/rz/angular/angular-effects.ts
new file mode 100644
index 0000000..2210943
--- /dev/null
+++ b/src/rz/angular/angular-effects.ts
@@ -0,0 +1,39 @@
+import { Parameters } from "../morph";
+import { addClassToDeclarationsAndImports } from "./effects/component/component-effects";
+import { exportGraphqlFile } from "./effects/graphql/graphql";
+import { exportInterfaceFile } from "./effects/interface/interface";
+import { addEffectToNgModule } from "./effects/ngrx/effects/ngrx-effects";
+import { addFacadeToNgModule } from "./effects/ngrx/facade/ngrx-facade";
+import { addReducerToNgModule } from "./effects/ngrx/reducer/ngrx-reducer";
+import { exportServiceFile } from "./effects/service/service";
+import { exportComponentFile } from "./effects/standalone-component/standalone-component";
+import { AngularType, AngularTypeNames, AngularOptionalType } from "./types/types";
+
+export function angularEffects(filePathWithName: string, type: AngularTypeNames, parameters: Parameters, optionalTypes: AngularOptionalType[]): void {
+ switch (type) {
+ case AngularTypeNames.Component:
+ addClassToDeclarationsAndImports(filePathWithName, parameters.className, optionalTypes);
+ break;
+ case AngularTypeNames.StandaloneComponent:
+ exportComponentFile(filePathWithName)
+ break;
+ case AngularTypeNames.Service:
+ exportServiceFile(filePathWithName);
+ break;
+ case AngularTypeNames.Interface:
+ exportInterfaceFile(filePathWithName)
+ break;
+ case AngularTypeNames.Graphql:
+ exportGraphqlFile(filePathWithName)
+ break;
+ case AngularTypeNames.NgrxEffects:
+ addEffectToNgModule(filePathWithName, parameters.className)
+ break;
+ case AngularTypeNames.NgrxFacade:
+ addFacadeToNgModule(filePathWithName, parameters.className)
+ break;
+ case AngularTypeNames.NgrxReducer:
+ addReducerToNgModule(filePathWithName, parameters.className, parameters.constantName)
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/component/component-effects.spec.ts b/src/rz/angular/effects/component/component-effects.spec.ts
new file mode 100644
index 0000000..419c181
--- /dev/null
+++ b/src/rz/angular/effects/component/component-effects.spec.ts
@@ -0,0 +1,35 @@
+import { readFileSync, writeFileSync } from 'fs';
+import { TemplateInputParameter } from '../../../utils/interfaces/template-parameters';
+import { effects, Parameters } from "../../../morph";
+
+describe('Angular Component Effects', () => {
+ afterEach(() => {
+ const moduleOriginal = readFileSync('src/rz/angular/effects/component/snapshots/module-original.ts.snap').toString();
+ writeFileSync('src/rz/angular/effects/component/index.ts', '');
+ writeFileSync('src/rz/angular/effects/component/sample.module.ts', moduleOriginal);
+ });
+ it('should update the closest app module file with an ngmodule export, declaration, import component, and export via optional type', () => {
+ const mockFilePath = 'src/rz/angular/effects/component/sample.component.ts';
+ const parameters: Parameters = {
+ className: 'Sample'
+ };
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: 'component'
+ }
+ effects(mockFilePath, mockTemplateInputParameter, 'angular', JSON.stringify(parameters));
+
+ const indexResult = readFileSync('src/rz/angular/effects/component/index.ts').toString();
+ const indexExpected = readFileSync('src/rz/angular/effects/component/snapshots/index-output.ts.snap').toString();
+ expect(indexResult).toEqual(indexExpected);
+
+ const moduleResult = readFileSync('src/rz/angular/effects/component/sample.module.ts').toString();
+ const moduleExpected = readFileSync('src/rz/angular/effects/component/snapshots/module-output.ts.snap').toString();
+ expect(moduleResult).toEqual(moduleExpected);
+ })
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/component/component-effects.ts b/src/rz/angular/effects/component/component-effects.ts
new file mode 100644
index 0000000..09c4385
--- /dev/null
+++ b/src/rz/angular/effects/component/component-effects.ts
@@ -0,0 +1,47 @@
+import { EditInput } from 'src/rz/morph/interfaces/morph.interface';
+import { readFileSync, writeFileSync } from 'fs';
+import { findClosestModuleFile } from "../../../utils";
+import { createRelativePath, exportTsFiles, isTsFile } from "../../../utils/add-export";
+import { morphTypescript } from '../../../typescript/morph-typescript';
+import { GlobalAngularOptionNames, AngularOptionalType } from '../../types/types';
+import { names } from '../../../global-variables';
+
+export function addClassToDeclarationsAndImports(filePathWithName: string, className: string, optionalTypes: AngularOptionalType[]): void {
+ if(isTsFile(filePathWithName)) {
+ const moduleTsFile = findClosestModuleFile(filePathWithName);
+ const componentFileName = filePathWithName.split('/').pop();
+ const componentName = componentFileName.split('.')[0];
+ const componentClassName = `${names(componentName).className}Component`;
+ const importPath = createRelativePath(filePathWithName, moduleTsFile);
+ const fileName = moduleTsFile.split('/').pop();
+ const fileToBeAddedTo = readFileSync(moduleTsFile, 'utf-8').toString();
+ // const componentName = `${className}Component`;
+ const editInput: EditInput = {
+ fileType: 'ts',
+ fileName: fileName,
+ filePath: moduleTsFile,
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'addNgModuleExport',
+ codeBlock: componentClassName,
+ },
+ {
+ nodeType: 'addNgModuleDeclaration',
+ codeBlock: componentClassName,
+ },
+ {
+ nodeType: 'import',
+ codeBlock: `{ ${componentClassName} }`,
+ path: importPath,
+ }
+ ]
+ };
+ if(optionalTypes?.find(option => option.name === GlobalAngularOptionNames.IsExported).selected){
+ exportTsFiles(filePathWithName);
+ }
+ const updatedFileToBeAddedTo = morphTypescript(editInput);
+ // TODO extract write file logic from morphCode logic
+ writeFileSync(moduleTsFile, updatedFileToBeAddedTo);
+ }
+ }
\ No newline at end of file
diff --git a/src/rz/angular/effects/component/index.ts b/src/rz/angular/effects/component/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/effects/component/sample.module.ts b/src/rz/angular/effects/component/sample.module.ts
new file mode 100644
index 0000000..de31813
--- /dev/null
+++ b/src/rz/angular/effects/component/sample.module.ts
@@ -0,0 +1,7 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [CommonModule],
+})
+export class CommonUiModule {}
diff --git a/src/rz/angular/effects/component/snapshots/index-output.ts.snap b/src/rz/angular/effects/component/snapshots/index-output.ts.snap
new file mode 100644
index 0000000..7f06fa2
--- /dev/null
+++ b/src/rz/angular/effects/component/snapshots/index-output.ts.snap
@@ -0,0 +1 @@
+export * from "./sample.component";
diff --git a/src/rz/angular/effects/component/snapshots/module-original.ts.snap b/src/rz/angular/effects/component/snapshots/module-original.ts.snap
new file mode 100644
index 0000000..de31813
--- /dev/null
+++ b/src/rz/angular/effects/component/snapshots/module-original.ts.snap
@@ -0,0 +1,7 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [CommonModule],
+})
+export class CommonUiModule {}
diff --git a/src/rz/angular/effects/component/snapshots/module-output.ts.snap b/src/rz/angular/effects/component/snapshots/module-output.ts.snap
new file mode 100644
index 0000000..bb9ac1f
--- /dev/null
+++ b/src/rz/angular/effects/component/snapshots/module-output.ts.snap
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { SampleComponent } from "./sample.component";
+
+@NgModule({
+ imports: [CommonModule],
+ exports: [SampleComponent],
+ declarations: [SampleComponent]
+})
+export class CommonUiModule { }
diff --git a/src/rz/angular/effects/graphql/graphql.spec.ts b/src/rz/angular/effects/graphql/graphql.spec.ts
new file mode 100644
index 0000000..4997120
--- /dev/null
+++ b/src/rz/angular/effects/graphql/graphql.spec.ts
@@ -0,0 +1,27 @@
+import { TemplateInputParameter } from './../../../utils/interfaces/template-parameters';
+import { writeFileSync, readFileSync } from 'fs';
+import { effects } from "../../../morph";
+import { AngularTypeNames } from "../../types/types";
+
+describe('exportGraphqlFile', () => {
+ afterEach(() => {
+ writeFileSync('src/rz/angular/effects/graphql/index.ts', '');
+ });
+ it('should export graphql file', () => {
+ const mockFilePath = 'src/rz/angular/effects/graphql/user.mutations.ts';
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.Graphql
+ };
+
+ effects(mockFilePath, mockTemplateInputParameter, 'angular');
+ const result = readFileSync('src/rz/angular/effects/graphql/index.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/graphql/snapshots/index-output.ts.snap').toString();
+ expect(result).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/graphql/graphql.ts b/src/rz/angular/effects/graphql/graphql.ts
new file mode 100644
index 0000000..774f592
--- /dev/null
+++ b/src/rz/angular/effects/graphql/graphql.ts
@@ -0,0 +1,7 @@
+import { exportTsFiles, isTsFile } from "../../../utils/add-export";
+
+export function exportGraphqlFile(filePathWithName: string): void {
+ if (isTsFile(filePathWithName)) {
+ exportTsFiles(filePathWithName);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/graphql/index.ts b/src/rz/angular/effects/graphql/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/effects/graphql/snapshots/index-output.ts.snap b/src/rz/angular/effects/graphql/snapshots/index-output.ts.snap
new file mode 100644
index 0000000..32fe8b9
--- /dev/null
+++ b/src/rz/angular/effects/graphql/snapshots/index-output.ts.snap
@@ -0,0 +1 @@
+export * from "./user.mutations";
diff --git a/src/rz/angular/effects/interface/index.ts b/src/rz/angular/effects/interface/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/effects/interface/interface.spec.ts b/src/rz/angular/effects/interface/interface.spec.ts
new file mode 100644
index 0000000..9fda629
--- /dev/null
+++ b/src/rz/angular/effects/interface/interface.spec.ts
@@ -0,0 +1,26 @@
+import { TemplateInputParameter } from './../../../utils/interfaces/template-parameters';
+import { writeFileSync, readFileSync } from 'fs';
+import { effects } from "../../../morph";
+import { AngularTypeNames } from "../../types/types";
+
+describe('exportInterfaceFile', () => {
+ afterEach(() => {
+ writeFileSync('src/rz/angular/effects/interface/index.ts', '');
+ });
+ it('should export service file', () => {
+ const mockFilePath = 'src/rz/angular/effects/interface/user.interface.ts';
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.Service
+ };
+ effects(mockFilePath, mockTemplateInputParameter, 'angular');
+ const result = readFileSync('src/rz/angular/effects/interface/index.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/interface/snapshots/index-output.ts.snap').toString();
+ expect(result).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/interface/interface.ts b/src/rz/angular/effects/interface/interface.ts
new file mode 100644
index 0000000..49452d2
--- /dev/null
+++ b/src/rz/angular/effects/interface/interface.ts
@@ -0,0 +1,7 @@
+import { exportTsFiles, isTsFile } from "../../../utils/add-export";
+
+export function exportInterfaceFile(filePathWithName: string): void {
+ if (isTsFile(filePathWithName)) {
+ exportTsFiles(filePathWithName);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/interface/snapshots/index-output.ts.snap b/src/rz/angular/effects/interface/snapshots/index-output.ts.snap
new file mode 100644
index 0000000..c17f532
--- /dev/null
+++ b/src/rz/angular/effects/interface/snapshots/index-output.ts.snap
@@ -0,0 +1 @@
+export * from "./user.interface";
diff --git a/src/rz/angular/effects/ngrx/effects/ngrx-effects.spec.ts b/src/rz/angular/effects/ngrx/effects/ngrx-effects.spec.ts
new file mode 100644
index 0000000..d0b2874
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/effects/ngrx-effects.spec.ts
@@ -0,0 +1,32 @@
+import { TemplateInputParameter } from './../../../../utils/interfaces/template-parameters';
+import { AngularTypeNames } from './../../../types/types';
+import { effects, Parameters } from "../../../../../../src/rz/morph";
+import { writeFileSync, readFileSync } from 'fs';
+
+describe('addEffectToNgModule', () => {
+ afterEach(() => {
+ const moduleToUseToReset = readFileSync('src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects.module.ts.snap').toString();
+ writeFileSync('src/rz/angular/effects/ngrx/effects/test.module.ts', moduleToUseToReset);
+ });
+ it('should update the closest app module file with the proper text', () => {
+ const mockFilePath = 'src/rz/angular/effects/ngrx/effects/snapshots/sample.effect.ts';
+ const parameters: Parameters = {
+ className: 'Test'
+ };
+ const parametersString = JSON.stringify(parameters);
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.NgrxEffects
+ }
+ effects(mockFilePath, mockTemplateInputParameter, 'angular', parametersString);
+ const result = readFileSync('src/rz/angular/effects/ngrx/effects/test.module.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects-output.module.ts.snap').toString();
+
+ expect(result).toEqual(expected);
+ })
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/effects/ngrx-effects.ts b/src/rz/angular/effects/ngrx/effects/ngrx-effects.ts
new file mode 100644
index 0000000..488d03f
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/effects/ngrx-effects.ts
@@ -0,0 +1,42 @@
+import { EditInput } from 'src/rz/morph/interfaces/morph.interface';
+import { findClosestModuleFile } from "../../../../utils";
+import { createRelativePath, isTsFile } from "../../../../utils/add-export";
+import { readFileSync, writeFileSync } from 'fs';
+import { morphTypescript } from '../../../../typescript/morph-typescript';
+
+export function addEffectToNgModule(filePathWithName: string, className: string): void {
+ // make sure that spec is not taken
+ if(isTsFile(filePathWithName)) {
+ const moduleTsFile = findClosestModuleFile(filePathWithName);
+ const importPath = createRelativePath(filePathWithName, moduleTsFile);
+ const fileName = moduleTsFile.split('.').pop();
+ const fileToBeAddedTo = readFileSync(moduleTsFile, 'utf-8').toString();
+ const EffectsName = `${className}Effects`;
+ const moduleName = `EffectsModule.forFeature([${EffectsName}])`
+ const editInput: EditInput = {
+ fileType: 'ts',
+ fileName: fileName,
+ filePath: moduleTsFile,
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'import',
+ codeBlock: `{ EffectsModule }`,
+ path: '@ngrx/effects',
+ },
+ {
+ nodeType: 'import',
+ codeBlock: `{ ${EffectsName} }`,
+ path: importPath,
+ },
+ {
+ nodeType: 'addNgModuleImport',
+ codeBlock: moduleName,
+ }
+ ]
+ };
+ const updatedFileToBeAddedTo = morphTypescript(editInput);
+ // TODO extract write file logic from morphCode logic
+ writeFileSync(moduleTsFile, updatedFileToBeAddedTo);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects-output.module.ts.snap b/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects-output.module.ts.snap
new file mode 100644
index 0000000..3c243c6
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects-output.module.ts.snap
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { EffectsModule } from "@ngrx/effects";
+import { TestEffects } from "./snapshots/sample.effect";
+
+@NgModule({
+ imports: [
+ CommonModule,
+ EffectsModule.forFeature([TestEffects])
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule { }
diff --git a/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects.module.ts.snap b/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects.module.ts.snap
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/effects/snapshots/test-ngrx-effects.module.ts.snap
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/ngrx/effects/test.module.ts b/src/rz/angular/effects/ngrx/effects/test.module.ts
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/effects/test.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/ngrx/facade/ngrx-facade.spec.ts b/src/rz/angular/effects/ngrx/facade/ngrx-facade.spec.ts
new file mode 100644
index 0000000..1b3b159
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/facade/ngrx-facade.spec.ts
@@ -0,0 +1,32 @@
+import { TemplateInputParameter } from './../../../../utils/interfaces/template-parameters';
+import { AngularTypeNames } from './../../../types/types';
+import { effects, Parameters } from "../../../../../../src/rz/morph";
+import { writeFileSync, readFileSync } from 'fs';
+
+describe('addFacadeToNgModule', () => {
+ afterEach(() => {
+ const moduleToUseToReset = readFileSync('src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade.module.ts.snap').toString();
+ writeFileSync('src/rz/angular/effects/ngrx/facade/test.module.ts', moduleToUseToReset);
+ });
+ it('should update the closest app module file with ngrx facade codemods', () => {
+ const mockFilePath = 'src/rz/angular/effects/ngrx/facade/snapshots/sample.facade.ts';
+ const parameters: Parameters = {
+ className: 'Test'
+ };
+ const parametersString = JSON.stringify(parameters);
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.NgrxFacade
+ }
+ effects(mockFilePath, mockTemplateInputParameter, 'angular', parametersString);
+ const result = readFileSync('src/rz/angular/effects/ngrx/facade/test.module.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade-output.module.ts.snap').toString();
+
+ expect(result).toEqual(expected);
+ })
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/facade/ngrx-facade.ts b/src/rz/angular/effects/ngrx/facade/ngrx-facade.ts
new file mode 100644
index 0000000..428f66d
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/facade/ngrx-facade.ts
@@ -0,0 +1,36 @@
+import { EditInput } from 'src/rz/morph/interfaces/morph.interface';
+import { findClosestModuleFile } from "../../../../utils";
+import { createRelativePath, isTsFile } from "../../../../utils/add-export";
+import { readFileSync, writeFileSync } from 'fs';
+import { morphTypescript } from '../../../../typescript/morph-typescript';
+
+export function addFacadeToNgModule(filePathWithName: string, className: string): void {
+ // make sure that spec is not taken
+ if(isTsFile(filePathWithName)) {
+ const moduleTsFile = findClosestModuleFile(filePathWithName);
+ const importPath = createRelativePath(filePathWithName, moduleTsFile);
+ const fileName = moduleTsFile.split('.').pop();
+ const fileToBeAddedTo = readFileSync(moduleTsFile, 'utf-8').toString();
+ const FacadeName = `${className}Facade`;
+ const editInput: EditInput = {
+ fileType: 'ts',
+ fileName: fileName,
+ filePath: moduleTsFile,
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'import',
+ codeBlock: `{ ${FacadeName} }`,
+ path: importPath,
+ },
+ {
+ nodeType: 'addNgModuleProvider',
+ codeBlock: FacadeName,
+ }
+ ]
+ };
+ const updatedFileToBeAddedTo = morphTypescript(editInput);
+ // TODO extract write file logic from morphCode logic
+ writeFileSync(moduleTsFile, updatedFileToBeAddedTo);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade-output.module.ts.snap b/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade-output.module.ts.snap
new file mode 100644
index 0000000..88486f8
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade-output.module.ts.snap
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { TestFacade } from "./snapshots/sample.facade";
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [TestFacade],
+})
+export class DataAccessBooksModule { }
diff --git a/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade.module.ts.snap b/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade.module.ts.snap
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/facade/snapshots/ngrx-facade.module.ts.snap
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/ngrx/facade/test.module.ts b/src/rz/angular/effects/ngrx/facade/test.module.ts
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/facade/test.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.spec.ts b/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.spec.ts
new file mode 100644
index 0000000..7843f12
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.spec.ts
@@ -0,0 +1,33 @@
+import { TemplateInputParameter } from './../../../../utils/interfaces/template-parameters';
+import { AngularTypeNames } from '../../../types/types';
+import { effects, Parameters } from "../../../../morph";
+import { writeFileSync, readFileSync } from 'fs';
+
+describe('addReducerToNgModule', () => {
+ afterEach(() => {
+ const moduleToUseToReset = readFileSync('src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer.module.ts.snap').toString();
+ writeFileSync('src/rz/angular/effects/ngrx/reducer/test.module.ts', moduleToUseToReset);
+ });
+ it('should update the closest app module file with ngrx reducer codemods', () => {
+ const mockFilePath = 'src/rz/angular/effects/ngrx/reducer/snapshots/sample.reducer.ts';
+ const parameters: Parameters = {
+ className: 'Test',
+ constantName: 'TEST'
+ };
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.NgrxReducer
+ }
+ const parametersString = JSON.stringify(parameters);
+ effects(mockFilePath, mockTemplateInputParameter, 'angular', parametersString);
+ const result = readFileSync('src/rz/angular/effects/ngrx/reducer/test.module.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer-output.module.ts.snap').toString();
+
+ expect(result).toEqual(expected);
+ })
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.ts b/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.ts
new file mode 100644
index 0000000..5cda66c
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/reducer/ngrx-reducer.ts
@@ -0,0 +1,37 @@
+import { EditInput } from 'src/rz/morph/interfaces/morph.interface';
+import { findClosestModuleFile } from "../../../../utils";
+import { createRelativePath, isTsFile } from "../../../../utils/add-export";
+import { readFileSync, writeFileSync } from 'fs';
+import { morphTypescript } from '../../../../typescript/morph-typescript';
+
+export function addReducerToNgModule(filePathWithName: string, className: string, constantName: string): void {
+ // make sure that spec is not taken
+ if(isTsFile(filePathWithName)) {
+ const moduleTsFile = findClosestModuleFile(filePathWithName);
+ const importPath = createRelativePath(filePathWithName, moduleTsFile);
+ const fileName = moduleTsFile.split('.').pop();
+ const fileToBeAddedTo = readFileSync(moduleTsFile, 'utf-8').toString();
+ const ReducerName = `from${className}`;
+ const moduleName = `StoreModule.forFeature(${ReducerName}.${constantName}_FEATURE_KEY, ${ReducerName}.reducer)`;
+ const editInput: EditInput = {
+ fileType: 'ts',
+ fileName: fileName,
+ filePath: moduleTsFile,
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'import',
+ codeBlock: `* as fromBooks`,
+ path: importPath,
+ },
+ {
+ nodeType: 'addNgModuleImport',
+ codeBlock: moduleName,
+ }
+ ]
+ };
+ const updatedFileToBeAddedTo = morphTypescript(editInput);
+ // TODO extract write file logic from morphCode logic
+ writeFileSync(moduleTsFile, updatedFileToBeAddedTo);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer-output.module.ts.snap b/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer-output.module.ts.snap
new file mode 100644
index 0000000..a8a41ba
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer-output.module.ts.snap
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import * as fromBooks from "./snapshots/sample.reducer";
+
+@NgModule({
+ imports: [
+ CommonModule,
+ StoreModule.forFeature(fromTest.TEST_FEATURE_KEY, fromTest.reducer)
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule { }
diff --git a/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer.module.ts.snap b/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer.module.ts.snap
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/reducer/snapshots/ngrx-reducer.module.ts.snap
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/ngrx/reducer/test.module.ts b/src/rz/angular/effects/ngrx/reducer/test.module.ts
new file mode 100644
index 0000000..0b3abdf
--- /dev/null
+++ b/src/rz/angular/effects/ngrx/reducer/test.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ],
+ providers: [],
+})
+export class DataAccessBooksModule {}
diff --git a/src/rz/angular/effects/service/index.ts b/src/rz/angular/effects/service/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/effects/service/service.spec.ts b/src/rz/angular/effects/service/service.spec.ts
new file mode 100644
index 0000000..9dcd28d
--- /dev/null
+++ b/src/rz/angular/effects/service/service.spec.ts
@@ -0,0 +1,26 @@
+import { TemplateInputParameter } from './../../../utils/interfaces/template-parameters';
+import { writeFileSync, readFileSync } from 'fs';
+import { effects } from "../../../morph";
+import { AngularTypeNames } from "../../types/types";
+
+describe('exportServiceFile', () => {
+ afterEach(() => {
+ writeFileSync('src/rz/angular/effects/service/index.ts', '');
+ });
+ it('should export service file', () => {
+ const mockFilePath = 'src/rz/angular/effects/service/user-service.ts';
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.StandaloneComponent
+ }
+ effects(mockFilePath, mockTemplateInputParameter, 'angular');
+ const result = readFileSync('src/rz/angular/effects/service/index.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/service/snapshots/index-output.ts.snap').toString();
+ expect(result).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/angular/effects/service/service.ts b/src/rz/angular/effects/service/service.ts
new file mode 100644
index 0000000..01df410
--- /dev/null
+++ b/src/rz/angular/effects/service/service.ts
@@ -0,0 +1,7 @@
+import { exportTsFiles, isTsFile } from "../../../utils/add-export";
+
+export function exportServiceFile(filePathWithName: string): void {
+ if (isTsFile(filePathWithName)) {
+ exportTsFiles(filePathWithName);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/service/snapshots/index-output.ts.snap b/src/rz/angular/effects/service/snapshots/index-output.ts.snap
new file mode 100644
index 0000000..a850ca1
--- /dev/null
+++ b/src/rz/angular/effects/service/snapshots/index-output.ts.snap
@@ -0,0 +1 @@
+export * from "./user-service";
diff --git a/src/rz/angular/effects/standalone-component/index.ts b/src/rz/angular/effects/standalone-component/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/effects/standalone-component/snapshots/index-output.ts.snap b/src/rz/angular/effects/standalone-component/snapshots/index-output.ts.snap
new file mode 100644
index 0000000..6b4650e
--- /dev/null
+++ b/src/rz/angular/effects/standalone-component/snapshots/index-output.ts.snap
@@ -0,0 +1 @@
+export * from "./standalone-component";
diff --git a/src/rz/angular/effects/standalone-component/standalone-component.ts b/src/rz/angular/effects/standalone-component/standalone-component.ts
new file mode 100644
index 0000000..a7d9af8
--- /dev/null
+++ b/src/rz/angular/effects/standalone-component/standalone-component.ts
@@ -0,0 +1,7 @@
+import { exportTsFiles, isTsFile } from "../../../utils/add-export";
+
+export function exportComponentFile(filePathWithName: string): void {
+ if(isTsFile(filePathWithName)) {
+ exportTsFiles(filePathWithName);
+ }
+}
\ No newline at end of file
diff --git a/src/rz/angular/effects/standalone-component/standlone-component.spec.ts b/src/rz/angular/effects/standalone-component/standlone-component.spec.ts
new file mode 100644
index 0000000..e62e5db
--- /dev/null
+++ b/src/rz/angular/effects/standalone-component/standlone-component.spec.ts
@@ -0,0 +1,27 @@
+import { TemplateInputParameter } from './../../../utils/interfaces/template-parameters';
+import { writeFileSync, readFileSync } from 'fs';
+import { effects } from "../../../morph";
+import { AngularTypeNames } from "../../types/types";
+
+describe('exportComponentFile', () => {
+ afterEach(() => {
+ writeFileSync('src/rz/angular/effects/standalone-component/index.ts', '');
+ });
+ it('should export component file', () => {
+ const mockFilePath = 'src/rz/angular/effects/standalone-component/standalone-component.ts';
+ const mockTemplateInputParameter: TemplateInputParameter = {
+ defaultValue: 'libs/{name}-dialog',
+ description: 'File path for name file(s)',
+ inputType: 'text',
+ name: 'nameFilePath',
+ optionalTypes: [{name: 'isExported', selected: true}],
+ paramType: 'filePath',
+ type: AngularTypeNames.StandaloneComponent
+ }
+
+ effects(mockFilePath, mockTemplateInputParameter, 'angular');
+ const result = readFileSync('src/rz/angular/effects/standalone-component/index.ts').toString();
+ const expected = readFileSync('src/rz/angular/effects/standalone-component/snapshots/index-output.ts.snap').toString();
+ expect(result).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/angular/index.ts b/src/rz/angular/index.ts
new file mode 100644
index 0000000..9d7167a
--- /dev/null
+++ b/src/rz/angular/index.ts
@@ -0,0 +1,2 @@
+export { angularTypes, AngularTypeNames } from "./types/types";
+export { defaultAngularTechnologies } from "./technologies/angular-technologies";
diff --git a/src/rz/angular/insert-into-html-tag/insert-into-html-tag.ts b/src/rz/angular/insert-into-html-tag/insert-into-html-tag.ts
new file mode 100644
index 0000000..772d4c2
--- /dev/null
+++ b/src/rz/angular/insert-into-html-tag/insert-into-html-tag.ts
@@ -0,0 +1,22 @@
+
+import visit = require('unist-util-visit');
+import { createUnifiedTree } from '../morph-angular-html';
+import { EditHtmlFile } from '../interfaces/edit-html.interface';
+
+
+// will insert code into an html block
+export function insertIntoHtmlTag(editFile: EditHtmlFile, fileToBeModified: any): any {
+ const codeToAddTree = createUnifiedTree(editFile.codeBlock as string);
+ let counter = 0;
+
+ visit(fileToBeModified, {type: 'element', tagName: editFile.tagNameToInsertInto}, (node: any, index) => {
+ visit(codeToAddTree, {type: 'element', tagName: 'body'}, (nodeOfCodeToAdd: any, index) => {
+ if(counter === 0) {
+ node.children.push(nodeOfCodeToAdd.children[0]);
+ counter++;
+ }
+ });
+ });
+
+ return fileToBeModified
+}
\ No newline at end of file
diff --git a/src/rz/angular/interfaces/edit-html.interface.ts b/src/rz/angular/interfaces/edit-html.interface.ts
new file mode 100644
index 0000000..00ae199
--- /dev/null
+++ b/src/rz/angular/interfaces/edit-html.interface.ts
@@ -0,0 +1,15 @@
+export interface EditHtmlInput {
+ fileType?: 'html',
+ fileToBeAddedTo?: string | any;
+ edits: EditHtmlFile[];
+}
+
+export interface EditHtmlFile {
+ nodeType: 'editHtmlTag' | 'addSiblingHtml' | 'insertIntoHtmlTag' |
+ 'deleteHtmlElement' | 'prependHtml' | 'appendHtml';
+ codeBlock: string | any[];
+ tagNameToInsert?: string;
+ tagNameToInsertInto?: string;
+ tagNameToModify?: string;
+ siblingTagName?: string;
+}
\ No newline at end of file
diff --git a/src/rz/angular/morph-angular-html.spec.ts b/src/rz/angular/morph-angular-html.spec.ts
new file mode 100644
index 0000000..e26e929
--- /dev/null
+++ b/src/rz/angular/morph-angular-html.spec.ts
@@ -0,0 +1,66 @@
+import { readFileSync } from 'fs';
+import { morphHtml} from './morph-angular-html';
+import { EditHtmlFile, EditHtmlInput } from "./interfaces/edit-html.interface";
+
+describe('EditAngularHTML', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/angular/snapshots/data-table.component.html.snap').toString();
+ const siblingCodeBlock = `
+ `;
+ const modifyTagNameCodeBlock = 'matSort';
+ it('should insert an html block of code after', () => {
+ const addSiblingHtml: EditHtmlFile = {
+ nodeType: 'addSiblingHtml',
+ codeBlock: siblingCodeBlock,
+ tagNameToInsert: 'mat-paginator',
+ siblingTagName: 'table'
+ };
+
+ const updateHtmlTag: EditHtmlFile = {
+ nodeType: 'editHtmlTag',
+ codeBlock: modifyTagNameCodeBlock,
+ tagNameToModify: 'table',
+ };
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ addSiblingHtml,
+ updateHtmlTag
+ ]
+ };
+
+ const expected = readFileSync('src/rz/angular/snapshots/data-table-output.component.html.snap').toString();
+
+ const newHtmlString = morphHtml(editHtmlInput);
+
+ expect(newHtmlString).toEqual(expected);
+ });
+
+ describe('insertIntoHtmlTag', () => {
+ it('should insert html into the specified tag', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html.snap').toString();
+ const codeBlock = '
new div content
';
+ const insertIntoHtmlTag: EditHtmlFile = {
+ nodeType: 'insertIntoHtmlTag',
+ codeBlock: codeBlock,
+ tagNameToInsertInto: 'div'
+ };
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ insertIntoHtmlTag
+ ]
+ };
+
+ const expected = readFileSync('src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html-output.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+ });
+
+});
\ No newline at end of file
diff --git a/src/rz/angular/morph-angular-html.ts b/src/rz/angular/morph-angular-html.ts
new file mode 100644
index 0000000..546df6d
--- /dev/null
+++ b/src/rz/angular/morph-angular-html.ts
@@ -0,0 +1,59 @@
+import { parse } from 'parse5';
+import fromParse5 = require('hast-util-from-parse5');
+import toHtml = require('hast-util-to-html');
+import { EditHtmlFile, EditHtmlInput } from './interfaces/edit-html.interface';
+import { insertCodeAfterElement } from './add-sibling-html';
+import { insertIntoHtmlTag } from './insert-into-html-tag/insert-into-html-tag';
+import { updateHtmlTag } from './update-html-tag';
+import * as prettier from 'prettier';
+import * as parserHtml from 'prettier/parser-html';
+import { deleteHtmlElement } from '../html/delete-html-element/delete-html-element';
+import { prependHtml } from '../html/prepend-html/prepend-html';
+import { appendHtml } from '../html/append-html/append-html';
+
+function convertToAngularHtmlAndPrettify(tree: any) {
+ const transformedTreeInHtml = toHtml(tree)
+ .replace('','').replace('','')
+ .replace('','').replace('','')
+ .replace('','').replace('','');
+
+ return prettier.format(transformedTreeInHtml, {
+ parser: "html",
+ plugins: [parserHtml]
+ });
+}
+
+export function createUnifiedTree(htmlString: string | any): any {
+ const p5ast = parse(String(htmlString), {sourceCodeLocationInfo: true});
+ return fromParse5(p5ast);
+}
+
+
+// fileToBeAddedToTree is top level
+export function morphHtml(editHtmlInput: EditHtmlInput): string {
+ let fileToBeAddedToTree = createUnifiedTree(editHtmlInput.fileToBeAddedTo);
+
+ editHtmlInput.edits.forEach((edit: EditHtmlFile) => {
+ switch (edit.nodeType) {
+ case 'editHtmlTag':
+ fileToBeAddedToTree = updateHtmlTag(edit, fileToBeAddedToTree);
+ break;
+ case 'addSiblingHtml':
+ fileToBeAddedToTree = insertCodeAfterElement(edit, fileToBeAddedToTree);
+ break;
+ case 'insertIntoHtmlTag':
+ fileToBeAddedToTree = insertIntoHtmlTag(edit, fileToBeAddedToTree);
+ break;
+ case 'deleteHtmlElement':
+ fileToBeAddedToTree = deleteHtmlElement(edit, fileToBeAddedToTree);
+ break;
+ case 'prependHtml':
+ fileToBeAddedToTree = prependHtml(edit, fileToBeAddedToTree);
+ break;
+ case 'appendHtml':
+ fileToBeAddedToTree = appendHtml(edit, fileToBeAddedToTree);
+ }
+ })
+
+ return convertToAngularHtmlAndPrettify(fileToBeAddedToTree);
+}
\ No newline at end of file
diff --git a/src/rz/angular/snapshots/data-table-output.component.html.snap b/src/rz/angular/snapshots/data-table-output.component.html.snap
new file mode 100644
index 0000000..c4aa8a6
--- /dev/null
+++ b/src/rz/angular/snapshots/data-table-output.component.html.snap
@@ -0,0 +1,76 @@
+
+
+
+
+ Filter
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/rz/angular/snapshots/data-table.component.ts.snap b/src/rz/angular/snapshots/data-table.component.ts.snap
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header-output.html.snap b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header-output.html.snap
new file mode 100644
index 0000000..6791856
--- /dev/null
+++ b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header-output.html.snap
@@ -0,0 +1,19 @@
+Sample header
+
+
+
+
diff --git a/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header.html.snap b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header.html.snap
new file mode 100644
index 0000000..b938510
--- /dev/null
+++ b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag-header.html.snap
@@ -0,0 +1 @@
+Sample header
diff --git a/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html-output.snap b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html-output.snap
new file mode 100644
index 0000000..24b4f4d
--- /dev/null
+++ b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html-output.snap
@@ -0,0 +1 @@
+
new div content
diff --git a/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html.snap b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html.snap
new file mode 100644
index 0000000..281c686
--- /dev/null
+++ b/src/rz/angular/snapshots/insert-into-html-tag/insert-into-html-tag.html.snap
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/rz/angular/technologies/angular-technologies.ts b/src/rz/angular/technologies/angular-technologies.ts
new file mode 100644
index 0000000..3bae434
--- /dev/null
+++ b/src/rz/angular/technologies/angular-technologies.ts
@@ -0,0 +1,12 @@
+export enum DefaultAngularTechnologies {
+ Angular = 'angular',
+ Apollo = 'apollo',
+ FontAwesome = 'font-awesome',
+ Jest = 'jest',
+ Nrwl = 'nrwl',
+ Prettier = 'prettier',
+ Rxjs = 'rxjs',
+ Scss = 'scss'
+}
+
+export const defaultAngularTechnologies = Object.values(DefaultAngularTechnologies);
\ No newline at end of file
diff --git a/src/rz/angular/types/types.ts b/src/rz/angular/types/types.ts
new file mode 100644
index 0000000..ac10a84
--- /dev/null
+++ b/src/rz/angular/types/types.ts
@@ -0,0 +1,68 @@
+export enum AngularTypeNames {
+ Generic = 'generic',
+ Class = 'class',
+ Component = 'component',
+ StandaloneComponent = 'standalone-component',
+ Directive = 'directive',
+ Enum = 'enum',
+ Guard = 'guard',
+ Graphql = 'graphql',
+ Interceptor = 'interceptor',
+ Interface = 'interface',
+ Library = 'library',
+ Module = 'module',
+ NgrxEffects = 'ngrx-effects',
+ NgrxFacade = 'ngrx-facade',
+ NgrxReducer = 'ngrx-reducer',
+ Pipe = 'pipe',
+ Resolver = 'resolver',
+ Service = 'service',
+ ServiceWorker = 'service-worker',
+ WebWorker = 'web-worker'
+}
+
+export enum GlobalAngularOptionNames {
+ IsExported = 'isExported'
+}
+
+export interface AngularOptionalType {
+ name: GlobalAngularOptionNames,
+ selected: boolean
+}
+
+export interface AngularType {
+ name: AngularTypeNames;
+ optionalTypes?: AngularOptionalType[]
+}
+
+export const angularTypes: Array = [
+ {
+ name: AngularTypeNames.Component,
+ optionalTypes: [
+ {
+ name: GlobalAngularOptionNames.IsExported,
+ selected: true
+ }
+ ]
+ },
+ {name: AngularTypeNames.Generic},
+ {name: AngularTypeNames.Class},
+ {name: AngularTypeNames.StandaloneComponent},
+ {name: AngularTypeNames.Directive},
+ {name: AngularTypeNames.Enum},
+ {name: AngularTypeNames.Guard},
+ {name: AngularTypeNames.Graphql},
+ {name: AngularTypeNames.Interceptor},
+ {name: AngularTypeNames.Interceptor},
+ {name: AngularTypeNames.Interface},
+ {name: AngularTypeNames.Library},
+ {name: AngularTypeNames.Module},
+ {name: AngularTypeNames.NgrxEffects},
+ {name: AngularTypeNames.NgrxFacade},
+ {name: AngularTypeNames.NgrxReducer},
+ {name: AngularTypeNames.Pipe},
+ {name: AngularTypeNames.Resolver},
+ {name: AngularTypeNames.Service},
+ {name: AngularTypeNames.ServiceWorker},
+ {name: AngularTypeNames.WebWorker},
+];
\ No newline at end of file
diff --git a/src/rz/angular/update-html-tag.ts b/src/rz/angular/update-html-tag.ts
new file mode 100644
index 0000000..e9358d4
--- /dev/null
+++ b/src/rz/angular/update-html-tag.ts
@@ -0,0 +1,12 @@
+import visit = require('unist-util-visit');
+import { EditHtmlFile } from "./interfaces/edit-html.interface";
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+// will add an angular directive to html
+export function updateHtmlTag(editHtmlFile: EditHtmlFile, fileToBeAddedToTree: any): any {
+ visit(fileToBeAddedToTree, {type: 'element', tagName: editHtmlFile.tagNameToModify}, (htmlElement: any) => {
+ htmlElement.properties[editHtmlFile.codeBlock as string] = true;
+ });
+
+ return fileToBeAddedToTree;
+}
\ No newline at end of file
diff --git a/src/rz/global-variables/colors/colors.spec.ts b/src/rz/global-variables/colors/colors.spec.ts
new file mode 100644
index 0000000..5ec86db
--- /dev/null
+++ b/src/rz/global-variables/colors/colors.spec.ts
@@ -0,0 +1,22 @@
+import { getPalette, createColorVariables } from './colors';
+
+describe('getPalette', () => {
+ it('should return a color palette', () => {
+ const result = getPalette('#cc33ca');
+ expect(result).toEqual(
+ {"100": "#f0c2ef", "200": "#e699e5", "300": "#db70da", "400": "#d452d2", "50": "#f9e7f9", "500": "#cc33ca", "600": "#c72ec5", "700": "#c027bd", "800": "#b920b7", "900": "#ad14ab", "A100": "#ffffff", "A200": "#fadbff", "A400": "#f2a8ff", "A700": "#ef8fff"}
+ );
+ });
+});
+
+describe('createColorVariables', () => {
+ it('should properly create color variables', () => {
+ const result = createColorVariables('#cc33ca', 'primary');
+ const expected = {
+ "primary": "#cc33ca",
+ "primaryDarker": "#b920b7",
+ "primaryLighter": "#f0c2ef",
+ }
+ expect(result).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/global-variables/colors/colors.ts b/src/rz/global-variables/colors/colors.ts
new file mode 100644
index 0000000..e37a216
--- /dev/null
+++ b/src/rz/global-variables/colors/colors.ts
@@ -0,0 +1,78 @@
+import { TinyColor } from '@ctrl/tinycolor';
+
+export interface MaterialPalette {
+ [key: string]: {
+ key: string,
+ hex: string,
+ isLight: boolean
+ };
+}
+
+export interface SubPalette {
+ main: string;
+ lighter: string;
+ darker: string;
+}
+
+type RGBA = any;
+
+const MIX_AMOUNTS_PRIMARY = {
+ 50: [true, 12],
+ 100: [true, 30],
+ 200: [true, 50],
+ 300: [true, 70],
+ 400: [true, 85],
+ 500: [true, 100],
+ 600: [false, 87],
+ 700: [false, 70],
+ 800: [false, 54],
+ 900: [false, 25]
+ };
+
+const MIX_AMOUNTS_SECONDARY = {
+ A100: [15, 80, 65],
+ A200: [15, 80, 55],
+ A400: [15, 100, 45],
+ A700: [15, 100, 40]
+};
+
+function multiply(rgb1: RGBA, rgb2: RGBA) {
+ rgb1.b = Math.floor(rgb1.b * rgb2.b / 255);
+ rgb1.g = Math.floor(rgb1.g * rgb2.g / 255);
+ rgb1.r = Math.floor(rgb1.r * rgb2.r / 255);
+ return new TinyColor('rgb ' + rgb1.r + ' ' + rgb1.g + ' ' + rgb1.b);
+ }
+
+export function getPalette(color: string): MaterialPalette {
+ const baseLight = new TinyColor('#ffffff');
+ const baseDark = multiply(new TinyColor(color).toRgb(), new TinyColor(color).toRgb());
+ const [, , , baseTriad] = new TinyColor(color).tetrad();
+
+ const primary = Object.keys(MIX_AMOUNTS_PRIMARY)
+ .map(k => {
+ const [light, amount] = MIX_AMOUNTS_PRIMARY[k];
+ return [k, new TinyColor(light ? baseLight : baseDark).mix(new TinyColor(color), amount)];
+ });
+
+ const accent = Object.keys(MIX_AMOUNTS_SECONDARY)
+ .map(k => {
+ const [amount, sat, light] = MIX_AMOUNTS_SECONDARY[k];
+ return [k, new TinyColor(baseDark).mix(new TinyColor(baseTriad), amount)
+ .saturate(sat).lighten(light)] as any;
+ });
+
+ return [...primary, ...accent].reduce((acc, [k, c]) => {
+ acc[k] = c.toHexString();
+ return acc;
+ }, {});
+}
+
+export function createColorVariables(color: string, variableName: string): any {
+ const colorPallette = getPalette(color);
+
+ return {
+ [`${variableName}Lighter`]: colorPallette['100'],
+ [`${variableName}`]: colorPallette['500'],
+ [`${variableName}Darker`]: colorPallette['800'],
+ }
+}
\ No newline at end of file
diff --git a/src/rz/global-variables/index.ts b/src/rz/global-variables/index.ts
new file mode 100644
index 0000000..08bd1d0
--- /dev/null
+++ b/src/rz/global-variables/index.ts
@@ -0,0 +1,8 @@
+
+export { createColorVariables, getPalette } from "./colors/colors";
+
+export { names } from "./names";
+
+export { powerUpVariablesFlatData } from './variable-dependencies/variable-dependencies';
+
+export { codeCmsVariablesToIgnore, powerUpVariables } from "./variables-to-ignore/variables-to-ignore";
\ No newline at end of file
diff --git a/src/rz/global-variables/interfaces/global-variables.interface.ts b/src/rz/global-variables/interfaces/global-variables.interface.ts
new file mode 100644
index 0000000..c465994
--- /dev/null
+++ b/src/rz/global-variables/interfaces/global-variables.interface.ts
@@ -0,0 +1,10 @@
+export type CodeCmsVariablesToIgnore = 'className' | 'propertyName' | 'constantName' | 'fileName';
+export interface PowerUpVariables {
+ name: string;
+ variablesToImplement?: any[];
+ defaultValue: string;
+ description?: string;
+ codeExample?: string;
+ stubValue?: string;
+ variableDependency: string
+}
\ No newline at end of file
diff --git a/src/rz/global-variables/interfaces/index.ts b/src/rz/global-variables/interfaces/index.ts
new file mode 100644
index 0000000..a546aa7
--- /dev/null
+++ b/src/rz/global-variables/interfaces/index.ts
@@ -0,0 +1 @@
+export { CodeCmsVariablesToIgnore, PowerUpVariables } from './global-variables.interface';
\ No newline at end of file
diff --git a/src/rz/global-variables/names.spec.ts b/src/rz/global-variables/names.spec.ts
new file mode 100644
index 0000000..692f4f9
--- /dev/null
+++ b/src/rz/global-variables/names.spec.ts
@@ -0,0 +1,39 @@
+import { names } from './names';
+
+describe('names', () => {
+ it('should support class names', () => {
+ expect(names('foo-bar').className).toEqual('FooBar');
+ expect(names('foo_bar').className).toEqual('FooBar');
+ expect(names('fooBar').className).toEqual('FooBar');
+ expect(names('[fooBar]').className).toEqual('FooBar');
+ expect(names('[...fooBar]').className).toEqual('FooBar');
+ expect(names('foo-@bar').className).toEqual('FooBar');
+ });
+
+ it('should support property names', () => {
+ expect(names('foo-bar').propertyName).toEqual('fooBar');
+ expect(names('foo_bar').propertyName).toEqual('fooBar');
+ expect(names('FooBar').propertyName).toEqual('fooBar');
+ expect(names('[fooBar]').propertyName).toEqual('fooBar');
+ expect(names('[...fooBar]').propertyName).toEqual('fooBar');
+ expect(names('foo-@bar').propertyName).toEqual('fooBar');
+ });
+
+ it('should support file names', () => {
+ expect(names('foo-bar').fileName).toEqual('foo-bar');
+ expect(names('foo_bar').fileName).toEqual('foo-bar');
+ expect(names('FooBar').fileName).toEqual('foo-bar');
+ expect(names('[fooBar]').fileName).toEqual('[foo-bar]');
+ expect(names('[...fooBar]').fileName).toEqual('[...foo-bar]');
+ expect(names('foo-@bar').fileName).toEqual('foo-@bar');
+ });
+
+ it('should support title names', () => {
+ expect(names('foo-bar').titleName).toEqual('Foo Bar');
+ expect(names('foo_bar').titleName).toEqual('Foo Bar');
+ expect(names('fooBar').titleName).toEqual('Foo Bar');
+ expect(names('[fooBar]').titleName).toEqual('Foo Bar');
+ expect(names('[...fooBar]').titleName).toEqual('Foo Bar');
+ expect(names('foo-@bar').titleName).toEqual('Foo Bar');
+ });
+});
diff --git a/src/rz/global-variables/names.ts b/src/rz/global-variables/names.ts
new file mode 100644
index 0000000..bd86fb0
--- /dev/null
+++ b/src/rz/global-variables/names.ts
@@ -0,0 +1,79 @@
+/**
+ * Util function to generate different strings based off the provided name.
+ *
+ * Examples:
+ *
+ * ```typescript
+ * names("my-name") // {name: 'my-name', className: 'MyName', propertyName: 'myName', constantName: 'MY_NAME', fileName: 'my-name'}
+ * names("myName") // {name: 'my-name', className: 'MyName', propertyName: 'myName', constantName: 'MY_NAME', fileName: 'my-name'}
+ * ```
+ * @param name
+ */
+ export function names(name: string): {
+ name: string;
+ className: string;
+ propertyName: string;
+ constantName: string;
+ fileName: string;
+ titleName: string;
+ } {
+ return {
+ name,
+ className: toClassName(name),
+ propertyName: toPropertyName(name),
+ constantName: toConstantName(name),
+ fileName: toFileName(name),
+ titleName: toTitleName(name)
+ };
+ }
+
+ /**
+ * Hyphenated to UpperCamelCase
+ */
+ function toClassName(str: string): string {
+ return toCapitalCase(toPropertyName(str));
+ }
+
+ /**
+ * Hyphenated to lowerCamelCase
+ */
+ function toPropertyName(s: string): string {
+ return s
+ .replace(/([^a-zA-Z0-9])+(.)?/g, (_, __, chr) =>
+ chr ? chr.toUpperCase() : ''
+ )
+ .replace(/[^a-zA-Z\d]/g, '')
+ .replace(/^([A-Z])/, (m) => m.toLowerCase());
+ }
+
+ /**
+ * Hyphenated to CONSTANT_CASE
+ */
+ function toConstantName(s: string): string {
+ return s.replace(/([^a-zA-Z0-9])/g, '_').toUpperCase();
+ }
+
+ /**
+ * Upper camelCase to lowercase, hyphenated
+ */
+ function toFileName(s: string): string {
+ return s
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+ .toLowerCase()
+ .replace(/[ _]/g, '-');
+ }
+
+ /**
+ * Capitalizes the first letter of a string
+ */
+ function toCapitalCase(s: string): string {
+ return s.charAt(0).toUpperCase() + s.substr(1);
+ }
+
+ function toTitleName(s: string): string {
+ return toClassName(s).split('')
+ .map(letter =>
+ letter.match(/[A-Z]/)?' ' + letter : letter
+ ).join('').trim()
+ }
+
\ No newline at end of file
diff --git a/src/rz/global-variables/variable-dependencies/variable-dependencies.ts b/src/rz/global-variables/variable-dependencies/variable-dependencies.ts
new file mode 100644
index 0000000..4c0f597
--- /dev/null
+++ b/src/rz/global-variables/variable-dependencies/variable-dependencies.ts
@@ -0,0 +1,141 @@
+import { PowerUpVariables } from "../interfaces"
+
+export const powerUpVariablesFlatData: PowerUpVariables[] = [
+ {
+ name: 'name',
+ description: 'Template variable to be used for class creation',
+ defaultValue: 'name',
+ stubValue: 'name',
+ variableDependency: 'name'
+ },
+ {
+ name: 'className',
+ defaultValue: 'className',
+ description: 'Hyphenated to UpperCamelCase',
+ codeExample: 'my-name to MyName',
+ stubValue: 'className',
+ variableDependency: 'name'
+ },
+ {
+ name: 'propertyName',
+ defaultValue: 'propertyName',
+ stubValue: 'propertyName',
+ description: 'Hyphenated to lowerCamelCase',
+ codeExample: 'my-name to myName',
+ variableDependency: 'name'
+ },
+ {
+ name: 'constantName',
+ defaultValue: 'constantName',
+ stubValue: 'constantName',
+ description: 'Hyphenated to CONSTANT_CASE',
+ codeExample: 'my-name to MY_NAME',
+ variableDependency: 'name'
+ },
+ {
+ name: 'fileName',
+ defaultValue: 'fileName',
+ stubValue: 'fileName',
+ description: 'Upper camelCase to lowercase, hyphenated',
+ codeExample: 'myName to my-name',
+ variableDependency: 'name'
+ },
+ {
+ name: 'titleName',
+ description: 'will create a Title Case title out of your kebab-case name',
+ defaultValue: '<%= titleName %>',
+ stubValue: 'titleName',
+ codeExample: 'myName to My Name',
+ variableDependency: 'name'
+ },
+ {
+ name: 'orgName',
+ description: 'Will dyanmically get organization name',
+ defaultValue: '<%= orgName %>',
+ stubValue: 'orgName',
+ variableDependency: 'orgName'
+ },
+ {
+ name: 'projectName',
+ description: 'Will dynamically get project name',
+ defaultValue: '<%= projectName %>',
+ stubValue: 'projectName',
+ variableDependency: 'projectName'
+ },
+ {
+ name: 'primary',
+ description: 'primary color to be used within app',
+ defaultValue: 'primary',
+ stubValue: 'primary',
+ variableDependency: 'primary'
+ },
+ {
+ name: 'primaryLighter',
+ defaultValue: 'primaryLighter',
+ stubValue: 'primaryLighter',
+ description: 'Lighter color of primary',
+ codeExample: 'primary to primaryLighter',
+ variableDependency: 'primary'
+ },
+ {
+ name: 'primaryDarker',
+ defaultValue: 'primaryDarker',
+ stubValue: 'primaryDarker',
+ description: 'Darker color of primary',
+ codeExample: 'primary to primaryDarker',
+ variableDependency: 'primary'
+ },
+ {
+ name: 'accent',
+ stubValue: 'accent',
+ description: 'accent color to be used within app',
+ defaultValue: 'accent',
+ variableDependency: 'accent'
+ },
+ {
+ name: 'accentLighter',
+ stubValue: 'accentLighter',
+ defaultValue: 'accentLighter',
+ description: 'Lighter color of accent',
+ codeExample: 'accent to accentLighter',
+ variableDependency: 'accent'
+ },
+ {
+ name: 'accentDarker',
+ stubValue: 'accentDarker',
+ defaultValue: 'accentDarker',
+ description: 'Darker color of accent',
+ codeExample: 'accent to accentDarker',
+ variableDependency: 'accent'
+ },
+ {
+ name: 'warn',
+ stubValue: 'warn',
+ defaultValue: 'warn',
+ description: 'warn color to be used within app',
+ variableDependency: 'warn'
+ },
+ {
+ name: 'warnLighter',
+ stubValue: 'warnLighter',
+ defaultValue: 'warnLighter',
+ description: 'Lighter color of warn',
+ codeExample: 'warn to warnLighter',
+ variableDependency: 'warn'
+ },
+ {
+ name: 'warnDarker',
+ stubValue: 'warnDarker',
+ defaultValue: 'warnDarker',
+ description: 'Darker color of warn',
+ codeExample: 'warn to warnDarker',
+ variableDependency: 'warn'
+ },
+ {
+ name: 'infrastructureCommandPath',
+ description: 'Template variable to be used for infrastructure commands',
+ defaultValue: 'infrastructureCommandPath',
+ stubValue: 'infrastructureCommandPath',
+ variableDependency: 'infrastructureCommandPath'
+ },
+ ]
\ No newline at end of file
diff --git a/src/rz/global-variables/variables-to-ignore/variables-to-ignore.ts b/src/rz/global-variables/variables-to-ignore/variables-to-ignore.ts
new file mode 100644
index 0000000..b347bbe
--- /dev/null
+++ b/src/rz/global-variables/variables-to-ignore/variables-to-ignore.ts
@@ -0,0 +1,116 @@
+import { PowerUpVariables } from "../interfaces";
+
+export const codeCmsVariablesToIgnore: string[] = ['className', 'propertyName', 'constantName', 'fileName'];
+
+export const powerUpVariables: PowerUpVariables[] = [
+ {
+ name: 'name',
+ description: 'Template variable to be used for class creation',
+ defaultValue: 'name',
+ variableDependency: 'name',
+ variablesToImplement: [
+ {
+ name: 'className',
+ description: 'Hyphenated to UpperCamelCase',
+ codeExample: 'my-name to MyName',
+ variableDependency: 'name'
+ },
+ {
+ name: 'propertyName',
+ description: 'Hyphenated to lowerCamelCase',
+ codeExample: 'my-name to myName',
+ variableDependency: 'name'
+ },
+ {
+ name: 'constantName',
+ description: 'Hyphenated to CONSTANT_CASE',
+ codeExample: 'my-name to MY_NAME'
+ },
+ {
+ name: 'fileName',
+ description: 'Upper camelCase to lowercase, hyphenated',
+ codeExample: 'myName to my-name'
+ },
+ {
+ name: 'titleName',
+ description: 'camelCase to Title Case',
+ codeExample: 'myName to My Name'
+ }
+ ]
+ },
+ {
+ name: 'orgName',
+ description: 'Will dyanmically get organization name',
+ defaultValue: '<%= orgName %>',
+ stubValue: 'orgName',
+ variableDependency: 'orgName'
+ },
+ {
+ name: 'projectName',
+ description: 'Will dynamically get project name',
+ defaultValue: '<%= projectName %>',
+ stubValue: 'projectName',
+ variableDependency: 'projectName'
+ },
+ {
+ name: 'primary',
+ description: 'primary color to be used within app',
+ defaultValue: 'primary',
+ variableDependency: 'primary',
+ variablesToImplement: [
+ {
+ name: 'primaryLighter',
+ description: 'Lighter color of primary',
+ codeExample: 'primary to primaryLighter'
+ },
+ {
+ name: 'primaryDarker',
+ description: 'Darker color of primary',
+ codeExample: 'primary to primaryDarker'
+ }
+ ]
+ },
+ {
+ name: 'accent',
+ description: 'accent color to be used within app',
+ defaultValue: 'accent',
+ variableDependency: 'accent',
+ variablesToImplement: [
+ {
+ name: 'accentLighter',
+ description: 'Lighter color of accent',
+ codeExample: 'accent to accentLighter'
+ },
+ {
+ name: 'accentDarker',
+ description: 'Darker color of accent',
+ codeExample: 'accent to accentDarker'
+ }
+ ]
+ },
+ {
+ name: 'warn',
+ defaultValue: 'warn',
+ description: 'warn color to be used within app',
+ variableDependency: 'warn',
+ variablesToImplement: [
+ {
+ name: 'warnLighter',
+ description: 'Lighter color of warn',
+ codeExample: 'warn to warnLighter'
+ },
+ {
+ name: 'warnDarker',
+ description: 'Darker color of warn',
+ codeExample: 'warn to warnDarker'
+ }
+ ]
+ },
+ {
+ name: 'infrastructureCommandPath',
+ description: 'Template variable to be used for infrastructure commands',
+ defaultValue: 'infrastructureCommandPath',
+ stubValue: 'infrastructureCommandPath',
+ variableDependency: 'infrastructureCommandPath'
+ }
+]
\ No newline at end of file
diff --git a/src/rz/html/append-html/append-html.spec.ts b/src/rz/html/append-html/append-html.spec.ts
new file mode 100644
index 0000000..c2928f0
--- /dev/null
+++ b/src/rz/html/append-html/append-html.spec.ts
@@ -0,0 +1,42 @@
+import { EditHtmlInput } from '../../angular/interfaces/edit-html.interface';
+import { readFileSync } from 'fs';
+import { morphHtml } from '../../angular/morph-angular-html';
+
+describe('appendHtml' , () => {
+ it('should append an html element', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/html/append-html/snapshots/append-html.html.snap').toString();
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'appendHtml',
+ codeBlock: '',
+ }
+ ]
+ };
+
+ const expected = readFileSync('src/rz/html/append-html/snapshots/append-html-output.html.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+
+ it('should append html code inside of passed in optional element', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element.html.snap').toString();
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'appendHtml',
+ codeBlock: '
test
',
+ tagNameToInsertInto: 'mat-toolbar'
+ }
+ ]
+ };
+
+ const expected = readFileSync('src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element-output.html.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/html/append-html/append-html.ts b/src/rz/html/append-html/append-html.ts
new file mode 100644
index 0000000..b5fbd4f
--- /dev/null
+++ b/src/rz/html/append-html/append-html.ts
@@ -0,0 +1,21 @@
+import { createUnifiedTree } from '../../angular/morph-angular-html';
+import visit = require('unist-util-visit');
+import { EditHtmlFile } from "../../angular/interfaces/edit-html.interface";
+
+export function appendHtml(editHtmlFile: EditHtmlFile, fileToBeAddedToTree: any): any {
+ let counter = 0;
+ let elementToReturn: any;
+
+ const element = editHtmlFile.tagNameToInsertInto ? {type: 'element', tagName: editHtmlFile.tagNameToInsertInto} : {type: 'element', tagName: 'body'};
+
+ visit(fileToBeAddedToTree, element, (htmlElement: any) => {
+ const codeToAddTree = createUnifiedTree(editHtmlFile.codeBlock as string);
+ if(counter === 0) {
+ htmlElement.children.push(codeToAddTree);
+ elementToReturn = editHtmlFile.tagNameToInsertInto ? htmlElement : htmlElement.children;
+ counter++;
+ }
+ });
+
+ return elementToReturn;
+}
\ No newline at end of file
diff --git a/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element-output.html.snap b/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element-output.html.snap
new file mode 100644
index 0000000..659a554
--- /dev/null
+++ b/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element-output.html.snap
@@ -0,0 +1,4 @@
+
+
hello
+
test
diff --git a/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element.html.snap b/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element.html.snap
new file mode 100644
index 0000000..d645aeb
--- /dev/null
+++ b/src/rz/html/append-html/snapshots/append-html-into-element/append-html-into-element.html.snap
@@ -0,0 +1,3 @@
+
+
hello
+
diff --git a/src/rz/html/append-html/snapshots/append-html-output.html.snap b/src/rz/html/append-html/snapshots/append-html-output.html.snap
new file mode 100644
index 0000000..16bcade
--- /dev/null
+++ b/src/rz/html/append-html/snapshots/append-html-output.html.snap
@@ -0,0 +1,2 @@
+
+
diff --git a/src/rz/html/append-html/snapshots/append-html.html.snap b/src/rz/html/append-html/snapshots/append-html.html.snap
new file mode 100644
index 0000000..281c686
--- /dev/null
+++ b/src/rz/html/append-html/snapshots/append-html.html.snap
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/rz/html/delete-html-element/delete-html-element.spec.ts b/src/rz/html/delete-html-element/delete-html-element.spec.ts
new file mode 100644
index 0000000..c5a753c
--- /dev/null
+++ b/src/rz/html/delete-html-element/delete-html-element.spec.ts
@@ -0,0 +1,23 @@
+import { EditHtmlInput } from './../../angular/interfaces/edit-html.interface';
+import { readFileSync } from 'fs';
+import { morphHtml } from '../../angular/morph-angular-html';
+
+describe('deleteHtmlElement' , () => {
+ it('should delete an html element', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/html/delete-html-element/snapshots/delete-html-element.html.snap').toString();
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'deleteHtmlElement',
+ codeBlock: 'mat-toolbar',
+ }
+ ]
+ };
+
+ const expected = readFileSync('src/rz/html/delete-html-element/snapshots/delete-html-element-output.html.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/html/delete-html-element/delete-html-element.ts b/src/rz/html/delete-html-element/delete-html-element.ts
new file mode 100644
index 0000000..456bdf7
--- /dev/null
+++ b/src/rz/html/delete-html-element/delete-html-element.ts
@@ -0,0 +1,10 @@
+import visit = require('unist-util-visit');
+import { EditHtmlFile } from "../../angular/interfaces/edit-html.interface";
+
+export function deleteHtmlElement(editHtmlFile: EditHtmlFile, fileToBeAddedToTree: any): any {
+ visit(fileToBeAddedToTree, {type: 'element', tagName: editHtmlFile.codeBlock}, (htmlElement: any, index, parent) => {
+ parent.children.splice(index, 1);
+ });
+
+ return fileToBeAddedToTree;
+}
\ No newline at end of file
diff --git a/src/rz/html/delete-html-element/snapshots/delete-html-element-output.html.snap b/src/rz/html/delete-html-element/snapshots/delete-html-element-output.html.snap
new file mode 100644
index 0000000..e69de29
diff --git a/src/rz/html/delete-html-element/snapshots/delete-html-element.html.snap b/src/rz/html/delete-html-element/snapshots/delete-html-element.html.snap
new file mode 100644
index 0000000..2739a75
--- /dev/null
+++ b/src/rz/html/delete-html-element/snapshots/delete-html-element.html.snap
@@ -0,0 +1 @@
+Sample header
\ No newline at end of file
diff --git a/src/rz/html/prepend-html/prepend-html.spec.ts b/src/rz/html/prepend-html/prepend-html.spec.ts
new file mode 100644
index 0000000..1b5fc7e
--- /dev/null
+++ b/src/rz/html/prepend-html/prepend-html.spec.ts
@@ -0,0 +1,42 @@
+import { EditHtmlInput } from './../../angular/interfaces/edit-html.interface';
+import { readFileSync } from 'fs';
+import { morphHtml } from '../../angular/morph-angular-html';
+
+describe('prependHtml' , () => {
+ it('should prepend html code into root of html file', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/html/prepend-html/snapshots/prepend-html.html.snap').toString();
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'prependHtml',
+ codeBlock: '',
+ }
+ ]
+ };
+
+ const expected = readFileSync('src/rz/html/prepend-html/snapshots/prepend-html-output.html.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+
+ it('should prepend an html code inside of passed in optional element', () => {
+ const fileToBeAddedTo = readFileSync('src/rz/html/prepend-html/snapshots/prepend-html-into-element/prepend-html-into-element.html.snap').toString();
+
+ const editHtmlInput: EditHtmlInput = {
+ fileToBeAddedTo: fileToBeAddedTo,
+ edits: [
+ {
+ nodeType: 'prependHtml',
+ codeBlock: '
test
',
+ tagNameToInsertInto: 'mat-toolbar'
+ }
+ ]
+ };
+
+ const expected = readFileSync('src/rz/html/prepend-html/snapshots/prepend-html-into-element/prepend-html-into-element-ouput.html.snap').toString();
+ const newHtmlString = morphHtml(editHtmlInput);
+ expect(newHtmlString).toEqual(expected);
+ });
+});
\ No newline at end of file
diff --git a/src/rz/html/prepend-html/prepend-html.ts b/src/rz/html/prepend-html/prepend-html.ts
new file mode 100644
index 0000000..25fdeed
--- /dev/null
+++ b/src/rz/html/prepend-html/prepend-html.ts
@@ -0,0 +1,21 @@
+import { createUnifiedTree } from '../../angular/morph-angular-html';
+import visit = require('unist-util-visit');
+import { EditHtmlFile } from "../../angular/interfaces/edit-html.interface";
+
+export function prependHtml(editHtmlFile: EditHtmlFile, fileToBeAddedToTree: any): any {
+ let counter = 0;
+ let elementToReturn: any;
+
+ const element = editHtmlFile.tagNameToInsertInto ? {type: 'element', tagName: editHtmlFile.tagNameToInsertInto} : {type: 'element', tagName: 'body'};
+
+ visit(fileToBeAddedToTree, element, (htmlElement: any) => {
+ const codeToAddTree = createUnifiedTree(editHtmlFile.codeBlock as string);
+ if(counter === 0) {
+ htmlElement.children.unshift(codeToAddTree);
+ elementToReturn = editHtmlFile.tagNameToInsertInto ? htmlElement : htmlElement.children;
+ counter++;
+ }
+ });
+
+ return elementToReturn;
+}
\ No newline at end of file
diff --git a/src/rz/html/prepend-html/snapshots/prepend-html-into-element/prepend-html-into-element-ouput.html.snap b/src/rz/html/prepend-html/snapshots/prepend-html-into-element/prepend-html-into-element-ouput.html.snap
new file mode 100644
index 0000000..32a3eb3
--- /dev/null
+++ b/src/rz/html/prepend-html/snapshots/prepend-html-into-element/prepend-html-into-element-ouput.html.snap
@@ -0,0 +1,4 @@
+