Compare commits

..

1 Commits

Author SHA1 Message Date
undergroundwires
d77b049a93 win: fix & improve disabling Nvidia telemetry $308
- Add missing permissions to delete telemetry driver $308.
- Remove unneeded recursion
- Improve disabling of Nvidia telemetry container. Terminate telemetry
  container on launch.
- Write NVIDIA in all uppercase which is the correct way.
- Add disabling NVIDIA game session telemetry.
- Remove script `Remove NVIDIA telemetry packages` and split its logic
  to other related script for better and more simplified organization.
2024-01-25 18:39:06 +01:00
677 changed files with 6133 additions and 10900 deletions

View File

@@ -3,7 +3,7 @@ root = true # Top-most EditorConfig file
[*]
end_of_line = lf
[*.{js,jsx,ts,tsx,vue,sh,scss}]
[*.{js,jsx,ts,tsx,vue,sh}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
@@ -24,10 +24,3 @@ indent_style = space
indent_size = 4
trim_trailing_whitespace = 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

View File

@@ -3,9 +3,6 @@ name: checks.external-urls
on:
schedule:
- cron: '0 0 * * 0' # at 00:00 on every Sunday
push:
paths:
- tests/checks/external-urls/**
jobs:
run-check:

View File

@@ -20,7 +20,6 @@ jobs:
fetch-depth: 0 # fetch all history
-
name: Checkout to bump commit
shell: bash
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
-
name: Setup node

31
2 Normal file
View File

@@ -0,0 +1,31 @@
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
#

View File

@@ -1,34 +1,5 @@
# 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)
* Fix CSP for Vue, Ace, Vite, Safari compatibility | [940febc](https://github.com/undergroundwires/privacy.sexy/commit/940febc3e80cfd0c01b5cc8282ebaab6b024d1b5)

View File

@@ -1,6 +1,6 @@
# privacy.sexy — Privacy is sexy
# privacy.sexy — Now you have the choice
> 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 -->
<p align="center">
@@ -122,7 +122,7 @@
## Get started
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
- 🖥️ **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).
- 🖥️ **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).
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).

View File

@@ -37,7 +37,6 @@ privacy.sexy adopts a defense in depth strategy to protect users on multiple lay
- **Auditing and Transparency:**
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.
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these logs.
- **Privilege Management:**
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
@@ -46,7 +45,6 @@ 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
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.
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these scripts.
### Update Security and Integrity

View File

@@ -51,8 +51,6 @@ Log file locations vary by operating system:
- Linux: `$HOME/.config/privacy.sexy/logs`
- Windows: `%APPDATA%\privacy.sexy\logs`
> 💡 privacy.sexy provides scripts to securely erase these logs.
### Script execution
The desktop version of privacy.sexy enables direct script execution, providing a seamless and integrated experience.
@@ -67,8 +65,6 @@ These locations vary based on the operating system:
- Linux: `$HOME/.config/privacy.sexy/runs`
- Windows: `%APPDATA%\privacy.sexy\runs`
> 💡 privacy.sexy provides scripts to securely erase your script execution history.
### Error handling
The desktop version of privacy.sexy features advanced error handling capabilities.

View File

@@ -32,12 +32,7 @@ The presentation layer uses an event-driven architecture for bidirectional react
## Visual design best-practices
- **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.
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.
## Application data

View File

@@ -1,5 +1,5 @@
import { resolve } from 'node:path';
import { mergeConfig, type UserConfig } from 'vite';
import { mergeConfig, UserConfig } from 'vite';
import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
import { getAliases, getClientEnvironmentVariables } from './vite-config-helper';
import { createVueConfig } from './vite.config';

4238
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
{
"name": "privacy.sexy",
"version": "0.13.0",
"version": "0.12.10",
"private": true,
"slogan": "Privacy is sexy",
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
"slogan": "Now you have the choice",
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆",
"author": "undergroundwires",
"type": "module",
"scripts": {
@@ -35,7 +35,6 @@
"dependencies": {
"@floating-ui/vue": "^1.0.2",
"@juggle/resize-observer": "^3.4.0",
"@types/markdown-it": "^13.0.7",
"ace-builds": "^1.30.0",
"electron-log": "^5.0.1",
"electron-progressbar": "^2.1.0",
@@ -45,14 +44,14 @@
"vue": "^3.3.7"
},
"devDependencies": {
"@modyfi/vite-plugin-yaml": "^1.1.0",
"@modyfi/vite-plugin-yaml": "^1.0.4",
"@rushstack/eslint-patch": "^1.6.1",
"@types/ace": "^0.0.49",
"@types/file-saver": "^2.0.5",
"@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.17.0",
"@vitejs/plugin-legacy": "^5.3.2",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-legacy": "^4.1.1",
"@vitejs/plugin-vue": "^4.4.0",
"@vue/eslint-config-airbnb-with-typescript": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/test-utils": "^2.4.1",
@@ -62,7 +61,7 @@
"electron-builder": "^24.6.4",
"electron-devtools-installer": "^3.2.0",
"electron-icon-builder": "^2.0.1",
"electron-vite": "^2.1.0",
"electron-vite": "^1.0.28",
"eslint": "^8.56.0",
"eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-vue": "^9.19.2",
@@ -80,8 +79,8 @@
"svgexport": "^0.4.2",
"terser": "^5.21.0",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vite": "^5.1.6",
"typescript": "^5.2.2",
"vite": "^4.4.11",
"vitest": "^0.34.6",
"vue-tsc": "^1.8.19",
"yaml-lint": "^1.7.0"

View File

@@ -6,11 +6,10 @@ development and installs recommended extensions from '.vscode/extensions.json'.
import os
import json
from pathlib import Path
import subprocess
import sys
import re
from typing import Any, Optional
from typing import Any
from shutil import which
VSCODE_SETTINGS_JSON_FILE: str = '.vscode/settings.json'
@@ -85,7 +84,7 @@ def install_recommended_extensions() -> None:
if not extensions:
print_skip(f"No recommendations found in the {VSCODE_EXTENSIONS_JSON_FILE} file.")
return
vscode_cli_path = locate_vscode_cli()
vscode_cli_path = which('code') # More reliable than using `code`, especially on Windows.
if vscode_cli_path is None:
print_error('Visual Studio Code CLI (`code`) tool not found.')
return
@@ -93,23 +92,11 @@ def install_recommended_extensions() -> None:
except json.JSONDecodeError:
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:
pattern: str = r'(?:"(?:\\.|[^"\\])*"|/\*[\s\S]*?\*/|//.*)|([^:]//.*$)'
return re.sub(
pattern,
lambda m: '' if m.group(1) else m.agroup(0), json_like, flags=re.MULTILINE,
lambda m: '' if m.group(1) else m.group(0), json_like, flags=re.MULTILINE,
)
def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> None:
@@ -136,12 +123,6 @@ def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> No
f"Visual Studio Code CLI tool not found: {vscode_cli_path}."
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)
print_installation_results(successful_installations, total_extensions)

View File

@@ -1,7 +1,7 @@
import type { IApplication } from '@/domain/IApplication';
import { IApplication } from '@/domain/IApplication';
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
import { IApplicationFactory } from './IApplicationFactory';
import { parseApplication } from './Parser/ApplicationParser';
import type { IApplicationFactory } from './IApplicationFactory';
export type ApplicationGetterType = () => IApplication;
const ApplicationGetter: ApplicationGetterType = parseApplication;

View File

@@ -1,6 +1,6 @@
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { assertInRange } from '@/application/Common/Enum';
import type { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
import { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
type Getter<T> = () => T;

View File

@@ -1,5 +1,5 @@
import { PlatformTimer } from './PlatformTimer';
import type { TimeoutType, Timer } from './Timer';
import { TimeoutType, Timer } from './Timer';
export function batchedDebounce<T>(
callback: (batches: readonly T[]) => void,

View File

@@ -1,4 +1,4 @@
import type { Timer } from './Timer';
import { Timer } from './Timer';
export const PlatformTimer: Timer = {
setTimeout: (callback, ms) => setTimeout(callback, ms),

View File

@@ -1,5 +1,5 @@
import { Timer, TimeoutType } from './Timer';
import { PlatformTimer } from './PlatformTimer';
import type { Timer, TimeoutType } from './Timer';
export type CallbackType = (..._: readonly unknown[]) => void;

View File

@@ -1,11 +1,11 @@
import type { IApplication } from '@/domain/IApplication';
import { IApplication } from '@/domain/IApplication';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { assertInRange } from '@/application/Common/Enum';
import { CategoryCollectionState } from './State/CategoryCollectionState';
import type { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
import type { ICategoryCollectionState } from './State/ICategoryCollectionState';
import { ICategoryCollectionState } from './State/ICategoryCollectionState';
import { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;

View File

@@ -1,10 +1,10 @@
import type { IApplicationContext } from '@/application/Context/IApplicationContext';
import { IApplicationContext } from '@/application/Context/IApplicationContext';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IApplication } from '@/domain/IApplication';
import { IApplication } from '@/domain/IApplication';
import { CurrentEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironmentFactory';
import { IApplicationFactory } from '../IApplicationFactory';
import { ApplicationFactory } from '../ApplicationFactory';
import { ApplicationContext } from './ApplicationContext';
import type { IApplicationFactory } from '../IApplicationFactory';
export async function buildContext(
factory: IApplicationFactory = ApplicationFactory.Current,

View File

@@ -1,7 +1,7 @@
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
import type { IApplication } from '@/domain/IApplication';
import type { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IApplication } from '@/domain/IApplication';
import { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState';
export interface IReadOnlyApplicationContext {
readonly app: IApplication;

View File

@@ -1,12 +1,12 @@
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { AdaptiveFilterContext } from './Filter/AdaptiveFilterContext';
import { UserFilter } from './Filter/UserFilter';
import { IUserFilter } from './Filter/IUserFilter';
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 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 {
public readonly os: OperatingSystem;
@@ -15,7 +15,7 @@ export class CategoryCollectionState implements ICategoryCollectionState {
public readonly selection: UserSelection;
public readonly filter: FilterContext;
public readonly filter: IUserFilter;
public constructor(
public readonly collection: ICategoryCollection,
@@ -45,7 +45,7 @@ const DefaultSelectionFactory: SelectionFactory = (
) => new UserSelectionFacade(...params);
export type FilterFactory = (
...params: ConstructorParameters<typeof AdaptiveFilterContext>
) => FilterContext;
...params: ConstructorParameters<typeof UserFilter>
) => IUserFilter;
const DefaultFilterFactory: FilterFactory = (...params) => new AdaptiveFilterContext(...params);
const DefaultFilterFactory: FilterFactory = (...params) => new UserFilter(...params);

View File

@@ -1,13 +1,13 @@
import { EventSource } from '@/infrastructure/Events/EventSource';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import type { ReadonlyScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { ReadonlyScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
import { CodeChangedEvent } from './Event/CodeChangedEvent';
import { CodePosition } from './Position/CodePosition';
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import { UserScriptGenerator } from './Generation/UserScriptGenerator';
import type { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
import type { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import type { IApplicationCode } from './IApplicationCode';
import { IApplicationCode } from './IApplicationCode';
import { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
export class ApplicationCode implements IApplicationCode {
public readonly changed = new EventSource<ICodeChangedEvent>();

View File

@@ -1,7 +1,7 @@
import type { IScript } from '@/domain/IScript';
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import type { ICodeChangedEvent } from './ICodeChangedEvent';
import { IScript } from '@/domain/IScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { ICodeChangedEvent } from './ICodeChangedEvent';
export class CodeChangedEvent implements ICodeChangedEvent {
public readonly code: string;

View File

@@ -1,5 +1,5 @@
import type { IScript } from '@/domain/IScript';
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { IScript } from '@/domain/IScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
export interface ICodeChangedEvent {
readonly code: string;

View File

@@ -1,4 +1,4 @@
import type { ICodeBuilder } from './ICodeBuilder';
import { ICodeBuilder } from './ICodeBuilder';
const TotalFunctionSeparatorChars = 58;

View File

@@ -1,9 +1,9 @@
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICodeBuilder } from './ICodeBuilder';
import { BatchBuilder } from './Languages/BatchBuilder';
import { ShellBuilder } from './Languages/ShellBuilder';
import type { ICodeBuilder } from './ICodeBuilder';
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class CodeBuilderFactory
extends ScriptingLanguageFactory<ICodeBuilder>

View File

@@ -1,4 +1,4 @@
import type { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
import type { ICodeBuilder } from './ICodeBuilder';
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
import { ICodeBuilder } from './ICodeBuilder';
export type ICodeBuilderFactory = IScriptingLanguageFactory<ICodeBuilder>;

View File

@@ -1,5 +1,5 @@
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
export interface IUserScript {
readonly code: string;

View File

@@ -1,6 +1,6 @@
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import type { IUserScript } from './IUserScript';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { IUserScript } from './IUserScript';
export interface IUserScriptGenerator {
buildCode(

View File

@@ -1,12 +1,12 @@
import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
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 type { IUserScriptGenerator } from './IUserScriptGenerator';
import type { IUserScript } from './IUserScript';
import type { ICodeBuilder } from './ICodeBuilder';
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class UserScriptGenerator implements IUserScriptGenerator {
constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) {

View File

@@ -1,5 +1,5 @@
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
import type { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
export interface IApplicationCode {
readonly changed: IEventSource<ICodeChangedEvent>;

View File

@@ -1,4 +1,4 @@
import type { ICodePosition } from './ICodePosition';
import { ICodePosition } from './ICodePosition';
export class CodePosition implements ICodePosition {
public get totalLines(): number {

View File

@@ -1,35 +0,0 @@
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());
}
}

View File

@@ -1,24 +1,24 @@
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
import { FilterActionType } from './FilterActionType';
import type {
FilterChangeDetails, FilterChangeDetailsVisitor,
import {
IFilterChangeDetails, IFilterChangeDetailsVisitor,
ApplyFilterAction, ClearFilterAction,
} from './FilterChangeDetails';
} from './IFilterChangeDetails';
export class FilterChange implements FilterChangeDetails {
export class FilterChange implements IFilterChangeDetails {
public static forApply(
filter: FilterResult,
): FilterChangeDetails {
filter: IFilterResult,
): IFilterChangeDetails {
return new FilterChange({ type: FilterActionType.Apply, filter });
}
public static forClear(): FilterChangeDetails {
public static forClear(): IFilterChangeDetails {
return new FilterChange({ type: FilterActionType.Clear });
}
private constructor(public readonly action: ApplyFilterAction | ClearFilterAction) { }
public visit(visitor: FilterChangeDetailsVisitor): void {
public visit(visitor: IFilterChangeDetailsVisitor): void {
switch (this.action.type) {
case FilterActionType.Apply:
if (visitor.onApply) {

View File

@@ -1,23 +0,0 @@
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;

View File

@@ -0,0 +1,23 @@
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;

View File

@@ -1,13 +0,0 @@
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;
}

View File

@@ -1,8 +1,8 @@
import type { IScript } from '@/domain/IScript';
import type { ICategory } from '@/domain/ICategory';
import type { FilterResult } from './FilterResult';
import { IScript } from '@/domain/IScript';
import { ICategory } from '@/domain/ICategory';
import { IFilterResult } from './IFilterResult';
export class AppliedFilterResult implements FilterResult {
export class FilterResult implements IFilterResult {
constructor(
public readonly scriptMatches: ReadonlyArray<IScript>,
public readonly categoryMatches: ReadonlyArray<ICategory>,

View File

@@ -1,6 +1,6 @@
import type { IScript, ICategory } from '@/domain/ICategory';
import { IScript, ICategory } from '@/domain/ICategory';
export interface FilterResult {
export interface IFilterResult {
readonly categoryMatches: ReadonlyArray<ICategory>;
readonly scriptMatches: ReadonlyArray<IScript>;
readonly query: string;

View File

@@ -0,0 +1,13 @@
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;
}

View File

@@ -1,9 +0,0 @@
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import type { FilterResult } from '../Result/FilterResult';
export interface FilterStrategy {
applyFilter(
filter: string,
collection: ICategoryCollection,
): FilterResult;
}

View File

@@ -1,80 +0,0 @@
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),
);
}

View File

@@ -0,0 +1,56 @@
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;
}

View File

@@ -1,18 +1,18 @@
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { IApplicationCode } from './Code/IApplicationCode';
import type { ReadonlyFilterContext, FilterContext } from './Filter/FilterContext';
import type { ReadonlyUserSelection, UserSelection } from './Selection/UserSelection';
import { IReadOnlyUserFilter, IUserFilter } from './Filter/IUserFilter';
import { ReadonlyUserSelection, UserSelection } from './Selection/UserSelection';
import { IApplicationCode } from './Code/IApplicationCode';
export interface IReadOnlyCategoryCollectionState {
readonly code: IApplicationCode;
readonly os: OperatingSystem;
readonly filter: ReadonlyFilterContext;
readonly filter: IReadOnlyUserFilter;
readonly selection: ReadonlyUserSelection;
readonly collection: ICategoryCollection;
}
export interface ICategoryCollectionState extends IReadOnlyCategoryCollectionState {
readonly filter: FilterContext;
readonly filter: IUserFilter;
readonly selection: UserSelection;
}

View File

@@ -1,5 +1,5 @@
import type { ICategory } from '@/domain/ICategory';
import type { CategorySelectionChangeCommand } from './CategorySelectionChange';
import { ICategory } from '@/domain/ICategory';
import { CategorySelectionChangeCommand } from './CategorySelectionChange';
export interface ReadonlyCategorySelection {
areAllScriptsSelected(category: ICategory): boolean;

View File

@@ -1,9 +1,9 @@
import type { ICategory } from '@/domain/ICategory';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import type { CategorySelectionChange, CategorySelectionChangeCommand } from './CategorySelectionChange';
import type { CategorySelection } from './CategorySelection';
import type { ScriptSelection } from '../Script/ScriptSelection';
import type { ScriptSelectionChange } from '../Script/ScriptSelectionChange';
import { ICategory } from '@/domain/ICategory';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ScriptSelection } from '../Script/ScriptSelection';
import { ScriptSelectionChange } from '../Script/ScriptSelectionChange';
import { CategorySelection } from './CategorySelection';
import { CategorySelectionChange, CategorySelectionChangeCommand } from './CategorySelectionChange';
export class ScriptToCategorySelectionMapper implements CategorySelection {
constructor(

View File

@@ -1,13 +1,13 @@
import { InMemoryRepository } from '@/infrastructure/Repository/InMemoryRepository';
import type { IScript } from '@/domain/IScript';
import { IScript } from '@/domain/IScript';
import { EventSource } from '@/infrastructure/Events/EventSource';
import type { ReadonlyRepository, Repository } from '@/application/Repository/Repository';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ReadonlyRepository, Repository } from '@/application/Repository/Repository';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
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 type { ScriptSelection } from './ScriptSelection';
import type { ScriptSelectionChange, ScriptSelectionChangeCommand } from './ScriptSelectionChange';
import type { SelectedScript } from './SelectedScript';
const DEBOUNCE_DELAY_IN_MS = 100;
@@ -81,7 +81,9 @@ export class DebouncedScriptSelection implements ScriptSelection {
}
public selectOnly(scripts: readonly IScript[]): void {
assertNonEmptyScriptSelection(scripts);
if (scripts.length === 0) {
throw new Error('Provided script array is empty. To deselect all scripts, please use the deselectAll() method instead.');
}
this.processChanges({
changes: [
...getScriptIdsToBeDeselected(this.scripts, scripts)
@@ -145,12 +147,6 @@ 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(
existingItems: ReadonlyRepository<string, SelectedScript>,
desiredScripts: readonly IScript[],

View File

@@ -1,7 +1,7 @@
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
import type { IScript } from '@/domain/IScript';
import type { SelectedScript } from './SelectedScript';
import type { ScriptSelectionChangeCommand } from './ScriptSelectionChange';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IScript } from '@/domain/IScript';
import { SelectedScript } from './SelectedScript';
import { ScriptSelectionChangeCommand } from './ScriptSelectionChange';
export interface ReadonlyScriptSelection {
readonly changed: IEventSource<readonly SelectedScript[]>;

View File

@@ -3,7 +3,6 @@ export type ScriptSelectionStatus = {
readonly isReverted: boolean;
} | {
readonly isSelected: false;
readonly isReverted?: undefined;
};
export interface ScriptSelectionChange {

View File

@@ -1,5 +1,5 @@
import type { IEntity } from '@/infrastructure/Entity/IEntity';
import type { IScript } from '@/domain/IScript';
import { IEntity } from '@/infrastructure/Entity/IEntity';
import { IScript } from '@/domain/IScript';
type ScriptId = IScript['id'];

View File

@@ -1,6 +1,6 @@
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
import type { IScript } from '@/domain/IScript';
import type { SelectedScript } from './SelectedScript';
import { IScript } from '@/domain/IScript';
import { SelectedScript } from './SelectedScript';
type SelectedScriptId = SelectedScript['id'];

View File

@@ -1,5 +1,5 @@
import type { CategorySelection, ReadonlyCategorySelection } from './Category/CategorySelection';
import type { ReadonlyScriptSelection, ScriptSelection } from './Script/ScriptSelection';
import { CategorySelection, ReadonlyCategorySelection } from './Category/CategorySelection';
import { ReadonlyScriptSelection, ScriptSelection } from './Script/ScriptSelection';
export interface ReadonlyUserSelection {
readonly categories: ReadonlyCategorySelection;

View File

@@ -1,10 +1,10 @@
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { CategorySelection } from './Category/CategorySelection';
import { ScriptToCategorySelectionMapper } from './Category/ScriptToCategorySelectionMapper';
import { DebouncedScriptSelection } from './Script/DebouncedScriptSelection';
import type { CategorySelection } from './Category/CategorySelection';
import type { ScriptSelection } from './Script/ScriptSelection';
import type { UserSelection } from './UserSelection';
import type { SelectedScript } from './Script/SelectedScript';
import { ScriptSelection } from './Script/ScriptSelection';
import { UserSelection } from './UserSelection';
import { SelectedScript } from './Script/SelectedScript';
export class UserSelectionFacade implements UserSelection {
public readonly categories: CategorySelection;

View File

@@ -1,4 +1,4 @@
import type { IApplication } from '@/domain/IApplication';
import { IApplication } from '@/domain/IApplication';
export interface IApplicationFactory {
getApp(): Promise<IApplication>;

View File

@@ -1,33 +1,31 @@
import type { CollectionData } from '@/application/collections/';
import type { IApplication } from '@/domain/IApplication';
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { IApplication } from '@/domain/IApplication';
import { IProjectInformation } from '@/domain/IProjectInformation';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import WindowsData from '@/application/collections/windows.yaml';
import MacOsData from '@/application/collections/macos.yaml';
import LinuxData from '@/application/collections/linux.yaml';
import { parseProjectDetails } from '@/application/Parser/ProjectDetailsParser';
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
import { Application } from '@/domain/Application';
import type { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
import { IAppMetadata } from '@/infrastructure/EnvironmentVariables/IAppMetadata';
import { EnvironmentVariablesFactory } from '@/infrastructure/EnvironmentVariables/EnvironmentVariablesFactory';
import { parseCategoryCollection } from './CategoryCollectionParser';
export function parseApplication(
categoryParser = parseCategoryCollection,
projectDetailsParser = parseProjectDetails,
informationParser = parseProjectInformation,
metadata: IAppMetadata = EnvironmentVariablesFactory.Current.instance,
collectionsData = PreParsedCollections,
): IApplication {
validateCollectionsData(collectionsData);
const projectDetails = projectDetailsParser(metadata);
const collections = collectionsData.map(
(collection) => categoryParser(collection, projectDetails),
);
const app = new Application(projectDetails, collections);
const information = informationParser(metadata);
const collections = collectionsData.map((collection) => categoryParser(collection, information));
const app = new Application(information, collections);
return app;
}
export type CategoryCollectionParserType
= (file: CollectionData, projectDetails: ProjectDetails) => ICategoryCollection;
= (file: CollectionData, info: IProjectInformation) => ICategoryCollection;
const PreParsedCollections: readonly CollectionData [] = [
WindowsData, MacOsData, LinuxData,

View File

@@ -1,8 +1,8 @@
import type { CollectionData } from '@/application/collections/';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { CategoryCollection } from '@/domain/CategoryCollection';
import type { ProjectDetails } from '@/domain/Project/ProjectDetails';
import { IProjectInformation } from '@/domain/IProjectInformation';
import { createEnumParser } from '../Common/Enum';
import { parseCategory } from './CategoryParser';
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
@@ -10,12 +10,12 @@ import { ScriptingDefinitionParser } from './ScriptingDefinition/ScriptingDefini
export function parseCategoryCollection(
content: CollectionData,
projectDetails: ProjectDetails,
info: IProjectInformation,
osParser = createEnumParser(OperatingSystem),
): ICategoryCollection {
validate(content);
const scripting = new ScriptingDefinitionParser()
.parse(content.scripting, projectDetails);
.parse(content.scripting, info);
const context = new CategoryCollectionParseContext(content.functions, scripting);
const categories = content.actions.map((action) => parseCategory(action, context));
const os = osParser.parseEnum(content.os, 'os');

View File

@@ -6,8 +6,8 @@ import { Category } from '@/domain/Category';
import { NodeValidator } from '@/application/Parser/NodeValidation/NodeValidator';
import { NodeType } from '@/application/Parser/NodeValidation/NodeType';
import { parseDocs } from './DocumentationParser';
import { ICategoryCollectionParseContext } from './Script/ICategoryCollectionParseContext';
import { parseScript } from './Script/ScriptParser';
import type { ICategoryCollectionParseContext } from './Script/ICategoryCollectionParseContext';
let categoryIdCounter = 0;

View File

@@ -1,6 +1,6 @@
import { CustomError } from '@/application/Common/CustomError';
import { NodeType } from './NodeType';
import type { NodeData } from './NodeData';
import { NodeData } from './NodeData';
export class NodeDataError extends CustomError {
constructor(message: string, public readonly context: INodeDataErrorContext) {

View File

@@ -1,6 +1,6 @@
import { isString } from '@/TypeHelpers';
import { type INodeDataErrorContext, NodeDataError } from './NodeDataError';
import type { NodeData } from './NodeData';
import { INodeDataErrorContext, NodeDataError } from './NodeDataError';
import { NodeData } from './NodeData';
export class NodeValidator {
constructor(private readonly context: INodeDataErrorContext) {

View File

@@ -1,29 +0,0 @@
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;

View File

@@ -0,0 +1,29 @@
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;

View File

@@ -1,11 +1,11 @@
import type { FunctionData } from '@/application/collections/';
import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { IScriptCompiler } from './Compiler/IScriptCompiler';
import { ScriptCompiler } from './Compiler/ScriptCompiler';
import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
import { SyntaxFactory } from './Validation/Syntax/SyntaxFactory';
import type { ILanguageSyntax } from './Validation/Syntax/ILanguageSyntax';
import type { IScriptCompiler } from './Compiler/IScriptCompiler';
import type { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
import type { ISyntaxFactory } from './Validation/Syntax/ISyntaxFactory';
import { ISyntaxFactory } from './Validation/Syntax/ISyntaxFactory';
import { ILanguageSyntax } from './Validation/Syntax/ILanguageSyntax';
export class CategoryCollectionParseContext implements ICategoryCollectionParseContext {
public readonly compiler: IScriptCompiler;

View File

@@ -1,10 +1,10 @@
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 { ExpressionEvaluationContext, type IExpressionEvaluationContext } from './ExpressionEvaluationContext';
import { IExpression } from './IExpression';
import { ExpressionPosition } from './ExpressionPosition';
import type { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
import type { IExpression } from './IExpression';
import { ExpressionEvaluationContext, IExpressionEvaluationContext } from './ExpressionEvaluationContext';
export type ExpressionEvaluator = (context: IExpressionEvaluationContext) => string;
export class Expression implements IExpression {

View File

@@ -1,6 +1,6 @@
import { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
import { IPipelineCompiler } from '../Pipes/IPipelineCompiler';
import { PipelineCompiler } from '../Pipes/PipelineCompiler';
import type { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
import type { IPipelineCompiler } from '../Pipes/IPipelineCompiler';
export interface IExpressionEvaluationContext {
readonly args: IReadOnlyFunctionCallArgumentCollection;

View File

@@ -1,6 +1,6 @@
import { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
import { ExpressionPosition } from './ExpressionPosition';
import type { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
import type { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
import { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
export interface IExpression {
readonly position: ExpressionPosition;

View File

@@ -1,9 +1,9 @@
import { type IExpressionEvaluationContext, ExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
import { 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 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 {
public constructor(

View File

@@ -1,4 +1,4 @@
import type { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
import { IReadOnlyFunctionCallArgumentCollection } from '../Function/Call/Argument/IFunctionCallArgumentCollection';
export interface IExpressionsCompiler {
compileExpressions(

View File

@@ -1,7 +1,7 @@
import { IExpression } from '../Expression/IExpression';
import { ParameterSubstitutionParser } from '../SyntaxParsers/ParameterSubstitutionParser';
import { WithParser } from '../SyntaxParsers/WithParser';
import type { IExpression } from '../Expression/IExpression';
import type { IExpressionParser } from './IExpressionParser';
import { IExpressionParser } from './IExpressionParser';
const Parsers = [
new ParameterSubstitutionParser(),

View File

@@ -1,4 +1,4 @@
import type { IExpression } from '../Expression/IExpression';
import { IExpression } from '../Expression/IExpression';
export interface IExpressionParser {
findExpressions(code: string): IExpression[];

View File

@@ -1,9 +1,9 @@
import { Expression, type ExpressionEvaluator } from '../../Expression/Expression';
import { IExpressionParser } from '../IExpressionParser';
import { IExpression } from '../../Expression/IExpression';
import { Expression, ExpressionEvaluator } from '../../Expression/Expression';
import { IFunctionParameter } from '../../../Function/Parameter/IFunctionParameter';
import { FunctionParameterCollection } from '../../../Function/Parameter/FunctionParameterCollection';
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 {
protected abstract readonly regex: RegExp;

View File

@@ -1,4 +1,4 @@
import type { IPipe } from '../IPipe';
import { IPipe } from '../IPipe';
export class EscapeDoubleQuotes implements IPipe {
public readonly name: string = 'escapeDoubleQuotes';

View File

@@ -1,4 +1,4 @@
import type { IPipe } from '../IPipe';
import { IPipe } from '../IPipe';
export class InlinePowerShell implements IPipe {
public readonly name: string = 'inlinePowerShell';

View File

@@ -1,6 +1,6 @@
import { IPipe } from './IPipe';
import { InlinePowerShell } from './PipeDefinitions/InlinePowerShell';
import { EscapeDoubleQuotes } from './PipeDefinitions/EscapeDoubleQuotes';
import type { IPipe } from './IPipe';
const RegisteredPipes = [
new EscapeDoubleQuotes(),

View File

@@ -1,5 +1,5 @@
import { type IPipeFactory, PipeFactory } from './PipeFactory';
import type { IPipelineCompiler } from './IPipelineCompiler';
import { IPipeFactory, PipeFactory } from './PipeFactory';
import { IPipelineCompiler } from './IPipelineCompiler';
export class PipelineCompiler implements IPipelineCompiler {
constructor(private readonly factory: IPipeFactory = new PipeFactory()) { }

View File

@@ -1,5 +1,5 @@
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
import { RegexParser, type IPrimitiveExpression } from '../Parser/Regex/RegexParser';
import { RegexParser, IPrimitiveExpression } from '../Parser/Regex/RegexParser';
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
export class ParameterSubstitutionParser extends RegexParser {

View File

@@ -1,11 +1,11 @@
// eslint-disable-next-line max-classes-per-file
import type { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import { IExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/IExpressionParser';
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { FunctionParameter } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameter';
import { IExpression } from '../Expression/IExpression';
import { ExpressionPosition } from '../Expression/ExpressionPosition';
import { ExpressionRegexBuilder } from '../Parser/Regex/ExpressionRegexBuilder';
import { createPositionFromRegexFullMatch } from '../Expression/ExpressionPositionFactory';
import type { IExpression } from '../Expression/IExpression';
export class WithParser implements IExpressionParser {
public findExpressions(code: string): IExpression[] {

View File

@@ -1,5 +1,5 @@
import { ensureValidParameterName } from '../../Shared/ParameterNameValidator';
import type { IFunctionCallArgument } from './IFunctionCallArgument';
import { IFunctionCallArgument } from './IFunctionCallArgument';
export class FunctionCallArgument implements IFunctionCallArgument {
constructor(

View File

@@ -1,5 +1,5 @@
import type { IFunctionCallArgument } from './IFunctionCallArgument';
import type { IFunctionCallArgumentCollection } from './IFunctionCallArgumentCollection';
import { IFunctionCallArgument } from './IFunctionCallArgument';
import { IFunctionCallArgumentCollection } from './IFunctionCallArgumentCollection';
export class FunctionCallArgumentCollection implements IFunctionCallArgumentCollection {
private readonly arguments = new Map<string, IFunctionCallArgument>();

View File

@@ -1,4 +1,4 @@
import type { IFunctionCallArgument } from './IFunctionCallArgument';
import { IFunctionCallArgument } from './IFunctionCallArgument';
export interface IReadOnlyFunctionCallArgumentCollection {
getArgument(parameterName: string): IFunctionCallArgument;

View File

@@ -1,4 +1,4 @@
import type { CompiledCode } from '../CompiledCode';
import { CompiledCode } from '../CompiledCode';
export interface CodeSegmentMerger {
mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode;

View File

@@ -1,5 +1,5 @@
import type { CompiledCode } from '../CompiledCode';
import type { CodeSegmentMerger } from './CodeSegmentMerger';
import { CompiledCode } from '../CompiledCode';
import { CodeSegmentMerger } from './CodeSegmentMerger';
export class NewlineCodeSegmentMerger implements CodeSegmentMerger {
public mergeCodeParts(codeSegments: readonly CompiledCode[]): CompiledCode {

View File

@@ -1,5 +1,5 @@
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import type { FunctionCall } from '../FunctionCall';
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import { FunctionCall } from '../FunctionCall';
import type { SingleCallCompiler } from './SingleCall/SingleCallCompiler';
export interface FunctionCallCompilationContext {

View File

@@ -1,6 +1,6 @@
import type { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import type { CompiledCode } from './CompiledCode';
import type { FunctionCall } from '../FunctionCall';
import { ISharedFunctionCollection } from '@/application/Parser/Script/Compiler/Function/ISharedFunctionCollection';
import { FunctionCall } from '../FunctionCall';
import { CompiledCode } from './CompiledCode';
export interface FunctionCallCompiler {
compileFunctionCalls(

View File

@@ -1,12 +1,12 @@
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { NewlineCodeSegmentMerger } from './CodeSegmentJoin/NewlineCodeSegmentMerger';
import { 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 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';
import { CodeSegmentMerger } from './CodeSegmentJoin/CodeSegmentMerger';
import { NewlineCodeSegmentMerger } from './CodeSegmentJoin/NewlineCodeSegmentMerger';
export class FunctionCallSequenceCompiler implements FunctionCallCompiler {
public static readonly instance: FunctionCallCompiler = new FunctionCallSequenceCompiler();

View File

@@ -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 { 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 {
public constructor(

View File

@@ -1,6 +1,6 @@
import type { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
import type { FunctionCall } from '../../FunctionCall';
import type { CompiledCode } from '../CompiledCode';
import { FunctionCall } from '../../FunctionCall';
import { CompiledCode } from '../CompiledCode';
import { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
export interface SingleCallCompiler {
compileSingleCall(

View File

@@ -1,7 +1,7 @@
import type { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { CompiledCode } from '../CompiledCode';
import type { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
import { ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { CompiledCode } from '../CompiledCode';
import { FunctionCallCompilationContext } from '../FunctionCallCompilationContext';
export interface SingleCallCompilerStrategy {
canCompile(func: ISharedFunction): boolean;

View File

@@ -1,5 +1,5 @@
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
export interface ArgumentCompiler {
createCompiledNestedCall(

View File

@@ -1,12 +1,12 @@
import type { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { IReadOnlyFunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/IFunctionCallArgumentCollection';
import { FunctionCallArgument } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgument';
import { FunctionCallArgumentCollection } from '@/application/Parser/Script/Compiler/Function/Call/Argument/FunctionCallArgumentCollection';
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import { ParsedFunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/ParsedFunctionCall';
import type { ArgumentCompiler } from './ArgumentCompiler';
import { ArgumentCompiler } from './ArgumentCompiler';
export class NestedFunctionArgumentCompiler implements ArgumentCompiler {
constructor(

View File

@@ -1,9 +1,9 @@
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
import type { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import { FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import type { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
import { IExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
import { FunctionBodyType, ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
export class InlineFunctionCallCompiler implements SingleCallCompilerStrategy {
public constructor(

View File

@@ -1,10 +1,10 @@
import { type CallFunctionBody, FunctionBodyType, type ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import type { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import type { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import type { CompiledCode } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/CompiledCode';
import { CallFunctionBody, FunctionBodyType, ISharedFunction } from '@/application/Parser/Script/Compiler/Function/ISharedFunction';
import { FunctionCall } from '@/application/Parser/Script/Compiler/Function/Call/FunctionCall';
import { FunctionCallCompilationContext } from '@/application/Parser/Script/Compiler/Function/Call/Compiler/FunctionCallCompilationContext';
import { 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 type { SingleCallCompilerStrategy } from '../SingleCallCompilerStrategy';
import type { ArgumentCompiler } from './Argument/ArgumentCompiler';
export class NestedFunctionCallCompiler implements SingleCallCompilerStrategy {
public constructor(

View File

@@ -1,4 +1,4 @@
import type { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
import { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
export interface FunctionCall {
readonly functionName: string;

View File

@@ -1,9 +1,9 @@
import type { FunctionCallData, FunctionCallsData, FunctionCallParametersData } from '@/application/collections/';
import { isArray, isPlainObject } from '@/TypeHelpers';
import { FunctionCall } from './FunctionCall';
import { FunctionCallArgumentCollection } from './Argument/FunctionCallArgumentCollection';
import { FunctionCallArgument } from './Argument/FunctionCallArgument';
import { ParsedFunctionCall } from './ParsedFunctionCall';
import type { FunctionCall } from './FunctionCall';
export function parseFunctionCalls(calls: FunctionCallsData): FunctionCall[] {
const sequence = getCallSequence(calls);

View File

@@ -1,5 +1,5 @@
import type { FunctionCall } from './FunctionCall';
import type { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
import { IReadOnlyFunctionCallArgumentCollection } from './Argument/IFunctionCallArgumentCollection';
import { FunctionCall } from './FunctionCall';
export class ParsedFunctionCall implements FunctionCall {
constructor(

View File

@@ -1,5 +1,5 @@
import type { IReadOnlyFunctionParameterCollection } from './Parameter/IFunctionParameterCollection';
import type { FunctionCall } from './Call/FunctionCall';
import { IReadOnlyFunctionParameterCollection } from './Parameter/IFunctionParameterCollection';
import { FunctionCall } from './Call/FunctionCall';
export interface ISharedFunction {
readonly name: string;

View File

@@ -1,4 +1,4 @@
import type { ISharedFunction } from './ISharedFunction';
import { ISharedFunction } from './ISharedFunction';
export interface ISharedFunctionCollection {
getFunctionByName(name: string): ISharedFunction;

View File

@@ -1,6 +1,6 @@
import type { FunctionData } from '@/application/collections/';
import type { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import type { ISharedFunctionCollection } from './ISharedFunctionCollection';
import { ILanguageSyntax } from '@/application/Parser/Script/Validation/Syntax/ILanguageSyntax';
import { ISharedFunctionCollection } from './ISharedFunctionCollection';
export interface ISharedFunctionsParser {
parseFunctions(

View File

@@ -1,5 +1,5 @@
import { ensureValidParameterName } from '../Shared/ParameterNameValidator';
import type { IFunctionParameter } from './IFunctionParameter';
import { IFunctionParameter } from './IFunctionParameter';
export class FunctionParameter implements IFunctionParameter {
constructor(

View File

@@ -1,5 +1,5 @@
import type { IFunctionParameterCollection } from './IFunctionParameterCollection';
import type { IFunctionParameter } from './IFunctionParameter';
import { IFunctionParameterCollection } from './IFunctionParameterCollection';
import { IFunctionParameter } from './IFunctionParameter';
export class FunctionParameterCollection implements IFunctionParameterCollection {
private parameters = new Array<IFunctionParameter>();

Some files were not shown because too many files have changed in this diff Show More