Compare commits
28 Commits
nvidia-308
...
anims
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b042b36aea | ||
|
|
be7a886225 | ||
|
|
4ac1425f76 | ||
|
|
a721e82a4f | ||
|
|
98845e6cae | ||
|
|
19645248ab | ||
|
|
255c51c8a0 | ||
|
|
bbf3490e9c | ||
|
|
c7fa4b6d02 | ||
|
|
17152c84dc | ||
|
|
894687c0e0 | ||
|
|
fb08f03765 | ||
|
|
faa7a38a7d | ||
|
|
d5bbc321f9 | ||
|
|
ebd82853dd | ||
|
|
6142f3a297 | ||
|
|
63366a4ec2 | ||
|
|
55fa7eae71 | ||
|
|
a54e16488c | ||
|
|
b9c89b701f | ||
|
|
311fcb1813 | ||
|
|
aa4205ff7a | ||
|
|
937f4593d1 | ||
|
|
4da306b9f7 | ||
|
|
a5ffed4cd6 | ||
|
|
6ab6dacd1b | ||
|
|
d277139dd5 | ||
|
|
7af8daa341 |
@@ -3,7 +3,7 @@ root = true # Top-most EditorConfig file
|
|||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
|
||||||
[*.{js,jsx,ts,tsx,vue,sh}]
|
[*.{js,jsx,ts,tsx,vue,sh,scss}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
@@ -24,3 +24,10 @@ indent_style = space
|
|||||||
indent_size = 4
|
indent_size = 4
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{scss}] # SASS guidelines: https://archive.today/2024.02.16-232553/https://sass-guidelin.es/
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2 # Recommended by SASS guidelines
|
||||||
|
max_line_length = 100 # Recommended by SASS guidelines
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|||||||
3
.github/workflows/checks.external-urls.yaml
vendored
3
.github/workflows/checks.external-urls.yaml
vendored
@@ -3,6 +3,9 @@ name: checks.external-urls
|
|||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * 0' # at 00:00 on every Sunday
|
- cron: '0 0 * * 0' # at 00:00 on every Sunday
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- tests/checks/external-urls/**
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-check:
|
run-check:
|
||||||
|
|||||||
1
.github/workflows/release.desktop.yaml
vendored
1
.github/workflows/release.desktop.yaml
vendored
@@ -20,6 +20,7 @@ jobs:
|
|||||||
fetch-depth: 0 # fetch all history
|
fetch-depth: 0 # fetch all history
|
||||||
-
|
-
|
||||||
name: Checkout to bump commit
|
name: Checkout to bump commit
|
||||||
|
shell: bash
|
||||||
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
|
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
|
||||||
-
|
-
|
||||||
name: Setup node
|
name: Setup node
|
||||||
|
|||||||
31
2
31
2
@@ -1,31 +0,0 @@
|
|||||||
Show error on AV removal on desktop $264, $304
|
|
||||||
|
|
||||||
This solves $264 where users do not get error messages when running
|
|
||||||
script file fails due to antivirus intervention (it being blocking the
|
|
||||||
script file as soon as privacy.sexy generates it to run it). Now if the
|
|
||||||
desktop app users tries to save or run a script file and it afils due to
|
|
||||||
antivirus removal, they'll get a special error message with guiding next
|
|
||||||
steps.
|
|
||||||
|
|
||||||
- Add additional check to able to fail if the file writing fails. This
|
|
||||||
includes trying to reading the written file back as suggested in $304.
|
|
||||||
This successfully detects antivirus (Defender) intervation as read
|
|
||||||
file operation triggers the antivirus scan that deletes the file.
|
|
||||||
- Show directory and file path in error messages as suggested in $304.
|
|
||||||
- Show an error message with more detailed information if an antivirus
|
|
||||||
is detected.
|
|
||||||
|
|
||||||
# Please enter the commit message for your changes. Lines starting
|
|
||||||
# with '#' will be ignored, and an empty message aborts the commit.
|
|
||||||
#
|
|
||||||
# Date: Tue Jan 16 16:23:08 2024 +0100
|
|
||||||
#
|
|
||||||
# On branch master
|
|
||||||
# Your branch is ahead of 'origin/master' by 1 commit.
|
|
||||||
# (use "git push" to publish your local commits)
|
|
||||||
#
|
|
||||||
# Changes to be committed:
|
|
||||||
# modified: ../../application/CodeRunner/CodeRunner.ts
|
|
||||||
# new file: NodeReliableFileWriter.ts
|
|
||||||
# new file: ReliableFileWriter.ts
|
|
||||||
#
|
|
||||||
29
CHANGELOG.md
29
CHANGELOG.md
@@ -1,5 +1,34 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.13.0 (2024-02-11)
|
||||||
|
|
||||||
|
* win: add disabling clipboard features #251, #247 | [c6ebba8](https://github.com/undergroundwires/privacy.sexy/commit/c6ebba85fb1b362be0d81d3078f19db71e0528b2)
|
||||||
|
* win: improve search privacy scripts #117 | [541f9aa](https://github.com/undergroundwires/privacy.sexy/commit/541f9aa5ee1b5f4885063b65beaf6cd873f0d786)
|
||||||
|
* win: add disabling Windows Copilot #263, #266 | [cd42550](https://github.com/undergroundwires/privacy.sexy/commit/cd425502ae882bba9642dc2171c2b5771946b5a9)
|
||||||
|
* win: add Dropbox telemetry blocking #125, #118 | [10829d6](https://github.com/undergroundwires/privacy.sexy/commit/10829d65aa3fb0df937bb8829244e6290bb748c7)
|
||||||
|
* Improve selection type documentation | [7af8daa](https://github.com/undergroundwires/privacy.sexy/commit/7af8daa3411b24efb6385c7876a49bd372753f38)
|
||||||
|
* Expand script names to take full available width | [d277139](https://github.com/undergroundwires/privacy.sexy/commit/d277139dd50eeb4e4057b0a7d8fc4ac2d70785de)
|
||||||
|
* Limit tooltip width for improved readability | [6ab6dac](https://github.com/undergroundwires/privacy.sexy/commit/6ab6dacd1be2d7bf1863b07b121d86f2a379ac67)
|
||||||
|
* Add markdown support for script/category names | [a5ffed4](https://github.com/undergroundwires/privacy.sexy/commit/a5ffed4cd60d9d058d5374145c1176b10fad1660)
|
||||||
|
* Normalize and improve font sizes | [4da306b](https://github.com/undergroundwires/privacy.sexy/commit/4da306b9f79b0bb7a64bb197fb246258cf435b8d)
|
||||||
|
* Change 'revert' button to title case | [937f459](https://github.com/undergroundwires/privacy.sexy/commit/937f4593d1a91081ab6b1bcb8f85d03879d7cf07)
|
||||||
|
* Remove playful emojis (🍑🍆) | [aa4205f](https://github.com/undergroundwires/privacy.sexy/commit/aa4205ff7af7d05cfb5e82bf541b521d49bbd1c8)
|
||||||
|
* Improve UI code styling for all platforms | [311fcb1](https://github.com/undergroundwires/privacy.sexy/commit/311fcb18133d1343f6a9ae5bd7a25795a1d12c49)
|
||||||
|
* Render bracket references as superscript text | [b9c89b7](https://github.com/undergroundwires/privacy.sexy/commit/b9c89b701fc77d20dcc706419a8659ad156c4fc2)
|
||||||
|
* Change slogan and refactor project info naming | [a54e164](https://github.com/undergroundwires/privacy.sexy/commit/a54e16488ce32219bcf811b5da85f06584b293fb)
|
||||||
|
* Add 'Revert All Selection' feature #68 | [55fa7ea](https://github.com/undergroundwires/privacy.sexy/commit/55fa7eae71031357d6f03f0d349a09cd446270d3)
|
||||||
|
* win, mac, linux: add privacy.sexy cleanup scripts | [63366a4](https://github.com/undergroundwires/privacy.sexy/commit/63366a4ec2533a376849d692211e9972b56ab4a8)
|
||||||
|
* Extend search by including documentation content | [6142f3a](https://github.com/undergroundwires/privacy.sexy/commit/6142f3a2973d20493f784f323f3be57fa8deaeef)
|
||||||
|
* Remove 'preview' label from Linux options | [ebd8285](https://github.com/undergroundwires/privacy.sexy/commit/ebd82853ddc56f1cc2fc9be3fe0b3001b07f0186)
|
||||||
|
* Change fonts for improved readability | [d5bbc32](https://github.com/undergroundwires/privacy.sexy/commit/d5bbc321f902dc60618ffdfda0d583a4a433f7af)
|
||||||
|
* Apply global styles for visual consistency | [faa7a38](https://github.com/undergroundwires/privacy.sexy/commit/faa7a38a7d16390f27e4a3e51017b81665cf85ca)
|
||||||
|
* Add UI animations for expand/collapse actions | [fb08f03](https://github.com/undergroundwires/privacy.sexy/commit/fb08f037651e1a7d453b9a6af724cbccecc5b903)
|
||||||
|
* win: relocate service disabling and improve docs | [894687c](https://github.com/undergroundwires/privacy.sexy/commit/894687c0e0375a24f40bcd720ea69c9b2aa62a58)
|
||||||
|
* win: add host blocking category #26 | [17152c8](https://github.com/undergroundwires/privacy.sexy/commit/17152c84dc639e75560998a6feddfd46e0f713ce)
|
||||||
|
* Update meta title and description | [c7fa4b6](https://github.com/undergroundwires/privacy.sexy/commit/c7fa4b6d020ac6fd3bf72bb4e57022dffb1ba921)
|
||||||
|
|
||||||
|
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.10...0.13.0)
|
||||||
|
|
||||||
## 0.12.10 (2024-01-17)
|
## 0.12.10 (2024-01-17)
|
||||||
|
|
||||||
* Fix CSP for Vue, Ace, Vite, Safari compatibility | [940febc](https://github.com/undergroundwires/privacy.sexy/commit/940febc3e80cfd0c01b5cc8282ebaab6b024d1b5)
|
* Fix CSP for Vue, Ace, Vite, Safari compatibility | [940febc](https://github.com/undergroundwires/privacy.sexy/commit/940febc3e80cfd0c01b5cc8282ebaab6b024d1b5)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# privacy.sexy — Now you have the choice
|
# privacy.sexy — Privacy is sexy
|
||||||
|
|
||||||
> Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆
|
> Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.
|
||||||
|
|
||||||
<!-- markdownlint-disable MD033 -->
|
<!-- markdownlint-disable MD033 -->
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
|
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
|
||||||
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.10/privacy.sexy-Setup-0.12.10.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.10/privacy.sexy-0.12.10.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.10/privacy.sexy-0.12.10.AppImage). For more options, see [here](#additional-install-options).
|
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-Setup-0.13.0.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-0.13.0.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-0.13.0.AppImage). For more options, see [here](#additional-install-options).
|
||||||
|
|
||||||
For a detailed comparison of features between the desktop and web versions of privacy.sexy, see [Desktop vs. Web Features](./docs/desktop-vs-web-features.md).
|
For a detailed comparison of features between the desktop and web versions of privacy.sexy, see [Desktop vs. Web Features](./docs/desktop-vs-web-features.md).
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ privacy.sexy adopts a defense in depth strategy to protect users on multiple lay
|
|||||||
- **Auditing and Transparency:**
|
- **Auditing and Transparency:**
|
||||||
The desktop application improves security and transparency by logging application activities and retaining files of executed scripts
|
The desktop application improves security and transparency by logging application activities and retaining files of executed scripts
|
||||||
This facilitates detailed auditability and effective troubleshooting, contributing to the integrity and reliability of the application.
|
This facilitates detailed auditability and effective troubleshooting, contributing to the integrity and reliability of the application.
|
||||||
|
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these logs.
|
||||||
- **Privilege Management:**
|
- **Privilege Management:**
|
||||||
The desktop application operates without persistent administrative or `sudo` privileges, reinforcing its security posture. It requests
|
The desktop application operates without persistent administrative or `sudo` privileges, reinforcing its security posture. It requests
|
||||||
elevation of privileges for system modifications with explicit user consent and logs every action taken with high privileges. This
|
elevation of privileges for system modifications with explicit user consent and logs every action taken with high privileges. This
|
||||||
@@ -45,6 +46,7 @@ privacy.sexy adopts a defense in depth strategy to protect users on multiple lay
|
|||||||
Before executing any script, the desktop application stores a copy to allow antivirus software to perform scans. This safeguards against
|
Before executing any script, the desktop application stores a copy to allow antivirus software to perform scans. This safeguards against
|
||||||
any unwanted modifications. Furthermore, the application incorporates integrity checks for tamper protection. If the script file differs from
|
any unwanted modifications. Furthermore, the application incorporates integrity checks for tamper protection. If the script file differs from
|
||||||
the user's selected script, the application will not execute or save the script, ensuring the processing of authentic scripts.
|
the user's selected script, the application will not execute or save the script, ensuring the processing of authentic scripts.
|
||||||
|
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these scripts.
|
||||||
|
|
||||||
### Update Security and Integrity
|
### Update Security and Integrity
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ Log file locations vary by operating system:
|
|||||||
- Linux: `$HOME/.config/privacy.sexy/logs`
|
- Linux: `$HOME/.config/privacy.sexy/logs`
|
||||||
- Windows: `%APPDATA%\privacy.sexy\logs`
|
- Windows: `%APPDATA%\privacy.sexy\logs`
|
||||||
|
|
||||||
|
> 💡 privacy.sexy provides scripts to securely erase these logs.
|
||||||
|
|
||||||
### Script execution
|
### Script execution
|
||||||
|
|
||||||
The desktop version of privacy.sexy enables direct script execution, providing a seamless and integrated experience.
|
The desktop version of privacy.sexy enables direct script execution, providing a seamless and integrated experience.
|
||||||
@@ -65,6 +67,8 @@ These locations vary based on the operating system:
|
|||||||
- Linux: `$HOME/.config/privacy.sexy/runs`
|
- Linux: `$HOME/.config/privacy.sexy/runs`
|
||||||
- Windows: `%APPDATA%\privacy.sexy\runs`
|
- Windows: `%APPDATA%\privacy.sexy\runs`
|
||||||
|
|
||||||
|
> 💡 privacy.sexy provides scripts to securely erase your script execution history.
|
||||||
|
|
||||||
### Error handling
|
### Error handling
|
||||||
|
|
||||||
The desktop version of privacy.sexy features advanced error handling capabilities.
|
The desktop version of privacy.sexy features advanced error handling capabilities.
|
||||||
|
|||||||
@@ -32,7 +32,12 @@ The presentation layer uses an event-driven architecture for bidirectional react
|
|||||||
|
|
||||||
## Visual design best-practices
|
## Visual design best-practices
|
||||||
|
|
||||||
Add visual clues for clickable items. It should be as clear as possible that they're interactable at first look without hovering. They should also have different visual state when hovering/touching on them that indicates that they are being clicked, which helps with accessibility.
|
- **Clickables**:
|
||||||
|
Add visual clues for clickable items.
|
||||||
|
It should be as clear as possible that they're interactable at first look without hovering.
|
||||||
|
They should also have different visual state when hovering/touching on them that indicates that they are being clicked, which helps with accessibility.
|
||||||
|
- **Borders**:
|
||||||
|
privacy.sexy prefers sharper edges in its design language.
|
||||||
|
|
||||||
## Application data
|
## Application data
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
import { mergeConfig, UserConfig } from 'vite';
|
import { mergeConfig, type UserConfig } from 'vite';
|
||||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
|
||||||
import { getAliases, getClientEnvironmentVariables } from './vite-config-helper';
|
import { getAliases, getClientEnvironmentVariables } from './vite-config-helper';
|
||||||
import { createVueConfig } from './vite.config';
|
import { createVueConfig } from './vite.config';
|
||||||
|
|||||||
4238
package-lock.json
generated
4238
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "privacy.sexy",
|
"name": "privacy.sexy",
|
||||||
"version": "0.12.10",
|
"version": "0.13.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"slogan": "Now you have the choice",
|
"slogan": "Privacy is sexy",
|
||||||
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆",
|
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
|
||||||
"author": "undergroundwires",
|
"author": "undergroundwires",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/vue": "^1.0.2",
|
"@floating-ui/vue": "^1.0.2",
|
||||||
"@juggle/resize-observer": "^3.4.0",
|
"@juggle/resize-observer": "^3.4.0",
|
||||||
|
"@types/markdown-it": "^13.0.7",
|
||||||
"ace-builds": "^1.30.0",
|
"ace-builds": "^1.30.0",
|
||||||
"electron-log": "^5.0.1",
|
"electron-log": "^5.0.1",
|
||||||
"electron-progressbar": "^2.1.0",
|
"electron-progressbar": "^2.1.0",
|
||||||
@@ -44,14 +45,14 @@
|
|||||||
"vue": "^3.3.7"
|
"vue": "^3.3.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
||||||
"@rushstack/eslint-patch": "^1.6.1",
|
"@rushstack/eslint-patch": "^1.6.1",
|
||||||
"@types/ace": "^0.0.49",
|
"@types/ace": "^0.0.49",
|
||||||
"@types/file-saver": "^2.0.5",
|
"@types/file-saver": "^2.0.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
||||||
"@typescript-eslint/parser": "^6.17.0",
|
"@typescript-eslint/parser": "^6.17.0",
|
||||||
"@vitejs/plugin-legacy": "^4.1.1",
|
"@vitejs/plugin-legacy": "^5.3.2",
|
||||||
"@vitejs/plugin-vue": "^4.4.0",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vue/eslint-config-airbnb-with-typescript": "^8.0.0",
|
"@vue/eslint-config-airbnb-with-typescript": "^8.0.0",
|
||||||
"@vue/eslint-config-typescript": "^12.0.0",
|
"@vue/eslint-config-typescript": "^12.0.0",
|
||||||
"@vue/test-utils": "^2.4.1",
|
"@vue/test-utils": "^2.4.1",
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
"electron-builder": "^24.6.4",
|
"electron-builder": "^24.6.4",
|
||||||
"electron-devtools-installer": "^3.2.0",
|
"electron-devtools-installer": "^3.2.0",
|
||||||
"electron-icon-builder": "^2.0.1",
|
"electron-icon-builder": "^2.0.1",
|
||||||
"electron-vite": "^1.0.28",
|
"electron-vite": "^2.1.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-plugin-cypress": "^2.15.1",
|
"eslint-plugin-cypress": "^2.15.1",
|
||||||
"eslint-plugin-vue": "^9.19.2",
|
"eslint-plugin-vue": "^9.19.2",
|
||||||
@@ -79,8 +80,8 @@
|
|||||||
"svgexport": "^0.4.2",
|
"svgexport": "^0.4.2",
|
||||||
"terser": "^5.21.0",
|
"terser": "^5.21.0",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^4.4.11",
|
"vite": "^5.1.6",
|
||||||
"vitest": "^0.34.6",
|
"vitest": "^0.34.6",
|
||||||
"vue-tsc": "^1.8.19",
|
"vue-tsc": "^1.8.19",
|
||||||
"yaml-lint": "^1.7.0"
|
"yaml-lint": "^1.7.0"
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ development and installs recommended extensions from '.vscode/extensions.json'.
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
from typing import Any
|
from typing import Any, Optional
|
||||||
from shutil import which
|
from shutil import which
|
||||||
|
|
||||||
VSCODE_SETTINGS_JSON_FILE: str = '.vscode/settings.json'
|
VSCODE_SETTINGS_JSON_FILE: str = '.vscode/settings.json'
|
||||||
@@ -84,7 +85,7 @@ def install_recommended_extensions() -> None:
|
|||||||
if not extensions:
|
if not extensions:
|
||||||
print_skip(f"No recommendations found in the {VSCODE_EXTENSIONS_JSON_FILE} file.")
|
print_skip(f"No recommendations found in the {VSCODE_EXTENSIONS_JSON_FILE} file.")
|
||||||
return
|
return
|
||||||
vscode_cli_path = which('code') # More reliable than using `code`, especially on Windows.
|
vscode_cli_path = locate_vscode_cli()
|
||||||
if vscode_cli_path is None:
|
if vscode_cli_path is None:
|
||||||
print_error('Visual Studio Code CLI (`code`) tool not found.')
|
print_error('Visual Studio Code CLI (`code`) tool not found.')
|
||||||
return
|
return
|
||||||
@@ -92,11 +93,23 @@ def install_recommended_extensions() -> None:
|
|||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
print_error(f"Invalid JSON in {VSCODE_EXTENSIONS_JSON_FILE}")
|
print_error(f"Invalid JSON in {VSCODE_EXTENSIONS_JSON_FILE}")
|
||||||
|
|
||||||
|
def locate_vscode_cli() -> Optional[str]:
|
||||||
|
vscode_alias = which('code') # More reliable than using `code`, especially on Windows.
|
||||||
|
if vscode_alias:
|
||||||
|
return vscode_alias
|
||||||
|
potential_vscode_cli_paths = [
|
||||||
|
'/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code' # macOS VS Code may not register 'code' command in PATH
|
||||||
|
]
|
||||||
|
for vscode_cli_candidate_path in potential_vscode_cli_paths:
|
||||||
|
if Path(vscode_cli_candidate_path).is_file():
|
||||||
|
return vscode_cli_candidate_path
|
||||||
|
return None
|
||||||
|
|
||||||
def remove_json_comments(json_like: str) -> str:
|
def remove_json_comments(json_like: str) -> str:
|
||||||
pattern: str = r'(?:"(?:\\.|[^"\\])*"|/\*[\s\S]*?\*/|//.*)|([^:]//.*$)'
|
pattern: str = r'(?:"(?:\\.|[^"\\])*"|/\*[\s\S]*?\*/|//.*)|([^:]//.*$)'
|
||||||
return re.sub(
|
return re.sub(
|
||||||
pattern,
|
pattern,
|
||||||
lambda m: '' if m.group(1) else m.group(0), json_like, flags=re.MULTILINE,
|
lambda m: '' if m.group(1) else m.agroup(0), json_like, flags=re.MULTILINE,
|
||||||
)
|
)
|
||||||
|
|
||||||
def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> None:
|
def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> None:
|
||||||
@@ -123,6 +136,12 @@ def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> No
|
|||||||
f"Visual Studio Code CLI tool not found: {vscode_cli_path}."
|
f"Visual Studio Code CLI tool not found: {vscode_cli_path}."
|
||||||
f"Could not install extension: {ext}",
|
f"Could not install extension: {ext}",
|
||||||
]))
|
]))
|
||||||
|
except Exception as e: # pylint: disable=broad-except
|
||||||
|
print_error(' '.join([
|
||||||
|
f"Failed to install extension '{ext}'.",
|
||||||
|
f"Attempted using Visual Studio Code CLI at: '{vscode_cli_path}'.",
|
||||||
|
f"Encountered error: {e}",
|
||||||
|
]))
|
||||||
total_extensions = len(extensions)
|
total_extensions = len(extensions)
|
||||||
print_installation_results(successful_installations, total_extensions)
|
print_installation_results(successful_installations, total_extensions)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
|
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
|
||||||
import { IApplicationFactory } from './IApplicationFactory';
|
|
||||||
import { parseApplication } from './Parser/ApplicationParser';
|
import { parseApplication } from './Parser/ApplicationParser';
|
||||||
|
import type { IApplicationFactory } from './IApplicationFactory';
|
||||||
|
|
||||||
export type ApplicationGetterType = () => IApplication;
|
export type ApplicationGetterType = () => IApplication;
|
||||||
const ApplicationGetter: ApplicationGetterType = parseApplication;
|
const ApplicationGetter: ApplicationGetterType = parseApplication;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||||
import { assertInRange } from '@/application/Common/Enum';
|
import { assertInRange } from '@/application/Common/Enum';
|
||||||
import { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
|
import type { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
|
||||||
|
|
||||||
type Getter<T> = () => T;
|
type Getter<T> = () => T;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PlatformTimer } from './PlatformTimer';
|
import { PlatformTimer } from './PlatformTimer';
|
||||||
import { TimeoutType, Timer } from './Timer';
|
import type { TimeoutType, Timer } from './Timer';
|
||||||
|
|
||||||
export function batchedDebounce<T>(
|
export function batchedDebounce<T>(
|
||||||
callback: (batches: readonly T[]) => void,
|
callback: (batches: readonly T[]) => void,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Timer } from './Timer';
|
import type { Timer } from './Timer';
|
||||||
|
|
||||||
export const PlatformTimer: Timer = {
|
export const PlatformTimer: Timer = {
|
||||||
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Timer, TimeoutType } from './Timer';
|
|
||||||
import { PlatformTimer } from './PlatformTimer';
|
import { PlatformTimer } from './PlatformTimer';
|
||||||
|
import type { Timer, TimeoutType } from './Timer';
|
||||||
|
|
||||||
export type CallbackType = (..._: readonly unknown[]) => void;
|
export type CallbackType = (..._: readonly unknown[]) => void;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||||
import { assertInRange } from '@/application/Common/Enum';
|
import { assertInRange } from '@/application/Common/Enum';
|
||||||
import { CategoryCollectionState } from './State/CategoryCollectionState';
|
import { CategoryCollectionState } from './State/CategoryCollectionState';
|
||||||
import { ICategoryCollectionState } from './State/ICategoryCollectionState';
|
import type { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
|
||||||
import { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
|
import type { ICategoryCollectionState } from './State/ICategoryCollectionState';
|
||||||
|
|
||||||
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
|
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { IApplicationContext } from '@/application/Context/IApplicationContext';
|
import type { IApplicationContext } from '@/application/Context/IApplicationContext';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
import { CurrentEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironmentFactory';
|
import { CurrentEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironmentFactory';
|
||||||
import { IApplicationFactory } from '../IApplicationFactory';
|
|
||||||
import { ApplicationFactory } from '../ApplicationFactory';
|
import { ApplicationFactory } from '../ApplicationFactory';
|
||||||
import { ApplicationContext } from './ApplicationContext';
|
import { ApplicationContext } from './ApplicationContext';
|
||||||
|
import type { IApplicationFactory } from '../IApplicationFactory';
|
||||||
|
|
||||||
export async function buildContext(
|
export async function buildContext(
|
||||||
factory: IApplicationFactory = ApplicationFactory.Current,
|
factory: IApplicationFactory = ApplicationFactory.Current,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
import { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState';
|
import type { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState';
|
||||||
|
|
||||||
export interface IReadOnlyApplicationContext {
|
export interface IReadOnlyApplicationContext {
|
||||||
readonly app: IApplication;
|
readonly app: IApplication;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { UserFilter } from './Filter/UserFilter';
|
import { AdaptiveFilterContext } from './Filter/AdaptiveFilterContext';
|
||||||
import { IUserFilter } from './Filter/IUserFilter';
|
|
||||||
import { ApplicationCode } from './Code/ApplicationCode';
|
import { ApplicationCode } from './Code/ApplicationCode';
|
||||||
import { UserSelection } from './Selection/UserSelection';
|
|
||||||
import { ICategoryCollectionState } from './ICategoryCollectionState';
|
|
||||||
import { IApplicationCode } from './Code/IApplicationCode';
|
|
||||||
import { UserSelectionFacade } from './Selection/UserSelectionFacade';
|
import { UserSelectionFacade } from './Selection/UserSelectionFacade';
|
||||||
|
import type { FilterContext } from './Filter/FilterContext';
|
||||||
|
import type { UserSelection } from './Selection/UserSelection';
|
||||||
|
import type { ICategoryCollectionState } from './ICategoryCollectionState';
|
||||||
|
import type { IApplicationCode } from './Code/IApplicationCode';
|
||||||
|
|
||||||
export class CategoryCollectionState implements ICategoryCollectionState {
|
export class CategoryCollectionState implements ICategoryCollectionState {
|
||||||
public readonly os: OperatingSystem;
|
public readonly os: OperatingSystem;
|
||||||
@@ -15,7 +15,7 @@ export class CategoryCollectionState implements ICategoryCollectionState {
|
|||||||
|
|
||||||
public readonly selection: UserSelection;
|
public readonly selection: UserSelection;
|
||||||
|
|
||||||
public readonly filter: IUserFilter;
|
public readonly filter: FilterContext;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
public readonly collection: ICategoryCollection,
|
public readonly collection: ICategoryCollection,
|
||||||
@@ -45,7 +45,7 @@ const DefaultSelectionFactory: SelectionFactory = (
|
|||||||
) => new UserSelectionFacade(...params);
|
) => new UserSelectionFacade(...params);
|
||||||
|
|
||||||
export type FilterFactory = (
|
export type FilterFactory = (
|
||||||
...params: ConstructorParameters<typeof UserFilter>
|
...params: ConstructorParameters<typeof AdaptiveFilterContext>
|
||||||
) => IUserFilter;
|
) => FilterContext;
|
||||||
|
|
||||||
const DefaultFilterFactory: FilterFactory = (...params) => new UserFilter(...params);
|
const DefaultFilterFactory: FilterFactory = (...params) => new AdaptiveFilterContext(...params);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||||
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
||||||
import { ReadonlyScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
|
import type { ReadonlyScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
|
||||||
import { CodeChangedEvent } from './Event/CodeChangedEvent';
|
import { CodeChangedEvent } from './Event/CodeChangedEvent';
|
||||||
import { CodePosition } from './Position/CodePosition';
|
import { CodePosition } from './Position/CodePosition';
|
||||||
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
|
|
||||||
import { UserScriptGenerator } from './Generation/UserScriptGenerator';
|
import { UserScriptGenerator } from './Generation/UserScriptGenerator';
|
||||||
import { IApplicationCode } from './IApplicationCode';
|
import type { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
|
||||||
import { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
|
import type { ICodeChangedEvent } from './Event/ICodeChangedEvent';
|
||||||
|
import type { IApplicationCode } from './IApplicationCode';
|
||||||
|
|
||||||
export class ApplicationCode implements IApplicationCode {
|
export class ApplicationCode implements IApplicationCode {
|
||||||
public readonly changed = new EventSource<ICodeChangedEvent>();
|
public readonly changed = new EventSource<ICodeChangedEvent>();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
||||||
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
||||||
import { ICodeChangedEvent } from './ICodeChangedEvent';
|
import type { ICodeChangedEvent } from './ICodeChangedEvent';
|
||||||
|
|
||||||
export class CodeChangedEvent implements ICodeChangedEvent {
|
export class CodeChangedEvent implements ICodeChangedEvent {
|
||||||
public readonly code: string;
|
public readonly code: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
||||||
|
|
||||||
export interface ICodeChangedEvent {
|
export interface ICodeChangedEvent {
|
||||||
readonly code: string;
|
readonly code: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ICodeBuilder } from './ICodeBuilder';
|
import type { ICodeBuilder } from './ICodeBuilder';
|
||||||
|
|
||||||
const TotalFunctionSeparatorChars = 58;
|
const TotalFunctionSeparatorChars = 58;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
|
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
|
||||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||||
import { ICodeBuilder } from './ICodeBuilder';
|
|
||||||
import { BatchBuilder } from './Languages/BatchBuilder';
|
import { BatchBuilder } from './Languages/BatchBuilder';
|
||||||
import { ShellBuilder } from './Languages/ShellBuilder';
|
import { ShellBuilder } from './Languages/ShellBuilder';
|
||||||
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
import type { ICodeBuilder } from './ICodeBuilder';
|
||||||
|
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
||||||
|
|
||||||
export class CodeBuilderFactory
|
export class CodeBuilderFactory
|
||||||
extends ScriptingLanguageFactory<ICodeBuilder>
|
extends ScriptingLanguageFactory<ICodeBuilder>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
|
import type { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
|
||||||
import { ICodeBuilder } from './ICodeBuilder';
|
import type { ICodeBuilder } from './ICodeBuilder';
|
||||||
|
|
||||||
export type ICodeBuilderFactory = IScriptingLanguageFactory<ICodeBuilder>;
|
export type ICodeBuilderFactory = IScriptingLanguageFactory<ICodeBuilder>;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
||||||
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
||||||
|
|
||||||
export interface IUserScript {
|
export interface IUserScript {
|
||||||
readonly code: string;
|
readonly code: string;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||||
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
||||||
import { IUserScript } from './IUserScript';
|
import type { IUserScript } from './IUserScript';
|
||||||
|
|
||||||
export interface IUserScriptGenerator {
|
export interface IUserScriptGenerator {
|
||||||
buildCode(
|
buildCode(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
|
||||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||||
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
|
||||||
import { CodePosition } from '../Position/CodePosition';
|
import { CodePosition } from '../Position/CodePosition';
|
||||||
import { IUserScriptGenerator } from './IUserScriptGenerator';
|
|
||||||
import { IUserScript } from './IUserScript';
|
|
||||||
import { ICodeBuilder } from './ICodeBuilder';
|
|
||||||
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
|
||||||
import { CodeBuilderFactory } from './CodeBuilderFactory';
|
import { CodeBuilderFactory } from './CodeBuilderFactory';
|
||||||
|
import type { IUserScriptGenerator } from './IUserScriptGenerator';
|
||||||
|
import type { IUserScript } from './IUserScript';
|
||||||
|
import type { ICodeBuilder } from './ICodeBuilder';
|
||||||
|
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
||||||
|
|
||||||
export class UserScriptGenerator implements IUserScriptGenerator {
|
export class UserScriptGenerator implements IUserScriptGenerator {
|
||||||
constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) {
|
constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||||
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
|
import type { ICodeChangedEvent } from './Event/ICodeChangedEvent';
|
||||||
|
|
||||||
export interface IApplicationCode {
|
export interface IApplicationCode {
|
||||||
readonly changed: IEventSource<ICodeChangedEvent>;
|
readonly changed: IEventSource<ICodeChangedEvent>;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ICodePosition } from './ICodePosition';
|
import type { ICodePosition } from './ICodePosition';
|
||||||
|
|
||||||
export class CodePosition implements ICodePosition {
|
export class CodePosition implements ICodePosition {
|
||||||
public get totalLines(): number {
|
public get totalLines(): number {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||||
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
|
import { FilterChange } from './Event/FilterChange';
|
||||||
|
import { LinearFilterStrategy } from './Strategy/LinearFilterStrategy';
|
||||||
|
import type { FilterResult } from './Result/FilterResult';
|
||||||
|
import type { FilterContext } from './FilterContext';
|
||||||
|
import type { FilterChangeDetails } from './Event/FilterChangeDetails';
|
||||||
|
import type { FilterStrategy } from './Strategy/FilterStrategy';
|
||||||
|
|
||||||
|
export class AdaptiveFilterContext implements FilterContext {
|
||||||
|
public readonly filterChanged = new EventSource<FilterChangeDetails>();
|
||||||
|
|
||||||
|
public currentFilter: FilterResult | undefined;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly collection: ICategoryCollection,
|
||||||
|
private readonly filterStrategy: FilterStrategy = new LinearFilterStrategy(),
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public applyFilter(filter: string): void {
|
||||||
|
if (!filter) {
|
||||||
|
throw new Error('Filter must be defined and not empty. Use clearFilter() to remove the filter');
|
||||||
|
}
|
||||||
|
const result = this.filterStrategy.applyFilter(filter, this.collection);
|
||||||
|
this.currentFilter = result;
|
||||||
|
this.filterChanged.notify(FilterChange.forApply(this.currentFilter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearFilter(): void {
|
||||||
|
this.currentFilter = undefined;
|
||||||
|
this.filterChanged.notify(FilterChange.forClear());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
|
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
|
||||||
import { FilterActionType } from './FilterActionType';
|
import { FilterActionType } from './FilterActionType';
|
||||||
import {
|
import type {
|
||||||
IFilterChangeDetails, IFilterChangeDetailsVisitor,
|
FilterChangeDetails, FilterChangeDetailsVisitor,
|
||||||
ApplyFilterAction, ClearFilterAction,
|
ApplyFilterAction, ClearFilterAction,
|
||||||
} from './IFilterChangeDetails';
|
} from './FilterChangeDetails';
|
||||||
|
|
||||||
export class FilterChange implements IFilterChangeDetails {
|
export class FilterChange implements FilterChangeDetails {
|
||||||
public static forApply(
|
public static forApply(
|
||||||
filter: IFilterResult,
|
filter: FilterResult,
|
||||||
): IFilterChangeDetails {
|
): FilterChangeDetails {
|
||||||
return new FilterChange({ type: FilterActionType.Apply, filter });
|
return new FilterChange({ type: FilterActionType.Apply, filter });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static forClear(): IFilterChangeDetails {
|
public static forClear(): FilterChangeDetails {
|
||||||
return new FilterChange({ type: FilterActionType.Clear });
|
return new FilterChange({ type: FilterActionType.Clear });
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(public readonly action: ApplyFilterAction | ClearFilterAction) { }
|
private constructor(public readonly action: ApplyFilterAction | ClearFilterAction) { }
|
||||||
|
|
||||||
public visit(visitor: IFilterChangeDetailsVisitor): void {
|
public visit(visitor: FilterChangeDetailsVisitor): void {
|
||||||
switch (this.action.type) {
|
switch (this.action.type) {
|
||||||
case FilterActionType.Apply:
|
case FilterActionType.Apply:
|
||||||
if (visitor.onApply) {
|
if (visitor.onApply) {
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
|
||||||
|
import type { FilterActionType } from './FilterActionType';
|
||||||
|
|
||||||
|
export interface FilterChangeDetails {
|
||||||
|
readonly action: FilterAction;
|
||||||
|
visit(visitor: FilterChangeDetailsVisitor): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterChangeDetailsVisitor {
|
||||||
|
readonly onClear?: () => void;
|
||||||
|
readonly onApply?: (filter: FilterResult) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApplyFilterAction = {
|
||||||
|
readonly type: FilterActionType.Apply,
|
||||||
|
readonly filter: FilterResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ClearFilterAction = {
|
||||||
|
readonly type: FilterActionType.Clear,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FilterAction = ApplyFilterAction | ClearFilterAction;
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
|
|
||||||
import { FilterActionType } from './FilterActionType';
|
|
||||||
|
|
||||||
export interface IFilterChangeDetails {
|
|
||||||
readonly action: FilterAction;
|
|
||||||
visit(visitor: IFilterChangeDetailsVisitor): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IFilterChangeDetailsVisitor {
|
|
||||||
readonly onClear?: () => void;
|
|
||||||
readonly onApply?: (filter: IFilterResult) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ApplyFilterAction = {
|
|
||||||
readonly type: FilterActionType.Apply,
|
|
||||||
readonly filter: IFilterResult;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ClearFilterAction = {
|
|
||||||
readonly type: FilterActionType.Clear,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FilterAction = ApplyFilterAction | ClearFilterAction;
|
|
||||||
13
src/application/Context/State/Filter/FilterContext.ts
Normal file
13
src/application/Context/State/Filter/FilterContext.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||||
|
import type { FilterResult } from './Result/FilterResult';
|
||||||
|
import type { FilterChangeDetails } from './Event/FilterChangeDetails';
|
||||||
|
|
||||||
|
export interface ReadonlyFilterContext {
|
||||||
|
readonly currentFilter: FilterResult | undefined;
|
||||||
|
readonly filterChanged: IEventSource<FilterChangeDetails>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterContext extends ReadonlyFilterContext {
|
||||||
|
applyFilter(filter: string): void;
|
||||||
|
clearFilter(): void;
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
|
||||||
import { IFilterResult } from './IFilterResult';
|
|
||||||
import { IFilterChangeDetails } from './Event/IFilterChangeDetails';
|
|
||||||
|
|
||||||
export interface IReadOnlyUserFilter {
|
|
||||||
readonly currentFilter: IFilterResult | undefined;
|
|
||||||
readonly filterChanged: IEventSource<IFilterChangeDetails>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IUserFilter extends IReadOnlyUserFilter {
|
|
||||||
applyFilter(filter: string): void;
|
|
||||||
clearFilter(): void;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { ICategory } from '@/domain/ICategory';
|
import type { ICategory } from '@/domain/ICategory';
|
||||||
import { IFilterResult } from './IFilterResult';
|
import type { FilterResult } from './FilterResult';
|
||||||
|
|
||||||
export class FilterResult implements IFilterResult {
|
export class AppliedFilterResult implements FilterResult {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly scriptMatches: ReadonlyArray<IScript>,
|
public readonly scriptMatches: ReadonlyArray<IScript>,
|
||||||
public readonly categoryMatches: ReadonlyArray<ICategory>,
|
public readonly categoryMatches: ReadonlyArray<ICategory>,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IScript, ICategory } from '@/domain/ICategory';
|
import type { IScript, ICategory } from '@/domain/ICategory';
|
||||||
|
|
||||||
export interface IFilterResult {
|
export interface FilterResult {
|
||||||
readonly categoryMatches: ReadonlyArray<ICategory>;
|
readonly categoryMatches: ReadonlyArray<ICategory>;
|
||||||
readonly scriptMatches: ReadonlyArray<IScript>;
|
readonly scriptMatches: ReadonlyArray<IScript>;
|
||||||
readonly query: string;
|
readonly query: string;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
|
import type { FilterResult } from '../Result/FilterResult';
|
||||||
|
|
||||||
|
export interface FilterStrategy {
|
||||||
|
applyFilter(
|
||||||
|
filter: string,
|
||||||
|
collection: ICategoryCollection,
|
||||||
|
): FilterResult;
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import type { ICategory, IScript } from '@/domain/ICategory';
|
||||||
|
import type { IScriptCode } from '@/domain/IScriptCode';
|
||||||
|
import type { IDocumentable } from '@/domain/IDocumentable';
|
||||||
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
|
import { AppliedFilterResult } from '../Result/AppliedFilterResult';
|
||||||
|
import type { FilterStrategy } from './FilterStrategy';
|
||||||
|
import type { FilterResult } from '../Result/FilterResult';
|
||||||
|
|
||||||
|
export class LinearFilterStrategy implements FilterStrategy {
|
||||||
|
applyFilter(filter: string, collection: ICategoryCollection): FilterResult {
|
||||||
|
const filterLowercase = filter.toLocaleLowerCase();
|
||||||
|
const filteredScripts = collection.getAllScripts().filter(
|
||||||
|
(script) => matchesScript(script, filterLowercase),
|
||||||
|
);
|
||||||
|
const filteredCategories = collection.getAllCategories().filter(
|
||||||
|
(category) => matchesCategory(category, filterLowercase),
|
||||||
|
);
|
||||||
|
return new AppliedFilterResult(
|
||||||
|
filteredScripts,
|
||||||
|
filteredCategories,
|
||||||
|
filter,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesCategory(
|
||||||
|
category: ICategory,
|
||||||
|
filterLowercase: string,
|
||||||
|
): boolean {
|
||||||
|
return matchesAny(
|
||||||
|
() => matchName(category.name, filterLowercase),
|
||||||
|
() => matchDocumentation(category, filterLowercase),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesScript(
|
||||||
|
script: IScript,
|
||||||
|
filterLowercase: string,
|
||||||
|
): boolean {
|
||||||
|
return matchesAny(
|
||||||
|
() => matchName(script.name, filterLowercase),
|
||||||
|
() => matchCode(script.code, filterLowercase),
|
||||||
|
() => matchDocumentation(script, filterLowercase),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesAny(
|
||||||
|
...predicates: ReadonlyArray<() => boolean>
|
||||||
|
): boolean {
|
||||||
|
return predicates.some((predicate) => predicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchName(
|
||||||
|
name: string,
|
||||||
|
filterLowercase: string,
|
||||||
|
): boolean {
|
||||||
|
return name.toLowerCase().includes(filterLowercase);
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchCode(
|
||||||
|
code: IScriptCode,
|
||||||
|
filterLowercase: string,
|
||||||
|
): boolean {
|
||||||
|
if (code.execute.toLowerCase().includes(filterLowercase)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (code.revert?.toLowerCase().includes(filterLowercase)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchDocumentation(
|
||||||
|
documentable: IDocumentable,
|
||||||
|
filterLowercase: string,
|
||||||
|
): boolean {
|
||||||
|
return documentable.docs.some(
|
||||||
|
(doc) => doc.toLocaleLowerCase().includes(filterLowercase),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { IScript } from '@/domain/IScript';
|
|
||||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
|
||||||
import { FilterResult } from './FilterResult';
|
|
||||||
import { IFilterResult } from './IFilterResult';
|
|
||||||
import { IUserFilter } from './IUserFilter';
|
|
||||||
import { IFilterChangeDetails } from './Event/IFilterChangeDetails';
|
|
||||||
import { FilterChange } from './Event/FilterChange';
|
|
||||||
|
|
||||||
export class UserFilter implements IUserFilter {
|
|
||||||
public readonly filterChanged = new EventSource<IFilterChangeDetails>();
|
|
||||||
|
|
||||||
public currentFilter: IFilterResult | undefined;
|
|
||||||
|
|
||||||
constructor(private collection: ICategoryCollection) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public applyFilter(filter: string): void {
|
|
||||||
if (!filter) {
|
|
||||||
throw new Error('Filter must be defined and not empty. Use clearFilter() to remove the filter');
|
|
||||||
}
|
|
||||||
const filterLowercase = filter.toLocaleLowerCase();
|
|
||||||
const filteredScripts = this.collection.getAllScripts().filter(
|
|
||||||
(script) => isScriptAMatch(script, filterLowercase),
|
|
||||||
);
|
|
||||||
const filteredCategories = this.collection.getAllCategories().filter(
|
|
||||||
(category) => category.name.toLowerCase().includes(filterLowercase),
|
|
||||||
);
|
|
||||||
const matches = new FilterResult(
|
|
||||||
filteredScripts,
|
|
||||||
filteredCategories,
|
|
||||||
filter,
|
|
||||||
);
|
|
||||||
this.currentFilter = matches;
|
|
||||||
this.filterChanged.notify(FilterChange.forApply(this.currentFilter));
|
|
||||||
}
|
|
||||||
|
|
||||||
public clearFilter(): void {
|
|
||||||
this.currentFilter = undefined;
|
|
||||||
this.filterChanged.notify(FilterChange.forClear());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isScriptAMatch(script: IScript, filterLowercase: string) {
|
|
||||||
if (script.name.toLowerCase().includes(filterLowercase)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (script.code.execute.toLowerCase().includes(filterLowercase)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (script.code.revert) {
|
|
||||||
return script.code.revert.toLowerCase().includes(filterLowercase);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { IReadOnlyUserFilter, IUserFilter } from './Filter/IUserFilter';
|
import type { IApplicationCode } from './Code/IApplicationCode';
|
||||||
import { ReadonlyUserSelection, UserSelection } from './Selection/UserSelection';
|
import type { ReadonlyFilterContext, FilterContext } from './Filter/FilterContext';
|
||||||
import { IApplicationCode } from './Code/IApplicationCode';
|
import type { ReadonlyUserSelection, UserSelection } from './Selection/UserSelection';
|
||||||
|
|
||||||
export interface IReadOnlyCategoryCollectionState {
|
export interface IReadOnlyCategoryCollectionState {
|
||||||
readonly code: IApplicationCode;
|
readonly code: IApplicationCode;
|
||||||
readonly os: OperatingSystem;
|
readonly os: OperatingSystem;
|
||||||
readonly filter: IReadOnlyUserFilter;
|
readonly filter: ReadonlyFilterContext;
|
||||||
readonly selection: ReadonlyUserSelection;
|
readonly selection: ReadonlyUserSelection;
|
||||||
readonly collection: ICategoryCollection;
|
readonly collection: ICategoryCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICategoryCollectionState extends IReadOnlyCategoryCollectionState {
|
export interface ICategoryCollectionState extends IReadOnlyCategoryCollectionState {
|
||||||
readonly filter: IUserFilter;
|
readonly filter: FilterContext;
|
||||||
readonly selection: UserSelection;
|
readonly selection: UserSelection;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ICategory } from '@/domain/ICategory';
|
import type { ICategory } from '@/domain/ICategory';
|
||||||
import { CategorySelectionChangeCommand } from './CategorySelectionChange';
|
import type { CategorySelectionChangeCommand } from './CategorySelectionChange';
|
||||||
|
|
||||||
export interface ReadonlyCategorySelection {
|
export interface ReadonlyCategorySelection {
|
||||||
areAllScriptsSelected(category: ICategory): boolean;
|
areAllScriptsSelected(category: ICategory): boolean;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ICategory } from '@/domain/ICategory';
|
import type { ICategory } from '@/domain/ICategory';
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { ScriptSelection } from '../Script/ScriptSelection';
|
import type { CategorySelectionChange, CategorySelectionChangeCommand } from './CategorySelectionChange';
|
||||||
import { ScriptSelectionChange } from '../Script/ScriptSelectionChange';
|
import type { CategorySelection } from './CategorySelection';
|
||||||
import { CategorySelection } from './CategorySelection';
|
import type { ScriptSelection } from '../Script/ScriptSelection';
|
||||||
import { CategorySelectionChange, CategorySelectionChangeCommand } from './CategorySelectionChange';
|
import type { ScriptSelectionChange } from '../Script/ScriptSelectionChange';
|
||||||
|
|
||||||
export class ScriptToCategorySelectionMapper implements CategorySelection {
|
export class ScriptToCategorySelectionMapper implements CategorySelection {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { InMemoryRepository } from '@/infrastructure/Repository/InMemoryRepository';
|
import { InMemoryRepository } from '@/infrastructure/Repository/InMemoryRepository';
|
||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||||
import { ReadonlyRepository, Repository } from '@/application/Repository/Repository';
|
import type { ReadonlyRepository, Repository } from '@/application/Repository/Repository';
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { batchedDebounce } from '@/application/Common/Timing/BatchedDebounce';
|
import { batchedDebounce } from '@/application/Common/Timing/BatchedDebounce';
|
||||||
import { ScriptSelection } from './ScriptSelection';
|
|
||||||
import { ScriptSelectionChange, ScriptSelectionChangeCommand } from './ScriptSelectionChange';
|
|
||||||
import { SelectedScript } from './SelectedScript';
|
|
||||||
import { UserSelectedScript } from './UserSelectedScript';
|
import { UserSelectedScript } from './UserSelectedScript';
|
||||||
|
import type { ScriptSelection } from './ScriptSelection';
|
||||||
|
import type { ScriptSelectionChange, ScriptSelectionChangeCommand } from './ScriptSelectionChange';
|
||||||
|
import type { SelectedScript } from './SelectedScript';
|
||||||
|
|
||||||
const DEBOUNCE_DELAY_IN_MS = 100;
|
const DEBOUNCE_DELAY_IN_MS = 100;
|
||||||
|
|
||||||
@@ -81,9 +81,7 @@ export class DebouncedScriptSelection implements ScriptSelection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public selectOnly(scripts: readonly IScript[]): void {
|
public selectOnly(scripts: readonly IScript[]): void {
|
||||||
if (scripts.length === 0) {
|
assertNonEmptyScriptSelection(scripts);
|
||||||
throw new Error('Provided script array is empty. To deselect all scripts, please use the deselectAll() method instead.');
|
|
||||||
}
|
|
||||||
this.processChanges({
|
this.processChanges({
|
||||||
changes: [
|
changes: [
|
||||||
...getScriptIdsToBeDeselected(this.scripts, scripts)
|
...getScriptIdsToBeDeselected(this.scripts, scripts)
|
||||||
@@ -147,6 +145,12 @@ export class DebouncedScriptSelection implements ScriptSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertNonEmptyScriptSelection(selectedItems: readonly IScript[]) {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
throw new Error('Provided script array is empty. To deselect all scripts, please use the deselectAll() method instead.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getScriptIdsToBeSelected(
|
function getScriptIdsToBeSelected(
|
||||||
existingItems: ReadonlyRepository<string, SelectedScript>,
|
existingItems: ReadonlyRepository<string, SelectedScript>,
|
||||||
desiredScripts: readonly IScript[],
|
desiredScripts: readonly IScript[],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { SelectedScript } from './SelectedScript';
|
import type { SelectedScript } from './SelectedScript';
|
||||||
import { ScriptSelectionChangeCommand } from './ScriptSelectionChange';
|
import type { ScriptSelectionChangeCommand } from './ScriptSelectionChange';
|
||||||
|
|
||||||
export interface ReadonlyScriptSelection {
|
export interface ReadonlyScriptSelection {
|
||||||
readonly changed: IEventSource<readonly SelectedScript[]>;
|
readonly changed: IEventSource<readonly SelectedScript[]>;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export type ScriptSelectionStatus = {
|
|||||||
readonly isReverted: boolean;
|
readonly isReverted: boolean;
|
||||||
} | {
|
} | {
|
||||||
readonly isSelected: false;
|
readonly isSelected: false;
|
||||||
|
readonly isReverted?: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ScriptSelectionChange {
|
export interface ScriptSelectionChange {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IEntity } from '@/infrastructure/Entity/IEntity';
|
import type { IEntity } from '@/infrastructure/Entity/IEntity';
|
||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
|
|
||||||
type ScriptId = IScript['id'];
|
type ScriptId = IScript['id'];
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
|
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
|
||||||
import { IScript } from '@/domain/IScript';
|
import type { IScript } from '@/domain/IScript';
|
||||||
import { SelectedScript } from './SelectedScript';
|
import type { SelectedScript } from './SelectedScript';
|
||||||
|
|
||||||
type SelectedScriptId = SelectedScript['id'];
|
type SelectedScriptId = SelectedScript['id'];
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CategorySelection, ReadonlyCategorySelection } from './Category/CategorySelection';
|
import type { CategorySelection, ReadonlyCategorySelection } from './Category/CategorySelection';
|
||||||
import { ReadonlyScriptSelection, ScriptSelection } from './Script/ScriptSelection';
|
import type { ReadonlyScriptSelection, ScriptSelection } from './Script/ScriptSelection';
|
||||||
|
|
||||||
export interface ReadonlyUserSelection {
|
export interface ReadonlyUserSelection {
|
||||||
readonly categories: ReadonlyCategorySelection;
|
readonly categories: ReadonlyCategorySelection;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { CategorySelection } from './Category/CategorySelection';
|
|
||||||
import { ScriptToCategorySelectionMapper } from './Category/ScriptToCategorySelectionMapper';
|
import { ScriptToCategorySelectionMapper } from './Category/ScriptToCategorySelectionMapper';
|
||||||
import { DebouncedScriptSelection } from './Script/DebouncedScriptSelection';
|
import { DebouncedScriptSelection } from './Script/DebouncedScriptSelection';
|
||||||
import { ScriptSelection } from './Script/ScriptSelection';
|
import type { CategorySelection } from './Category/CategorySelection';
|
||||||
import { UserSelection } from './UserSelection';
|
import type { ScriptSelection } from './Script/ScriptSelection';
|
||||||
import { SelectedScript } from './Script/SelectedScript';
|
import type { UserSelection } from './UserSelection';
|
||||||
|
import type { SelectedScript } from './Script/SelectedScript';
|
||||||
|
|
||||||
export class UserSelectionFacade implements UserSelection {
|
export class UserSelectionFacade implements UserSelection {
|
||||||
public readonly categories: CategorySelection;
|
public readonly categories: CategorySelection;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
|
|
||||||
export interface IApplicationFactory {
|
export interface IApplicationFactory {
|
||||||
getApp(): Promise<IApplication>;
|
getApp(): Promise<IApplication>;
|
||||||
|
|||||||
@@ -1,31 +1,33 @@
|
|||||||
import type { CollectionData } from '@/application/collections/';
|
import type { CollectionData } from '@/application/collections/';
|
||||||
import { IApplication } from '@/domain/IApplication';
|
import type { IApplication } from '@/domain/IApplication';
|
||||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import WindowsData from '@/application/collections/windows.yaml';
|
import WindowsData from '@/application/collections/windows.yaml';
|
||||||
import MacOsData from '@/application/collections/macos.yaml';
|
import MacOsData from '@/application/collections/macos.yaml';
|
||||||
import LinuxData from '@/application/collections/linux.yaml';
|
import LinuxData from '@/application/collections/linux.yaml';
|
||||||
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
|
import { parseProjectDetails } from '@/application/Parser/ProjectDetailsParser';
|
||||||
import { Application } from '@/domain/Application';
|
import { Application } from '@/domain/Application';
|
||||||
import { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
|
import type { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
|
||||||
import { EnvironmentVariablesFactory } from '@/infrastructure/EnvironmentVariables/EnvironmentVariablesFactory';
|
import { EnvironmentVariablesFactory } from '@/infrastructure/EnvironmentVariables/EnvironmentVariablesFactory';
|
||||||
import { parseCategoryCollection } from './CategoryCollectionParser';
|
import { parseCategoryCollection } from './CategoryCollectionParser';
|
||||||
|
|
||||||
export function parseApplication(
|
export function parseApplication(
|
||||||
categoryParser = parseCategoryCollection,
|
categoryParser = parseCategoryCollection,
|
||||||
informationParser = parseProjectInformation,
|
projectDetailsParser = parseProjectDetails,
|
||||||
metadata: IAppMetadata = EnvironmentVariablesFactory.Current.instance,
|
metadata: IAppMetadata = EnvironmentVariablesFactory.Current.instance,
|
||||||
collectionsData = PreParsedCollections,
|
collectionsData = PreParsedCollections,
|
||||||
): IApplication {
|
): IApplication {
|
||||||
validateCollectionsData(collectionsData);
|
validateCollectionsData(collectionsData);
|
||||||
const information = informationParser(metadata);
|
const projectDetails = projectDetailsParser(metadata);
|
||||||
const collections = collectionsData.map((collection) => categoryParser(collection, information));
|
const collections = collectionsData.map(
|
||||||
const app = new Application(information, collections);
|
(collection) => categoryParser(collection, projectDetails),
|
||||||
|
);
|
||||||
|
const app = new Application(projectDetails, collections);
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CategoryCollectionParserType
|
export type CategoryCollectionParserType
|
||||||
= (file: CollectionData, info: IProjectInformation) => ICategoryCollection;
|
= (file: CollectionData, projectDetails: ProjectDetails) => ICategoryCollection;
|
||||||
|
|
||||||
const PreParsedCollections: readonly CollectionData [] = [
|
const PreParsedCollections: readonly CollectionData [] = [
|
||||||
WindowsData, MacOsData, LinuxData,
|
WindowsData, MacOsData, LinuxData,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { CollectionData } from '@/application/collections/';
|
import type { CollectionData } from '@/application/collections/';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||||
import { CategoryCollection } from '@/domain/CategoryCollection';
|
import { CategoryCollection } from '@/domain/CategoryCollection';
|
||||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
|
||||||
import { createEnumParser } from '../Common/Enum';
|
import { createEnumParser } from '../Common/Enum';
|
||||||
import { parseCategory } from './CategoryParser';
|
import { parseCategory } from './CategoryParser';
|
||||||
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
|
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
|
||||||
@@ -10,12 +10,12 @@ import { ScriptingDefinitionParser } from './ScriptingDefinition/ScriptingDefini
|
|||||||
|
|
||||||
export function parseCategoryCollection(
|
export function parseCategoryCollection(
|
||||||
content: CollectionData,
|
content: CollectionData,
|
||||||
info: IProjectInformation,
|
projectDetails: ProjectDetails,
|
||||||
osParser = createEnumParser(OperatingSystem),
|
osParser = createEnumParser(OperatingSystem),
|
||||||
): ICategoryCollection {
|
): ICategoryCollection {
|
||||||
validate(content);
|
validate(content);
|
||||||
const scripting = new ScriptingDefinitionParser()
|
const scripting = new ScriptingDefinitionParser()
|
||||||
.parse(content.scripting, info);
|
.parse(content.scripting, projectDetails);
|
||||||
const context = new CategoryCollectionParseContext(content.functions, scripting);
|
const context = new CategoryCollectionParseContext(content.functions, scripting);
|
||||||
const categories = content.actions.map((action) => parseCategory(action, context));
|
const categories = content.actions.map((action) => parseCategory(action, context));
|
||||||
const os = osParser.parseEnum(content.os, 'os');
|
const os = osParser.parseEnum(content.os, 'os');
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { Category } from '@/domain/Category';
|
|||||||
import { NodeValidator } from '@/application/Parser/NodeValidation/NodeValidator';
|
import { NodeValidator } from '@/application/Parser/NodeValidation/NodeValidator';
|
||||||
import { NodeType } from '@/application/Parser/NodeValidation/NodeType';
|
import { NodeType } from '@/application/Parser/NodeValidation/NodeType';
|
||||||
import { parseDocs } from './DocumentationParser';
|
import { parseDocs } from './DocumentationParser';
|
||||||
import { ICategoryCollectionParseContext } from './Script/ICategoryCollectionParseContext';
|
|
||||||
import { parseScript } from './Script/ScriptParser';
|
import { parseScript } from './Script/ScriptParser';
|
||||||
|
import type { ICategoryCollectionParseContext } from './Script/ICategoryCollectionParseContext';
|
||||||
|
|
||||||
let categoryIdCounter = 0;
|
let categoryIdCounter = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { CustomError } from '@/application/Common/CustomError';
|
import { CustomError } from '@/application/Common/CustomError';
|
||||||
import { NodeType } from './NodeType';
|
import { NodeType } from './NodeType';
|
||||||
import { NodeData } from './NodeData';
|
import type { NodeData } from './NodeData';
|
||||||
|
|
||||||
export class NodeDataError extends CustomError {
|
export class NodeDataError extends CustomError {
|
||||||
constructor(message: string, public readonly context: INodeDataErrorContext) {
|
constructor(message: string, public readonly context: INodeDataErrorContext) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { isString } from '@/TypeHelpers';
|
import { isString } from '@/TypeHelpers';
|
||||||
import { INodeDataErrorContext, NodeDataError } from './NodeDataError';
|
import { type INodeDataErrorContext, NodeDataError } from './NodeDataError';
|
||||||
import { NodeData } from './NodeData';
|
import type { NodeData } from './NodeData';
|
||||||
|
|
||||||
export class NodeValidator {
|
export class NodeValidator {
|
||||||
constructor(private readonly context: INodeDataErrorContext) {
|
constructor(private readonly context: INodeDataErrorContext) {
|
||||||
|
|||||||
29
src/application/Parser/ProjectDetailsParser.ts
Normal file
29
src/application/Parser/ProjectDetailsParser.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
|
||||||
|
import { GitHubProjectDetails } from '@/domain/Project/GitHubProjectDetails';
|
||||||
|
import type { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
|
||||||
|
import { Version } from '@/domain/Version';
|
||||||
|
import { EnvironmentVariablesFactory } from '@/infrastructure/EnvironmentVariables/EnvironmentVariablesFactory';
|
||||||
|
import type { ConstructorArguments } from '@/TypeHelpers';
|
||||||
|
|
||||||
|
export function
|
||||||
|
parseProjectDetails(
|
||||||
|
metadata: IAppMetadata = EnvironmentVariablesFactory.Current.instance,
|
||||||
|
createProjectDetails: ProjectDetailsFactory = (
|
||||||
|
...args
|
||||||
|
) => new GitHubProjectDetails(...args),
|
||||||
|
): ProjectDetails {
|
||||||
|
const version = new Version(
|
||||||
|
metadata.version,
|
||||||
|
);
|
||||||
|
return createProjectDetails(
|
||||||
|
metadata.name,
|
||||||
|
version,
|
||||||
|
metadata.slogan,
|
||||||
|
metadata.repositoryUrl,
|
||||||
|
metadata.homepageUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProjectDetailsFactory = (
|
||||||
|
...args: ConstructorArguments<typeof GitHubProjectDetails>
|
||||||
|
) => ProjectDetails;
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
|
||||||
import { ProjectInformation } from '@/domain/ProjectInformation';
|
|
||||||
import { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
|
|
||||||
import { Version } from '@/domain/Version';
|
|
||||||
import { EnvironmentVariablesFactory } from '@/infrastructure/EnvironmentVariables/EnvironmentVariablesFactory';
|
|
||||||
import { ConstructorArguments } from '@/TypeHelpers';
|
|
||||||
|
|
||||||
export function
|
|
||||||
parseProjectInformation(
|
|
||||||
metadata: IAppMetadata = EnvironmentVariablesFactory.Current.instance,
|
|
||||||
createProjectInformation: ProjectInformationFactory = (
|
|
||||||
...args
|
|
||||||
) => new ProjectInformation(...args),
|
|
||||||
): IProjectInformation {
|
|
||||||
const version = new Version(
|
|
||||||
metadata.version,
|
|
||||||
);
|
|
||||||
return createProjectInformation(
|
|
||||||
metadata.name,
|
|
||||||
version,
|
|
||||||
metadata.slogan,
|
|
||||||
metadata.repositoryUrl,
|
|
||||||
metadata.homepageUrl,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ProjectInformationFactory = (
|
|
||||||
...args: ConstructorArguments<typeof ProjectInformation>
|
|
||||||
) => IProjectInformation;
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { FunctionData } from '@/application/collections/';
|
import type { FunctionData } from '@/application/collections/';
|
||||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||||
import { IScriptCompiler } from './Compiler/IScriptCompiler';
|
|
||||||
import { ScriptCompiler } from './Compiler/ScriptCompiler';
|
import { ScriptCompiler } from './Compiler/ScriptCompiler';
|
||||||
import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
|
|
||||||
import { SyntaxFactory } from './Validation/Syntax/SyntaxFactory';
|
import { SyntaxFactory } from './Validation/Syntax/SyntaxFactory';
|
||||||
import { ISyntaxFactory } from './Validation/Syntax/ISyntaxFactory';
|
import type { ILanguageSyntax } from './Validation/Syntax/ILanguageSyntax';
|
||||||
import { ILanguageSyntax } from './Validation/Syntax/ILanguageSyntax';
|
import type { IScriptCompiler } from './Compiler/IScriptCompiler';
|
||||||
|
import type { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
|
||||||
|
import type { ISyntaxFactory } from './Validation/Syntax/ISyntaxFactory';
|
||||||
|
|
||||||
export class CategoryCollectionParseContext implements ICategoryCollectionParseContext {
|
export class CategoryCollectionParseContext implements ICategoryCollectionParseContext {
|
||||||
public readonly compiler: IScriptCompiler;
|
public readonly compiler: IScriptCompiler;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
|
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
|
||||||
import { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
|
|
||||||
import { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
|
|
||||||
import { FunctionCallArgumentCollection } from '../../Function/Call/Argument/FunctionCallArgumentCollection';
|
import { FunctionCallArgumentCollection } from '../../Function/Call/Argument/FunctionCallArgumentCollection';
|
||||||
import { IExpression } from './IExpression';
|
import { ExpressionEvaluationContext, type IExpressionEvaluationContext } from './ExpressionEvaluationContext';
|
||||||
import { ExpressionPosition } from './ExpressionPosition';
|
import { ExpressionPosition } from './ExpressionPosition';
|
||||||
import { ExpressionEvaluationContext, IExpressionEvaluationContext } from './ExpressionEvaluationContext';
|
import type { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||||
|
import type { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
|
||||||
|
import type { IExpression } from './IExpression';
|
||||||
|
|
||||||
export type ExpressionEvaluator = (context: IExpressionEvaluationContext) => string;
|
export type ExpressionEvaluator = (context: IExpressionEvaluationContext) => string;
|
||||||
export class Expression implements IExpression {
|
export class Expression implements IExpression {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
|
|
||||||
import { IPipelineCompiler } from '../Pipes/IPipelineCompiler';
|
|
||||||
import { PipelineCompiler } from '../Pipes/PipelineCompiler';
|
import { PipelineCompiler } from '../Pipes/PipelineCompiler';
|
||||||
|
import type { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||||
|
import type { IPipelineCompiler } from '../Pipes/IPipelineCompiler';
|
||||||
|
|
||||||
export interface IExpressionEvaluationContext {
|
export interface IExpressionEvaluationContext {
|
||||||
readonly args: IReadOnlyFunctionCallArgumentCollection;
|
readonly args: IReadOnlyFunctionCallArgumentCollection;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
|
|
||||||
import { ExpressionPosition } from './ExpressionPosition';
|
import { ExpressionPosition } from './ExpressionPosition';
|
||||||
import { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
|
import type { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
|
||||||
|
import type { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
|
||||||
|
|
||||||
export interface IExpression {
|
export interface IExpression {
|
||||||
readonly position: ExpressionPosition;
|
readonly position: ExpressionPosition;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { IExpressionEvaluationContext, ExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
|
import { type IExpressionEvaluationContext, ExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
|
||||||
import { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
|
|
||||||
import { IExpressionsCompiler } from './IExpressionsCompiler';
|
|
||||||
import { IExpression } from './Expression/IExpression';
|
|
||||||
import { IExpressionParser } from './Parser/IExpressionParser';
|
|
||||||
import { CompositeExpressionParser } from './Parser/CompositeExpressionParser';
|
import { CompositeExpressionParser } from './Parser/CompositeExpressionParser';
|
||||||
|
import type { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||||
|
import type { IExpressionsCompiler } from './IExpressionsCompiler';
|
||||||
|
import type { IExpression } from './Expression/IExpression';
|
||||||
|
import type { IExpressionParser } from './Parser/IExpressionParser';
|
||||||
|
|
||||||
export class ExpressionsCompiler implements IExpressionsCompiler {
|
export class ExpressionsCompiler implements IExpressionsCompiler {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
|
import type { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||||
|
|
||||||
export interface IExpressionsCompiler {
|
export interface IExpressionsCompiler {
|
||||||
compileExpressions(
|
compileExpressions(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { IExpression } from '../Expression/IExpression';
|
|
||||||
import { ParameterSubstitutionParser } from '../SyntaxParsers/ParameterSubstitutionParser';
|
import { ParameterSubstitutionParser } from '../SyntaxParsers/ParameterSubstitutionParser';
|
||||||
import { WithParser } from '../SyntaxParsers/WithParser';
|
import { WithParser } from '../SyntaxParsers/WithParser';
|
||||||
import { IExpressionParser } from './IExpressionParser';
|
import type { IExpression } from '../Expression/IExpression';
|
||||||
|
import type { IExpressionParser } from './IExpressionParser';
|
||||||
|
|
||||||
const Parsers = [
|
const Parsers = [
|
||||||
new ParameterSubstitutionParser(),
|
new ParameterSubstitutionParser(),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IExpression } from '../Expression/IExpression';
|
import type { IExpression } from '../Expression/IExpression';
|
||||||
|
|
||||||
export interface IExpressionParser {
|
export interface IExpressionParser {
|
||||||
findExpressions(code: string): IExpression[];
|
findExpressions(code: string): IExpression[];
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { IExpressionParser } from '../IExpressionParser';
|
import { Expression, type ExpressionEvaluator } from '../../Expression/Expression';
|
||||||
import { IExpression } from '../../Expression/IExpression';
|
|
||||||
import { Expression, ExpressionEvaluator } from '../../Expression/Expression';
|
|
||||||
import { IFunctionParameter } from '../../../Function/Parameter/IFunctionParameter';
|
|
||||||
import { FunctionParameterCollection } from '../../../Function/Parameter/FunctionParameterCollection';
|
import { FunctionParameterCollection } from '../../../Function/Parameter/FunctionParameterCollection';
|
||||||
import { createPositionFromRegexFullMatch } from '../../Expression/ExpressionPositionFactory';
|
import { createPositionFromRegexFullMatch } from '../../Expression/ExpressionPositionFactory';
|
||||||
|
import type { IExpressionParser } from '../IExpressionParser';
|
||||||
|
import type { IExpression } from '../../Expression/IExpression';
|
||||||
|
import type { IFunctionParameter } from '../../../Function/Parameter/IFunctionParameter';
|
||||||
|
|
||||||
export abstract class RegexParser implements IExpressionParser {
|
export abstract class RegexParser implements IExpressionParser {
|
||||||
protected abstract readonly regex: RegExp;
|
protected abstract readonly regex: RegExp;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IPipe } from '../IPipe';
|
import type { IPipe } from '../IPipe';
|
||||||
|
|
||||||
export class EscapeDoubleQuotes implements IPipe {
|
export class EscapeDoubleQuotes implements IPipe {
|
||||||
public readonly name: string = 'escapeDoubleQuotes';
|
public readonly name: string = 'escapeDoubleQuotes';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IPipe } from '../IPipe';
|
import type { IPipe } from '../IPipe';
|
||||||
|
|
||||||
export class InlinePowerShell implements IPipe {
|
export class InlinePowerShell implements IPipe {
|
||||||
public readonly name: string = 'inlinePowerShell';
|
public readonly name: string = 'inlinePowerShell';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IPipe } from './IPipe';
|
|
||||||
import { InlinePowerShell } from './PipeDefinitions/InlinePowerShell';
|
import { InlinePowerShell } from './PipeDefinitions/InlinePowerShell';
|
||||||
import { EscapeDoubleQuotes } from './PipeDefinitions/EscapeDoubleQuotes';
|
import { EscapeDoubleQuotes } from './PipeDefinitions/EscapeDoubleQuotes';
|
||||||
|
import type { IPipe } from './IPipe';
|
||||||
|
|
||||||
const RegisteredPipes = [
|
const RegisteredPipes = [
|
||||||
new EscapeDoubleQuotes(),
|
new EscapeDoubleQuotes(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IPipeFactory, PipeFactory } from './PipeFactory';
|
import { type IPipeFactory, PipeFactory } from './PipeFactory';
|
||||||
import { IPipelineCompiler } from './IPipelineCompiler';
|
import type { IPipelineCompiler } from './IPipelineCompiler';
|
||||||
|
|
||||||
export class PipelineCompiler implements IPipelineCompiler {
|
export class PipelineCompiler implements IPipelineCompiler {
|
||||||
constructor(private readonly factory: IPipeFactory = new PipeFactory()) { }
|
constructor(private readonly factory: IPipeFactory = new PipeFactory()) { }
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
|
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
|
||||||
import { RegexParser, IPrimitiveExpression } from '../Parser/Regex/RegexParser';
|
import { RegexParser, type IPrimitiveExpression } from '../Parser/Regex/RegexParser';
|
||||||
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
|
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
|
||||||
|
|
||||||
export class ParameterSubstitutionParser extends RegexParser {
|
export class ParameterSubstitutionParser extends RegexParser {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// eslint-disable-next-line max-classes-per-file
|
// eslint-disable-next-line max-classes-per-file
|
||||||
import { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
|
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
|
||||||
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
|
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
|
||||||
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
|
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
|
||||||
import { IExpression } from '../Expression/IExpression';
|
|
||||||
import { ExpressionPosition } from '../Expression/ExpressionPosition';
|
import { ExpressionPosition } from '../Expression/ExpressionPosition';
|
||||||
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
|
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
|
||||||
import { createPositionFromRegexFullMatch } from '../Expression/ExpressionPositionFactory';
|
import { createPositionFromRegexFullMatch } from '../Expression/ExpressionPositionFactory';
|
||||||
|
import type { IExpression } from '../Expression/IExpression';
|
||||||
|
|
||||||
export class WithParser implements IExpressionParser {
|
export class WithParser implements IExpressionParser {
|
||||||
public findExpressions(code: string): IExpression[] {
|
public findExpressions(code: string): IExpression[] {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ensureValidParameterName } from '../../Shared/ParameterNameValidator';
|
import { ensureValidParameterName } from '../../Shared/ParameterNameValidator';
|
||||||
import { IFunctionCallArgument } from './IFunctionCallArgument';
|
import type { IFunctionCallArgument } from './IFunctionCallArgument';
|
||||||
|
|
||||||
export class FunctionCallArgument implements IFunctionCallArgument {
|
export class FunctionCallArgument implements IFunctionCallArgument {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IFunctionCallArgument } from './IFunctionCallArgument';
|
import type { IFunctionCallArgument } from './IFunctionCallArgument';
|
||||||
import { IFunctionCallArgumentCollection } from './IFunctionCallArgumentCollection';
|
import type { IFunctionCallArgumentCollection } from './IFunctionCallArgumentCollection';
|
||||||
|
|
||||||
export class FunctionCallArgumentCollection implements IFunctionCallArgumentCollection {
|
export class FunctionCallArgumentCollection implements IFunctionCallArgumentCollection {
|
||||||
private readonly arguments = new Map<string, IFunctionCallArgument>();
|
private readonly arguments = new Map<string, IFunctionCallArgument>();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IFunctionCallArgument } from './IFunctionCallArgument';
|
import type { IFunctionCallArgument } from './IFunctionCallArgument';
|
||||||
|
|
||||||
export interface IReadOnlyFunctionCallArgumentCollection {
|
export interface IReadOnlyFunctionCallArgumentCollection {
|
||||||
getArgument(parameterName: string): IFunctionCallArgument;
|
getArgument(parameterName: string): IFunctionCallArgument;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CompiledCode } from '../CompiledCode';
|
import type { CompiledCode } from '../CompiledCode';
|
||||||
|
|
||||||
export interface CodeSegmentMerger {
|
export interface CodeSegmentMerger {
|
||||||
mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode;
|
mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CompiledCode } from '../CompiledCode';
|
import type { CompiledCode } from '../CompiledCode';
|
||||||
import { CodeSegmentMerger } from './CodeSegmentMerger';
|
import type { CodeSegmentMerger } from './CodeSegmentMerger';
|
||||||
|
|
||||||
export class NewlineCodeSegmentMerger implements CodeSegmentMerger {
|
export class NewlineCodeSegmentMerger implements CodeSegmentMerger {
|
||||||
public mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode {
|
public mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
||||||
import { FunctionCall } from '../FunctionCall';
|
import type { FunctionCall } from '../FunctionCall';
|
||||||
import type { SingleCallCompiler } from './SingleCall/SingleCallCompiler';
|
import type { SingleCallCompiler } from './SingleCall/SingleCallCompiler';
|
||||||
|
|
||||||
export interface FunctionCallCompilationContext {
|
export interface FunctionCallCompilationContext {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
|
||||||
import { FunctionCall } from '../FunctionCall';
|
import type { CompiledCode } from './CompiledCode';
|
||||||
import { CompiledCode } from './CompiledCode';
|
import type { FunctionCall } from '../FunctionCall';
|
||||||
|
|
||||||
export interface FunctionCallCompiler {
|
export interface FunctionCallCompiler {
|
||||||
compileFunctionCalls(
|
compileFunctionCalls(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { ISharedFunctionCollection } from '../../ISharedFunctionCollection';
|
|
||||||
import { FunctionCallCompiler } from './FunctionCallCompiler';
|
|
||||||
import { CompiledCode } from './CompiledCode';
|
|
||||||
import { FunctionCallCompilationContext } from './FunctionCallCompilationContext';
|
|
||||||
import { SingleCallCompiler } from './SingleCall/SingleCallCompiler';
|
|
||||||
import { AdaptiveFunctionCallCompiler } from './SingleCall/AdaptiveFunctionCallCompiler';
|
|
||||||
import { CodeSegmentMerger } from './CodeSegmentJoin/CodeSegmentMerger';
|
|
||||||
import { NewlineCodeSegmentMerger } from './CodeSegmentJoin/NewlineCodeSegmentMerger';
|
import { NewlineCodeSegmentMerger } from './CodeSegmentJoin/NewlineCodeSegmentMerger';
|
||||||
|
import { AdaptiveFunctionCallCompiler } from './SingleCall/AdaptiveFunctionCallCompiler';
|
||||||
|
import type { ISharedFunctionCollection } from '../../ISharedFunctionCollection';
|
||||||
|
import type { FunctionCallCompiler } from './FunctionCallCompiler';
|
||||||
|
import type { CompiledCode } from './CompiledCode';
|
||||||
|
import type { FunctionCallCompilationContext } from './FunctionCallCompilationContext';
|
||||||
|
import type { SingleCallCompiler } from './SingleCall/SingleCallCompiler';
|
||||||
|
import type { CodeSegmentMerger } from './CodeSegmentJoin/CodeSegmentMerger';
|
||||||
|
|
||||||
export class FunctionCallSequenceCompiler implements FunctionCallCompiler {
|
export class FunctionCallSequenceCompiler implements FunctionCallCompiler {
|
||||||
public static readonly instance: FunctionCallCompiler = new FunctionCallSequenceCompiler();
|
public static readonly instance: FunctionCallCompiler = new FunctionCallSequenceCompiler();
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { FunctionCall } from '../../FunctionCall';
|
|
||||||
import { CompiledCode } from '../CompiledCode';
|
|
||||||
import { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
|
||||||
import { IReadOnlyFunctionCallArgumentCollection } from '../../Argument/IFunctionCallArgumentCollection';
|
|
||||||
import { ISharedFunction } from '../../../ISharedFunction';
|
|
||||||
import { SingleCallCompiler } from './SingleCallCompiler';
|
|
||||||
import { SingleCallCompilerStrategy } from './SingleCallCompilerStrategy';
|
|
||||||
import { InlineFunctionCallCompiler } from './Strategies/InlineFunctionCallCompiler';
|
import { InlineFunctionCallCompiler } from './Strategies/InlineFunctionCallCompiler';
|
||||||
import { NestedFunctionCallCompiler } from './Strategies/NestedFunctionCallCompiler';
|
import { NestedFunctionCallCompiler } from './Strategies/NestedFunctionCallCompiler';
|
||||||
|
import type { FunctionCall } from '../../FunctionCall';
|
||||||
|
import type { CompiledCode } from '../CompiledCode';
|
||||||
|
import type { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
||||||
|
import type { IReadOnlyFunctionCallArgumentCollection } from '../../Argument/IFunctionCallArgumentCollection';
|
||||||
|
import type { ISharedFunction } from '../../../ISharedFunction';
|
||||||
|
import type { SingleCallCompiler } from './SingleCallCompiler';
|
||||||
|
import type { SingleCallCompilerStrategy } from './SingleCallCompilerStrategy';
|
||||||
|
|
||||||
export class AdaptiveFunctionCallCompiler implements SingleCallCompiler {
|
export class AdaptiveFunctionCallCompiler implements SingleCallCompiler {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { FunctionCall } from '../../FunctionCall';
|
import type { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
||||||
import { CompiledCode } from '../CompiledCode';
|
import type { FunctionCall } from '../../FunctionCall';
|
||||||
import { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
import type { CompiledCode } from '../CompiledCode';
|
||||||
|
|
||||||
export interface SingleCallCompiler {
|
export interface SingleCallCompiler {
|
||||||
compileSingleCall(
|
compileSingleCall(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
import type { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { CompiledCode } from '../CompiledCode';
|
import type { CompiledCode } from '../CompiledCode';
|
||||||
import { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
import type { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
|
||||||
|
|
||||||
export interface SingleCallCompilerStrategy {
|
export interface SingleCallCompilerStrategy {
|
||||||
canCompile(func: ISharedFunction): boolean;
|
canCompile(func: ISharedFunction): boolean;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
||||||
|
|
||||||
export interface ArgumentCompiler {
|
export interface ArgumentCompiler {
|
||||||
createCompiledNestedCall(
|
createCompiledNestedCall(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
|
||||||
import { FunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
|
import { FunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
|
||||||
import { FunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgumentCollection';
|
import { FunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgumentCollection';
|
||||||
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
|
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
|
||||||
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
||||||
import { ParsedFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/ParsedFunctionCall';
|
import { ParsedFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/ParsedFunctionCall';
|
||||||
import { ArgumentCompiler } from './ArgumentCompiler';
|
import type { ArgumentCompiler } from './ArgumentCompiler';
|
||||||
|
|
||||||
export class NestedFunctionArgumentCompiler implements ArgumentCompiler {
|
export class NestedFunctionArgumentCompiler implements ArgumentCompiler {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
|
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
|
||||||
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||||
import { FunctionBodyType, ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
import { FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
|
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
|
||||||
import { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
|
import type { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
|
||||||
|
|
||||||
export class InlineFunctionCallCompiler implements SingleCallCompilerStrategy {
|
export class InlineFunctionCallCompiler implements SingleCallCompilerStrategy {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { CallFunctionBody, FunctionBodyType, ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
import { type CallFunctionBody, FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
|
||||||
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
|
||||||
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
|
||||||
import { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
|
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
|
||||||
import { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
|
|
||||||
import { ArgumentCompiler } from './Argument/ArgumentCompiler';
|
|
||||||
import { NestedFunctionArgumentCompiler } from './Argument/NestedFunctionArgumentCompiler';
|
import { NestedFunctionArgumentCompiler } from './Argument/NestedFunctionArgumentCompiler';
|
||||||
|
import type { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
|
||||||
|
import type { ArgumentCompiler } from './Argument/ArgumentCompiler';
|
||||||
|
|
||||||
export class NestedFunctionCallCompiler implements SingleCallCompilerStrategy {
|
export class NestedFunctionCallCompiler implements SingleCallCompilerStrategy {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
|
import type { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
|
||||||
|
|
||||||
export interface FunctionCall {
|
export interface FunctionCall {
|
||||||
readonly functionName: string;
|
readonly functionName: string;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { FunctionCallData, FunctionCallsData, FunctionCallParametersData } from '@/application/collections/';
|
import type { FunctionCallData, FunctionCallsData, FunctionCallParametersData } from '@/application/collections/';
|
||||||
import { isArray, isPlainObject } from '@/TypeHelpers';
|
import { isArray, isPlainObject } from '@/TypeHelpers';
|
||||||
import { FunctionCall } from './FunctionCall';
|
|
||||||
import { FunctionCallArgumentCollection } from './Argument/FunctionCallArgumentCollection';
|
import { FunctionCallArgumentCollection } from './Argument/FunctionCallArgumentCollection';
|
||||||
import { FunctionCallArgument } from './Argument/FunctionCallArgument';
|
import { FunctionCallArgument } from './Argument/FunctionCallArgument';
|
||||||
import { ParsedFunctionCall } from './ParsedFunctionCall';
|
import { ParsedFunctionCall } from './ParsedFunctionCall';
|
||||||
|
import type { FunctionCall } from './FunctionCall';
|
||||||
|
|
||||||
export function parseFunctionCalls(calls: FunctionCallsData): FunctionCall[] {
|
export function parseFunctionCalls(calls: FunctionCallsData): FunctionCall[] {
|
||||||
const sequence = getCallSequence(calls);
|
const sequence = getCallSequence(calls);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
|
import type { FunctionCall } from './FunctionCall';
|
||||||
import { FunctionCall } from './FunctionCall';
|
import type { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
|
||||||
|
|
||||||
export class ParsedFunctionCall implements FunctionCall {
|
export class ParsedFunctionCall implements FunctionCall {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IReadOnlyFunctionParameterCollection } from './Parameter/IFunctionParameterCollection';
|
import type { IReadOnlyFunctionParameterCollection } from './Parameter/IFunctionParameterCollection';
|
||||||
import { FunctionCall } from './Call/FunctionCall';
|
import type { FunctionCall } from './Call/FunctionCall';
|
||||||
|
|
||||||
export interface ISharedFunction {
|
export interface ISharedFunction {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ISharedFunction } from './ISharedFunction';
|
import type { ISharedFunction } from './ISharedFunction';
|
||||||
|
|
||||||
export interface ISharedFunctionCollection {
|
export interface ISharedFunctionCollection {
|
||||||
getFunctionByName(name: string): ISharedFunction;
|
getFunctionByName(name: string): ISharedFunction;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { FunctionData } from '@/application/collections/';
|
import type { FunctionData } from '@/application/collections/';
|
||||||
import { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
|
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
|
||||||
import { ISharedFunctionCollection } from './ISharedFunctionCollection';
|
import type { ISharedFunctionCollection } from './ISharedFunctionCollection';
|
||||||
|
|
||||||
export interface ISharedFunctionsParser {
|
export interface ISharedFunctionsParser {
|
||||||
parseFunctions(
|
parseFunctions(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ensureValidParameterName } from '../Shared/ParameterNameValidator';
|
import { ensureValidParameterName } from '../Shared/ParameterNameValidator';
|
||||||
import { IFunctionParameter } from './IFunctionParameter';
|
import type { IFunctionParameter } from './IFunctionParameter';
|
||||||
|
|
||||||
export class FunctionParameter implements IFunctionParameter {
|
export class FunctionParameter implements IFunctionParameter {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IFunctionParameterCollection } from './IFunctionParameterCollection';
|
import type { IFunctionParameterCollection } from './IFunctionParameterCollection';
|
||||||
import { IFunctionParameter } from './IFunctionParameter';
|
import type { IFunctionParameter } from './IFunctionParameter';
|
||||||
|
|
||||||
export class FunctionParameterCollection implements IFunctionParameterCollection {
|
export class FunctionParameterCollection implements IFunctionParameterCollection {
|
||||||
private parameters = new Array<IFunctionParameter>();
|
private parameters = new Array<IFunctionParameter>();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user