angularjs-to-angular
Migrate an AngularJS codebase to an Angular codebase
Example
constants:
angular_directory: 'angular'
src_directory: '{{ angular_directory }}/src'
app_directory: '{{ src_directory }}/app'
assets_directory: '{{ src_directory }}/assets'
entry_file_path: '{{ src_directory }}/main.ts'
entry_file_path_template: '{{ src_directory }}/index.html'
constants_directory: '{{ app_directory }}/constants'
components_directory: '{{ app_directory }}/components'
services_directory: '{{ app_directory }}/services'
directives_directory: '{{ app_directory }}/directives'
pipes_directory: '{{ app_directory }}/pipes'
modules_directory: '{{ app_directory }}/modules'
context_depth: 3
dependencies:
- 'rxjs'
- '@angular/router'
- '@angular/forms'
- '@angular/common'
- '@angular/platform-browser'
- '@angular/platform-browser-dynamic'
dev_dependencies:
- '@angular/cli'
library_mappings: |
- All `$http` and `$httpProvider` usages should be converted/replaced with `HttpClient` from `@angular/common/http`. IMPORTANT: Always use `provideHttpClient(withInterceptorsFromDi())` instead of `HttpClientModule`.
- All `$location` usages should be converted/replaced with Angular 16's `Router`.
- All `$scope` usages should be converted/replaced with component properties and Angular 16's data binding.
- All `angular-aria` usages should be handled with Angular 16's built-in accessibility features.
- All `angular-loader` usages should be converted/replaced with Angular 16's lazy loading modules.
- All `angular-messages` usages should be converted/replaced with Angular 16's form validation features.
- All `angular-resource` usages should be converted/replaced with `HttpClient`.
- All `angular-route` usages should be converted/replaced with `@angular/router`.
- All `angular-touch` usages should be converted/replaced with Angular 16's event handling.
- All `$timeout` usages should be converted/replaced with the `setTimeout` function.
- All `$interval` usages should be converted/replaced with the `setInterval` function.
- All `angular.noop` usages should be converted/replaced with the rxjs `noop` function (don't forget to import it from `rxjs`).
transformation_notes: |
## Codebase Transformation Notes
> IMPORTANT: YOU MUST ALWAYS OUTPUT CODE (Typescript, HTML, or SCSS) THAT IS VALID AND COMPATIBLE WITH ANGULAR 16. NEVER OUTPUT ANGULARJS CODE.
### Generation Preferences
When generating code, follow these guidelines:
- Only include information from the portion you were told to convert.
- Do not create new configs, components, or example usages.
- Remove AngularJS-specific elements that cannot be converted to Angular 16.
- Leave empty functions as they are.
- If the current file path was provided above, you should ensure that the import paths are relative to this path.
- At the top of the converted file, you should include a comment with the original file path. Something like `// Converted from <original-file-path>`.
- The resulting code should be DRY and only declare one component per file.
- The resulting code should be written in TypeScript.
- You should always define and export classes or functions as appropriate.
- Always include comments from the original code that are still relevant after conversion.
- ALWAYS use ES6+ syntax for typescript code. That means use the spread operator, arrow functions, etc where possible.
- Prefer to use async/await over promises wherever possible. For example, `await somePromise` is better than `somePromise.then(...)`, making the surrounding function async as needed. If the function is a built-in angular method, you should not make it async as that is not an allowed pattern.
- When setting variables to undefined values, use `null` instead.
- Prefer Angular 16's dependency injection and service mechanisms.
- Do not hallucinate!
### AngularJS to Angular 16 Conversion Guidelines
- AngularJS `ng-` and `data-ng-` directives and attributes should be converted to the Angular 16-equivalent logic. Do not leave these in the template.
- Special built-in AngularJS services and factories, typically defined as `$<service-name>`, should be converted to Angular 16-equivalent logic.
- AngularJS injectors are no longer needed in Angular 16 (since Angular uses its own dependency injection mechanism).
- Local variables accessed through `$ctrl` or `$scope` in AngularJS should be converted to direct references in Angular 16. In templates, replace `$ctrl.myVar` or `$scope.myVar` with just `myVar`. In TypeScript files, replace references to `$ctrl` or `$scope` properties with direct class property/method access.
- Whenever you see some variable (e.g. `myVar`) passed in with the AngularJS one-way binding shorthand (e.g. `data-users-in-org="::$ctrl.myVar"`), you should convert it to `myVar` in the template (e.g. `usersInOrg="myVar"`).
- All events that start with `ng-` or `data-ng-` should be converted/replaced with their Angular 16-equivalent. For example, both `ng-click` and `data-ng-click` should be converted/replaced with `(click)` event binding, both `ng-change` and `data-ng-change` should be converted/replaced with `(change)` event binding, etc.
- All attributes that start with `data-ng-` should be converted/replaced with their Angular 16-equivalent. For example, both `ng-class` and `data-ng-class` should be converted/replaced with `[ngClass]` directive, both `ng-href` and `data-ng-href` should be converted/replaced with `[href]` property binding, etc.
- All `ng-model` or `data-ng-model` usages should be converted/replaced with `[(ngModel)]` for two-way data binding.
- All `ng-disabled` or `data-ng-disabled` usages should be converted/replaced with `[disabled]` property binding.
- All `ng-style` or `data-ng-style` usages should be converted/replaced with `[ngStyle]` directive.
- All `ng-repeat` or `data-ng-repeat` usages should be converted/replaced with `*ngFor` directive. All *ngFor directives must also include `trackby` with a trackby function.
- All `ng-if` or `data-ng-if` usages should be converted/replaced with `*ngIf` directive.
- All `ng-show` or `data-ng-show` and `ng-hide` or `data-ng-hide` usages should be converted/replaced with `*ngIf` or `[hidden]` property binding.
- All `ng-bind-html` or `data-ng-bind-html` usages should be converted/replaced with `[innerHTML]` property binding.
- All `ng-bind` or `data-ng-bind` usages should be converted/replaced with `{{ }}` interpolation.
- All `ng-class` or `data-ng-class` usages should be converted/replaced with `[ngClass]` directive.
- All `ng-transclude` or `data-ng-transclude` usages should be converted/replaced with Angular 16's `<ng-content>`. For named slots, use `<ng-content select="[slot-name]"></ng-content>`.
- All `ng-include` or `data-ng-include` usages should be converted/replaced with the corresponding Angular 16 component. Use the component's selector in place of the ng-include reference (e.g., `<my-component>`), assuming the component has already been converted according to the “New Files” criteria below.
### New Files
When defining new files based on unconverted files, assume the following naming strategies (useful for imports):
- AngularJS constants and values → TypeScript constants exported as the name of the constant in `{{ constants_directory }}/<constant-name>.ts`.
- AngularJS services, factories, and providers → Angular services in `{{ services_directory }}/<current-file-name>.service.ts`. Each service should be decorated with `@Injectable()` and properly provided in modules.
- AngularJS pure directives (directives without templates) → Angular directives in `{{ directives_directory }}/<current-file-name>.directive.ts`.
- AngularJS filters → Angular pipes in `{{ pipes_directory }}/<current-file-name>.pipe.ts`.
- AngularJS controllers, components, and directives with templates → Angular components in `{{ components_directory }}/<current-file-name>.component.ts` (note: we keep the components structure flat with no folder nesting.) This will export a single default class.
- AngularJS template HTML files → Angular template HTML in `{{ components_directory }}/<current-file-name>.html`.
- AngularJS config and routes → Angular modules and routing modules in `{{ modules_directory }}/<current-file-name>.module.ts`.
### Libraries
The following libraries are already installed in the project and available for you to use (in addition to the default Angular 16 libraries): {{ dependencies }}
#### Mapping AngularJS libraries and features to Angular 16-compatible libraries and features:
{{ library_mappings }}
ignore_file_paths:
- 'gulpfile.js'
- 'LICENSE'
- '**/test/**'
- 'test/**'
- 'package.json'
- '.gitignore'
- 'tsconfig.json'
- 'README.md'
- '**/{{ angular_directory }}'
- '**/{{ angular_directory }}/**'
- '*.config$'
- '**/public/**'
- '**/lib/**'
steps:
- name: Create Angular app
tools:
- name: run_terminal_command
arguments:
command: 'npx @angular/cli@latest new {{ angular_directory }} --routing --style=scss'
- name: Install dependencies
tools:
- name: for_each
items: '{{ dependencies }}'
each_item:
item_name: dependency
tools:
- name: run_terminal_command
arguments:
path_to_directory: '{{ angular_directory }}'
command: 'npm install {{ dependency }} --save'
- name: for_each
items: '{{ dev_dependencies }}'
each_item:
item_name: dependency
tools:
- name: run_terminal_command
arguments:
path_to_directory: '{{ angular_directory }}'
command: 'npm install {{ dependency }} --save-dev'
- name: Update tsconfig to be stricter
tools:
- name: find_files_by_name_with_regex
arguments:
find_file_name_pattern: 'tsconfig\.json'
returns: tsconfig_file_paths
- name: get_first
arguments:
array: '{{ tsconfig_file_paths }}'
returns: tsconfig_file_path
- name: edit_json
arguments:
path_to_file: '{{ tsconfig_file_path }}'
json_path: 'compilerOptions'
action: 'add'
values:
- key: 'noUnusedLocals'
value: true
- key: 'noUnusedParameters'
value: true
- name: Build a dependency graph of the codebase
tools:
- name: build_dependency_graph_with_ai
arguments:
exclude_path_patterns: '{{ ignore_file_paths }}'
- name: Convert files in order
tools:
- name: get_files_in_topological_order
arguments:
top_down: true
returns: conversion_order_by_level
- name: for_each
items: '{{ conversion_order_by_level }}'
each_item:
item_name: level
tools:
- name: async_each
items: '{{ level }}'
each_item:
item_name: file_to_convert
tools:
- name: get_content_from_file
arguments:
path_to_file: '{{ file_to_convert }}'
returns: file_contents
- name: get_file_long_context
arguments:
path_to_file: '{{ file_to_convert }}'
depth: '{{ context_depth }}'
graph_type: 'embedding'
returns: file_context
- name: get_file_name
arguments:
path_to_file: '{{ file_to_convert }}'
include_extension: false
returns: file_name
# - name: hash_string
# arguments:
# input_string: '{{ file_to_convert }}'
# max_length: 10
# returns: file_hash
- name: switch
content: |
## {{ file_to_convert }}
```
{{ file_contents }}
```
cases:
# Try to update the index.html file
- condition_prompt: Is this the root entry point template file for the AngularJS app? Typically, this is named something like `index.html`, has lots of imports, and sometimes has an `ng-app` directive.
break: true
tools:
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code to convert to Angular ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Convert the AngularJS template code to be compatible with Angular and MERGE that code with the existing content in the file.
- Do not just concatenate converted parts together; you should rewrite so that the code is DRY without losing or changing any functionality.
- If there are no changes to make, return an empty code block (``````).
- The resulting code should be a valid entry point template file for Angular.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ entry_file_path_template }}'
edit_prompts: '{{ chunked_prompts }}'
- name: mark_files_converted_in_context
arguments:
done_converting: true
old_file_path: '{{ file_to_convert }}'
new_file_paths:
- '{{ entry_file_path_template }}'
# Check for root entry point logic file
- condition_prompt: Is this the root entry point logic file for the AngularJS app? Typically, this is named something like `main.js` or `app.js`.
break: true
tools:
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code to convert to Angular ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Convert the AngularJS logic code to be compatible with Angular and MERGE that code with the existing content in the file.
- Do not just concatenate converted parts together; you should rewrite so that the code is DRY without losing or changing any functionality.
- If there are no changes to make, return an empty code block (``````).
- The resulting code should be valid Angular code in TypeScript.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ entry_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths:
- '{{ entry_file_path }}'
# Templates
- condition_prompt: Is this file an AngularJS template? (is it an `.html` file?)
break: true
tools:
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code to convert to Angular ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- The component, controller, or directive ts logic file related to this template will be converted in a later step.
{{ transformation_notes }}
returns: chunked_prompts
- name: make_variable
arguments:
value: '{{ components_directory }}/{{ file_name }}.html'
returns: template_file_path
- name: edit_file_long_context
arguments:
path_to_file: '{{ template_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths:
- '{{ template_file_path }}'
# Constants or Values
- condition_prompt: Does this file contain an AngularJS constant or value definition? (Does it contain `.constant(...)` or `.value(...)`?)
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each constant or value defined in the file. This is the string declared as the first argument to `.constant(...)` or `.value(...)`. If there are none, return an empty array.'
results_as_array: true
returns: constant_or_value_names
- name: async_each
items: '{{ constant_or_value_names }}'
returns_key: constant_file_path
each_item:
item_name: constant_or_value_name
tools:
- name: make_variable
arguments:
value: '{{ constants_directory }}/{{ constant_or_value_name }}.ts'
returns: constant_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ constant_or_value_name }}` from the above AngularJS code and convert it to a TypeScript constant for Angular.
- Only extract and convert `{{ constant_or_value_name }}` and its relevant information to make it work in Angular on its own. Ignore anything else.
- The resulting file will be created at {{ constant_file_path }}.
- Constants should be properly exported and can be imported and used in other files.
- Use appropriate Angular patterns and modules.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ constant_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ file_paths }}'
# Filters to Pipes
- condition_prompt: Does this file contain an AngularJS filter definition? (Does it contain `.filter(...)`?)
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each filter defined in the file. This is the string declared as the first argument to `.filter(...)`. If there are none, return an empty array.'
results_as_array: true
returns: filter_names
- name: async_each
items: '{{ filter_names }}'
returns_key: pipe_file_path
each_item:
item_name: filter_name
tools:
- name: make_variable
arguments:
value: '{{ pipes_directory }}/{{ filter_name }}.pipe.ts'
returns: pipe_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ filter_name }}` from the above AngularJS code and convert it to an Angular pipe.
- Only extract and convert `{{ filter_name }}` and its relevant information to make it work in Angular on its own. Ignore anything else.
- The resulting file will be created at {{ pipe_file_path }}.
- Pipes should be properly decorated with `@Pipe` and exported.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ pipe_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ file_paths }}'
# Services
- condition_prompt: Does this file contain an AngularJS service definition? (Does it contain `.service(...)` or `.factory(...)`, or `.provider(...)`?)
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each service defined in the file. This is the string declared as the first argument to `.service(...)` or `.factory(...)`, or `.provider(...)`. If there are none, return an empty array.'
results_as_array: true
returns: service_names
- name: async_each
items: '{{ service_names }}'
returns_key: service_file_path
each_item:
item_name: service_name
tools:
- name: make_variable
arguments:
value: '{{ services_directory }}/{{ service_name }}.service.ts'
returns: service_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ service_name }}` from the above AngularJS code and convert it to an Angular service.
- Only extract and convert `{{ service_name }}` and its relevant information to make it work in Angular on its own. Ignore anything else.
- The resulting file will be created at {{ service_file_path }}.
- Services should be properly decorated with `@Injectable()` and exported.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ service_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ file_paths }}'
# Configs and Routes
- condition_prompt: Does this file contain an AngularJS config definition (does it contain `.config(...)`) or AngularJS routes definitions (`$routeProvider.when(...)`, `$stateProvider.state(...)`, or some obvious URL paths that should be included in the Angular Router)?
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each config defined in the file. This is the string declared as the first argument to `.config(...)`. If there is no name defined, use the name of the function or object passed into `.config(...)`. If it is defined inline, invent a name for the function or object and use that name. If there are none, return an empty array.'
results_as_array: true
returns: config_names
- name: async_each
items: '{{ config_names }}'
returns_key: file_paths
each_item:
item_name: config_name
tools:
- name: ask_question
arguments:
question_prompt: |
Does the config `{{ config_name }}` contain routes definitions that should be included in the Angular Router? Does it contain `$routeProvider.when(...)`, `$stateProvider.state(...)`, or any obvious URL paths?
```
{{ file_contents }}
```
returns: has_routes
- name: if_else
condition: '{{ has_routes }}'
returns_key: module_file_path
if:
tools:
# Convert to routing module
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code to convert to Angular ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract the route definitions from the above AngularJS code specific to `{{ config_name }}`.
- Only consider the route definitions and related variables for `{{ config_name }}`. Ignore all other code.
- Convert the extracted route code to use Angular Router.
- Ensure all previous functionality remains along with the new logic.
- Rewrite the code to be DRY without losing functionality. The result should be a valid Angular routing module.
- If there is no convertible code, return an empty string.
- Do not implement anything other than the router. Other logic will be converted in different steps.
{{ transformation_notes }}
returns: chunked_prompts
- name: make_variable
arguments:
value: '{{ modules_directory }}/{{ config_name }}.routing.module.ts'
returns: module_file_path
- name: edit_file_long_context
arguments:
path_to_file: '{{ module_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
else:
tools:
# Convert to Angular module
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ config_name }}` from the above AngularJS code and convert it to an Angular module.
- Only extract and convert `{{ config_name }}` and its relevant information. Ignore anything else.
- The resulting file will be created at {{ module_file_path }}.
- Modules should be decorated with `@NgModule` and include declarations, imports, providers, and exports as necessary.
{{ transformation_notes }}
returns: chunked_prompts
- name: make_variable
arguments:
value: '{{ modules_directory }}/{{ config_name }}.module.ts'
returns: module_file_path
- name: edit_file_long_context
arguments:
path_to_file: '{{ module_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: file_paths
returns: all_file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ all_file_paths }}'
# Directives
- condition_prompt: Does this file contain an AngularJS directive definition? (Does it contain `.directive(...)`?)
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each directive defined in the file. If there are none, return an empty array.'
results_as_array: true
returns: directive_names
- name: async_each
items: '{{ directive_names }}'
returns_key: directive_file_path
each_item:
item_name: directive_name
tools:
- name: ask_question
arguments:
question_prompt: |
Does the directive `{{ directive_name }}` have a template? It does if it references some other external html file or defines its template inline.
```
{{ file_contents }}
```
returns: has_template
- name: if_else
condition: '{{ has_template }}'
returns_key: result_file_path
if:
tools:
# Directives with templates become components
- name: make_variable
arguments:
value: '{{ components_directory }}/{{ directive_name }}.component.ts'
returns: result_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ directive_name }}` from the above AngularJS code and convert it to an Angular component.
- The resulting file will be created at: `{{ result_file_path }}`
- Components should be properly decorated with `@Component` and include the template and styles as necessary.
- Only convert the typescript logic. Do not convert html templates and css styles unless they are defined inline.
- Inputs should always have an `!` after them to denote they are initialized elsewhere. Example: `@Input() myInput!: string;`. `@Input() myInput: string;` will throw errors.
- You should always export a single default class from the component: `export default class ...`.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ result_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
else:
tools:
# This must be a pure directive
- name: make_variable
arguments:
value: '{{ directives_directory }}/{{ directive_name }}.directive.ts'
returns: result_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ directive_name }}` from the above AngularJS code and convert it to an Angular directive.
- The resulting file will be created at: `{{ result_file_path }}`
- Directives should be properly decorated with `@Directive` and exported.
- Inputs should always have an `!` after them to denote they are initialized elsewhere. Example: `@Input() myInput!: string;`. `@Input() myInput: string;` will throw errors.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ result_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: directive_file_path
returns: file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ file_paths }}'
# Controllers to Components
- condition_prompt: Does this file contain an AngularJS controller/component definition? (Does it contain `.controller(...)` or `.component(...)`?)
tools:
- name: find_content_in_file_with_ai
arguments:
path_to_file: '{{ file_to_convert }}'
find_context_prompt: 'Find and return JUST the name of each controller/component defined in the file. This is the string declared as the first argument to `.controller(...)` or `.component(...)`. If there are none, return an empty array.'
results_as_array: true
returns: controller_names
- name: async_each
items: '{{ controller_names }}'
returns_key: component_file_path
each_item:
item_name: controller_name
tools:
- name: make_variable
arguments:
value: '{{ components_directory }}/{{ controller_name }}.component.ts'
returns: component_file_path
- name: chunk_prompt
arguments:
contents:
- priority: 3
content: '{{ file_context }}'
- priority: 2
content: |
AngularJS Code ({{ file_to_convert }}):
```
{{ file_contents }}
```
- priority: 1
content: |
# Instructions
- Extract `{{ controller_name }}` from the above AngularJS code and convert it to an Angular component. that references the templateHTML file if necessary.
- Only extract and convert `{{ controller_name }}` and its relevant information to make it work in Angular on its own. Ignore anything else.
- The resulting files will be created at: `{{ component_file_path }}`
- Components should be properly decorated with `@Component` and include the template and styles as necessary.
- Only convert the controller/component typescript logic. Do not convert html templates and css styles unless they are defined inline.
- Inputs should always have an `!` after them to denote they are initialized elsewhere. Example: `@Input() myInput!: string;`. `@Input() myInput: string;` will throw errors.
{{ transformation_notes }}
returns: chunked_prompts
- name: edit_file_long_context
arguments:
path_to_file: '{{ component_file_path }}'
edit_prompts: '{{ chunked_prompts }}'
returns: file_paths
- name: mark_files_converted_in_context
arguments:
done_converting: false
old_file_path: '{{ file_to_convert }}'
new_file_paths: '{{ file_paths }}'
# Default case
default:
tools:
- name: echo_one
arguments:
echo_arg: 'Doing nothing with {{ file_to_convert }}'
# Mark file as converted
- name: mark_files_converted_in_context
arguments:
done_converting: true
old_file_path: '{{ file_to_convert }}'
- name: Combine Routes into app-routing.module.ts
tools:
- name: find_files_by_name_with_regex
arguments:
path_to_directory: '{{ modules_directory }}'
find_file_name_pattern: '.*\.routing\.module\.ts$'
returns: routing_module_paths
- name: get_content_from_files
arguments:
paths_to_files: '{{ routing_module_paths }}'
returns: routing_module_contents
- name: edit_file
arguments:
path_to_file: '{{ app_directory }}/app.routes.ts'
edit_prompt: |
The below code could contain Angular Router configurations. You should extract and add any routes directly into the `app.routes.ts` file, in addition to adding any comments that start with `// Converted from` that are present at the top of the file we are extracting from. Be meticulous and precise. Do not hallucinate.
## Routing Module Files
```
{{ routing_module_contents }}
```
# Delete routing modules now that they have been extracted into app.routes.ts
- name: for_each
items: '{{ routing_module_paths }}'
each_item:
item_name: routing_module_path
tools:
- name: delete_file_or_folder
arguments:
path_to_target: '{{ routing_module_path }}'
- name: Copy static assets
tools:
- name: find_files_by_name_with_regex
arguments:
path_to_directory: 'src'
find_file_name_pattern: .*\.(css|svg|png|jpg|jpeg|eot|ttf|otf|woff|woff2|gif|bmp|webp|webm|mp3)$
returns: static_asset_files
- name: for_each
items: '{{ static_asset_files }}'
each_item:
item_name: static_file
tools:
- name: copy_file
arguments:
source_path: '{{ static_file }}'
destination_path: '{{ assets_directory }}/{{ static_file }}'
returns: copied_file_path
- name: Add CSS imports to styles.css
tools:
- name: find_files_by_name_with_regex
arguments:
path_to_directory: '{{ assets_directory }}'
find_file_name_pattern: '.*\.css$'
returns: css_files
- name: edit_file
arguments:
path_to_file: '{{ src_directory }}/styles.css'
edit_prompt: |
Add CSS imports at the top of the file for the following CSS files:
```
{{ css_files }}
```
Use the appropriate syntax to import CSS files in Angular `styles.css`.
- name: Resolve import paths
tools:
- name: resolve_import_paths
arguments:
path_to_directory: '{{ angular_directory }}'
Last updated