Merge pull request #364 from OneUptime/workflow-project

fix validation errors on the modal
This commit is contained in:
Simon Larsen
2023-02-20 16:19:42 +00:00
committed by GitHub
179 changed files with 48306 additions and 4489 deletions

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install && npm run compile

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonUI && npm install --force && npm run compile

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install && npm run compile

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd Model && npm install && npm run compile

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && npm install

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
# Build and deploy file.

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
# Build and deploy accounts.

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
# Build and deploy file.

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3
# Build and deploy accounts.

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: npm run prerun
- run: sudo docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonServer && bash test-setup.sh

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Model && npm install
- run: cd Common && npm install && npm run test

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd CommonUI && npm install --force && npm run test

View File

@@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Home && npm install && npm run test

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd Model && npm install
- run: cd Model && npm install && npm run test

View File

@@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd ProbeAPI && npm install && npm run test

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
check-latest: true
node-version: 18.3.0
- run: cd Common && npm install
- run: cd CommonServer && npm install
- run: cd Probe && npm install && npm run test

View File

@@ -54,9 +54,6 @@ RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# Install trivy for container scanning
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s -- -b /usr/local/bin
# Install app dependencies
COPY ./Alert/package*.json /usr/src/app/
RUN npm install

View File

@@ -99,8 +99,14 @@ export default class URL extends DatabaseProperty {
}`;
if (!this.email) {
if (this.route && this.route.toString().startsWith('/')) {
if (urlString.endsWith('/')) {
urlString = urlString.substring(0, urlString.length - 1);
}
urlString += this.route.toString();
} else {
if (urlString.endsWith('/')) {
urlString = urlString.substring(0, urlString.length - 1);
}
urlString += '/' + this.route.toString();
}

View File

@@ -1,8 +1,7 @@
enum CodeType {
JavaScript = 'JavaScript',
CSS = 'CSS',
HTML = 'HTML',
JavaScript = 'javascript',
CSS = 'css',
HTML = 'html',
// TODO add more mime types.
}

View File

@@ -0,0 +1,17 @@
export default class EqualToOrNull {
private _value!: string;
public get value(): string {
return this._value;
}
public set value(v: string) {
this._value = v;
}
public constructor(value: string) {
this.value = value;
}
public toString(): string {
return this.value;
}
}

View File

@@ -5,7 +5,7 @@ import { ReflectionMetadataType } from '../Reflection';
const uniqueColumnBy: Symbol = Symbol('UniqueColumnBy');
export default (columnName: string): ReflectionMetadataType => {
export default (columnName: string | Array<string>): ReflectionMetadataType => {
return Reflect.metadata(uniqueColumnBy, columnName);
};

View File

@@ -10,6 +10,7 @@ enum ExceptionCode {
NotAuthenticatedxception = 401,
PaymentRequiredException = 402,
NotFoundException = 404,
TimeoutException = 408,
}
export default ExceptionCode;

View File

@@ -0,0 +1,8 @@
import Exception from './Exception';
import ExceptionCode from './ExceptionCode';
export default class TimeoutException extends Exception {
public constructor(message: string) {
super(ExceptionCode.TimeoutException, message);
}
}

View File

@@ -14,6 +14,7 @@ enum IconProp {
ChevronDown = 'ChevronDown',
ChevronRight = 'ChevronRight',
ChevronUp = 'ChevronUp',
Play = 'Play',
ChevronLeft = 'ChevronLeft',
UpDownArrow = 'UpDownArrow',
Public = 'Public',

View File

@@ -19,10 +19,12 @@ import InBetween from './Database/InBetween';
import Domain from './Domain';
import NotNull from './Database/NotNull';
import { BaseEntity } from 'typeorm';
import EqualToOrNull from './Database/EqualToOrNull';
export enum ObjectType {
ObjectID = 'ObjectID',
Name = 'Name',
EqualToOrNull = 'EqualToOrNull',
Email = 'Email',
Phone = 'Phone',
Color = 'Color',
@@ -82,6 +84,8 @@ export type JSONValue =
| Domain
| Array<Domain>
| Array<Search>
| EqualToOrNull
| Array<EqualToOrNull>
| GreaterThan
| Array<GreaterThan>
| GreaterThanOrEqual

View File

@@ -24,6 +24,7 @@ import NotNull from './Database/NotNull';
import { JSONArray, JSONObject, JSONValue, ObjectType } from './JSON';
import { TableColumnMetadata } from '../Types/Database/TableColumn';
import TableColumnType from '../Types/Database/TableColumnType';
import EqualToOrNull from './Database/EqualToOrNull';
export default class JSONFunctions {
public static toJSON(
@@ -354,6 +355,11 @@ export default class JSONFunctions {
_type: ObjectType.GreaterThan,
value: (val as GreaterThan).value,
};
} else if (val && val instanceof EqualToOrNull) {
return {
_type: ObjectType.EqualToOrNull,
value: (val as EqualToOrNull).value.toString(),
};
} else if (val && val instanceof LessThanOrEqual) {
return {
_type: ObjectType.LessThanOrEqual,
@@ -432,6 +438,16 @@ export default class JSONFunctions {
((val as JSONObject)['_type'] as string) === ObjectType.Domain
) {
return new Domain((val as JSONObject)['value'] as string);
} else if (
val &&
typeof val === Typeof.Object &&
(val as JSONObject)['_type'] &&
(val as JSONObject)['value'] &&
typeof (val as JSONObject)['value'] === Typeof.String &&
((val as JSONObject)['_type'] as string) ===
ObjectType.EqualToOrNull
) {
return new EqualToOrNull((val as JSONObject)['value'] as string);
} else if (
val &&
typeof val === Typeof.Object &&

View File

@@ -28,10 +28,6 @@ enum Permission {
Public = 'Public', // non-registered user. Everyone has this permission.
// Billing Permissions (Owner Permission)
CanDeleteProject = 'CanDeleteProject',
CanUpdateProject = 'CanDeleteProject',
// Billing Permissions (Owner Permission)
CanCreateProjectApiKey = 'CanCreateProjectApiKey',
CanDeleteProjectApiKey = 'CanDeleteProjectApiKey',
@@ -103,6 +99,11 @@ enum Permission {
CanEditWorkflow = 'CanEditWorkflow',
CanReadWorkflow = 'CanReadWorkflow',
// Workflow Permissions (Owner Permission)
CanDeleteProject = 'CanDeleteProject',
CanEditProject = 'CanEditProject',
CanReadProject = 'CanReadProject',
// Workflow Permissions (Owner Permission)
CanCreateWorkflowLog = 'CanCreateWorkflowLog',
CanDeleteWorkflowLog = 'CanDeleteWorkflowLog',
@@ -426,22 +427,7 @@ export class PermissionHelper {
isAssignableToTenant: false,
isAccessControlPermission: false,
},
{
permission: Permission.CanDeleteProject,
title: 'Can Delete Project',
description:
'A user assigned this permission can delete this project.',
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CanUpdateProject,
title: 'Can Update Project',
description:
'A user assigned this permission can update this project.',
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CanManageProjectBilling,
title: 'Can Manage Billing',
@@ -862,6 +848,31 @@ export class PermissionHelper {
isAccessControlPermission: false,
},
{
permission: Permission.CanDeleteProject,
title: 'Can Delete Project',
description:
'A user assigned this permission can delete Project.',
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CanEditProject,
title: 'Can Edit Project',
description:
'A user assigned this permission can edit Project.',
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CanReadProject,
title: 'Can Read Project',
description:
'A user assigned this permission can read this Project.',
isAssignableToTenant: true,
isAccessControlPermission: false,
},
{
permission: Permission.CanCreateWorkflowVariable,
title: 'Can Create Workflow Variables',

View File

@@ -1,23 +1,27 @@
import Route from '../API/Route';
import IconProp from '../Icon/IconProp';
import { JSONObject } from '../JSON';
export enum ComponentInputType {
Text = 'Text',
Password = 'Password',
Date = 'Date',
DateTime = 'Date Time',
Boolean = 'Boolean',
Boolean = 'True or False',
Number = 'Number',
Decimal = 'Decimal',
JavaScript = 'JavaScript',
AnyValue = 'AnyValue',
AnyValue = 'Any Type',
JSON = 'JSON',
StringDictionary = 'StringDictionary',
StringDictionary = 'Dictionary of String',
URL = 'URL',
Email = 'Email',
CronTab = 'CronTab',
Query = 'Query',
BaseModel = 'BaseModel',
BaseModelArray = 'BaseModelArray',
JSONArray = 'JSONArray',
Query = 'Database Query',
BaseModel = 'Database Record',
BaseModelArray = 'Database Records',
JSONArray = 'List of JSON',
LongText = 'Long Text',
}
export enum ComponentType {
@@ -25,6 +29,25 @@ export enum ComponentType {
Component = 'Component',
}
export enum NodeType {
Node = 'Node',
PlaceholderNode = 'PlaceholderNode',
}
export interface NodeDataProp {
error: string;
id: string;
nodeType: NodeType;
onClick?: (node: NodeDataProp) => void | undefined;
isPreview?: boolean | undefined; // is this used to show in the components modal?
metadata: ComponentMetadata;
metadataId: string;
internalId: string;
arguments: JSONObject;
returnValues: JSONObject;
componentType: ComponentType;
}
export interface Port {
title: string;
description: string;
@@ -38,6 +61,7 @@ export interface Argument {
type: ComponentInputType;
id: string;
isAdvanced?: boolean | undefined;
placeholder?: string | undefined;
}
export interface ReturnValue {
@@ -46,6 +70,7 @@ export interface ReturnValue {
description: string;
type: ComponentInputType;
required: boolean;
placeholder?: string | undefined;
}
export default interface ComponentMetadata {
@@ -60,6 +85,7 @@ export default interface ComponentMetadata {
inPorts: Array<Port>;
outPorts: Array<Port>;
tableName?: string | undefined;
documentationLink?: Route;
}
export interface ComponentCategory {

View File

@@ -0,0 +1,8 @@
enum ComponentID {
Webhook = 'webhook',
Log = 'log',
Schedule = 'schedule',
JavaScriptCode = 'javascript',
}
export default ComponentID;

View File

@@ -6,6 +6,11 @@ import SlackComponents from './Components/Slack';
import ConditionComponents from './Components/Condition';
import JsonComponents from './Components/JSON';
import JavaScriptComponents from './Components/JavaScript';
import EmailComponents from './Components/Email';
import WebhookComponents from './Components/Webhook';
import ManualComponents from './Components/Manual';
import WorkflowComponents from './Components/Workflow';
import IconProp from '../Icon/IconProp';
const components: Array<ComponentMetadata> = [
@@ -16,6 +21,10 @@ const components: Array<ComponentMetadata> = [
...ConditionComponents,
...JsonComponents,
...JavaScriptComponents,
...EmailComponents,
...WebhookComponents,
...WorkflowComponents,
...ManualComponents,
];
export default components;
@@ -56,6 +65,11 @@ export const Categories: Array<ComponentCategory> = [
description: 'Make your workflows run at regular intervals.',
icon: IconProp.Clock,
},
{
name: 'Email',
description: 'Send email to anyone in your workflows.',
icon: IconProp.Clock,
},
{
name: 'Utils',
description: 'Utils that make workflow design simpler.',

View File

@@ -16,32 +16,36 @@ const components: Array<ComponentMetadata> = [
{
id: 'url',
name: 'URL',
description: 'URL to send request to',
description: 'URL to send request to.',
type: ComponentInputType.URL,
required: true,
placeholder: 'https://api.yourcompany.com',
},
{
id: 'request-body',
name: 'Request Body',
description: 'Response Body',
description: 'Request Body in JSON',
type: ComponentInputType.JSON,
required: true,
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
{
id: 'query-string',
name: 'Query String',
description: 'Send query string params',
description: 'Send query string params.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"query1": "value1", "query2": "value2", ....}',
},
{
id: 'request-headers',
name: 'Request Headers',
description: 'Request headers to send',
description: 'Request headers to send.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"header1": "value1", "header2": "value2", ....}',
},
],
returnValues: [
@@ -107,32 +111,36 @@ const components: Array<ComponentMetadata> = [
{
id: 'url',
name: 'URL',
description: 'URL to send request to',
description: 'URL to send request to.',
type: ComponentInputType.URL,
required: true,
placeholder: 'https://api.yourcompany.com',
},
{
id: 'request-body',
name: 'Request Body',
description: 'Response Body',
description: 'Request Body in JSON',
type: ComponentInputType.JSON,
required: false,
required: true,
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
{
id: 'query-string',
name: 'Query String',
description: 'Send query string params',
description: 'Send query string params.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"query1": "value1", "query2": "value2", ....}',
},
{
id: 'request-headers',
name: 'Request Headers',
description: 'Request headers to send',
description: 'Request headers to send.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"header1": "value1", "header2": "value2", ....}',
},
],
returnValues: [
@@ -198,32 +206,36 @@ const components: Array<ComponentMetadata> = [
{
id: 'url',
name: 'URL',
description: 'URL to send request to',
description: 'URL to send request to.',
type: ComponentInputType.URL,
required: true,
placeholder: 'https://api.yourcompany.com',
},
{
id: 'request-body',
name: 'Request Body',
description: 'Response Body',
description: 'Request Body in JSON',
type: ComponentInputType.JSON,
required: false,
required: true,
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
{
id: 'query-string',
name: 'Query String',
description: 'Send query string params',
description: 'Send query string params.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"query1": "value1", "query2": "value2", ....}',
},
{
id: 'request-headers',
name: 'Request Headers',
description: 'Request headers to send',
description: 'Request headers to send.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"header1": "value1", "header2": "value2", ....}',
},
],
returnValues: [
@@ -289,32 +301,36 @@ const components: Array<ComponentMetadata> = [
{
id: 'url',
name: 'URL',
description: 'URL to send request to',
description: 'URL to send request to.',
type: ComponentInputType.URL,
required: true,
placeholder: 'https://api.yourcompany.com',
},
{
id: 'request-body',
name: 'Request Body',
description: 'Response Body',
description: 'Request Body in JSON',
type: ComponentInputType.JSON,
required: false,
required: true,
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
{
id: 'query-string',
name: 'Query String',
description: 'Send query string params',
description: 'Send query string params.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"query1": "value1", "query2": "value2", ....}',
},
{
id: 'request-headers',
name: 'Request Headers',
description: 'Request headers to send',
description: 'Request headers to send.',
type: ComponentInputType.StringDictionary,
required: false,
isAdvanced: true,
placeholder: '{"header1": "value1", "header2": "value2", ....}',
},
],
returnValues: [

View File

@@ -0,0 +1,94 @@
import IconProp from '../../Icon/IconProp';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
} from './../Component';
const components: Array<ComponentMetadata> = [
{
id: 'send-email',
title: 'Send Email',
category: 'Email',
description: 'Send email from your workflows',
iconProp: IconProp.Email,
componentType: ComponentType.Component,
arguments: [
{
type: ComponentInputType.Text,
name: 'Email',
description: 'Email to send to',
required: true,
id: 'email',
},
{
type: ComponentInputType.Text,
name: 'Subject',
description: 'Email to send to',
required: false,
id: 'subject',
},
{
type: ComponentInputType.LongText,
name: 'Email Body',
description: 'Email to send to',
required: false,
id: 'email-body',
},
{
type: ComponentInputType.Text,
name: 'SMTP HOST',
description: 'SMTP Host to send emails from',
required: true,
id: 'smtp_host',
},
{
type: ComponentInputType.Text,
name: 'SMTP Username',
description: 'SMTP Username to send emails from',
required: true,
id: 'smtp_username',
},
{
type: ComponentInputType.Password,
name: 'SMTP Password',
description: 'SMTP Password to send emails from',
required: true,
id: 'smtp_password',
},
{
type: ComponentInputType.Number,
name: 'SMTP Port',
description: 'SMTP Port to send emails from',
required: true,
id: 'smtp_port',
},
{
type: ComponentInputType.Boolean,
name: 'Use TLS/SSL',
description:
'Check this box if you would like to use TLS/SSL to send emails',
required: false,
id: 'secure',
},
],
returnValues: [],
inPorts: [
{
title: 'In',
description:
'Please connect components to this port for this component to work.',
id: 'in',
},
],
outPorts: [
{
title: 'Email Sent',
description:
'Connect to this port if you want other componets to execute after the email is sent.',
id: 'out',
},
],
},
];
export default components;

View File

@@ -1,4 +1,6 @@
import Route from '../../API/Route';
import IconProp from '../../Icon/IconProp';
import ComponentID from '../ComponentID';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
@@ -6,19 +8,28 @@ import ComponentMetadata, {
const components: Array<ComponentMetadata> = [
{
id: 'javascript',
id: ComponentID.JavaScriptCode,
title: 'Run Custom JavaScript',
category: 'Custom Code',
description: 'Run custom JavaScript in your workflow',
iconProp: IconProp.Code,
componentType: ComponentType.Component,
documentationLink: Route.fromString('/workflow/docs/JavaScript.md'),
arguments: [
{
type: ComponentInputType.AnyValue,
name: 'Value',
description: 'Value as Input',
type: ComponentInputType.JavaScript,
name: 'JavaScript Code',
description: 'JavaScript Code',
required: true,
id: 'input',
id: 'code',
},
{
type: ComponentInputType.JSON,
name: 'Arguments',
description:
'Pass in arguments to your JavaScript Code from this workflow',
required: false,
id: 'arguments',
},
],
returnValues: [
@@ -27,7 +38,7 @@ const components: Array<ComponentMetadata> = [
name: 'Value',
description: 'Value as Output',
required: false,
id: 'output',
id: 'returnValue',
},
],
inPorts: [

View File

@@ -1,4 +1,5 @@
import IconProp from '../../Icon/IconProp';
import ComponentID from '../ComponentID';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
@@ -6,7 +7,7 @@ import ComponentMetadata, {
const components: Array<ComponentMetadata> = [
{
id: 'log',
id: ComponentID.Log,
title: 'Log',
category: 'Utils',
description: 'Log to console what ever is passed to this component',

View File

@@ -0,0 +1,39 @@
import IconProp from '../../Icon/IconProp';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
} from './../Component';
const components: Array<ComponentMetadata> = [
{
id: 'manual',
title: 'Manual',
category: 'Utils',
description: 'Run this workflow manually',
iconProp: IconProp.Play,
componentType: ComponentType.Trigger,
arguments: [],
returnValues: [
{
type: ComponentInputType.JSON,
name: 'JSON',
description:
'Enter JSON value that you need to run this workflow',
required: false,
id: 'value',
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
],
inPorts: [],
outPorts: [
{
title: 'Execute',
description:
'Connect other components to this port if you want them to be executed.',
id: 'execute',
},
],
},
];
export default components;

View File

@@ -3,24 +3,28 @@ import ComponentMetadata, {
ComponentInputType,
ComponentType,
} from './../Component';
import ComponentID from '../ComponentID';
import Route from '../../API/Route';
const components: Array<ComponentMetadata> = [
{
id: 'webhook',
id: ComponentID.Webhook,
title: 'Webhook',
category: 'Webhook',
description:
'Hook any of your external apps and services with this workflow.',
iconProp: IconProp.AltGlobe,
componentType: ComponentType.Trigger,
documentationLink: Route.fromString('/workflow/docs/Webhook.md'),
arguments: [],
returnValues: [
{
id: 'response-headers',
name: 'Response Headers',
description: 'Response Headers for this request',
id: 'request-headers',
name: 'Request Headers',
description: 'Request Headers for this request',
type: ComponentInputType.StringDictionary,
required: false,
placeholder: '{"header1": "value1", "header2": "value2", ....}',
},
{
id: 'request-params',
@@ -28,6 +32,7 @@ const components: Array<ComponentMetadata> = [
description: 'Request Query Params for this request',
type: ComponentInputType.StringDictionary,
required: false,
placeholder: '{"query1": "value1", "query2": "value2", ....}',
},
{
id: 'request-body',
@@ -35,6 +40,7 @@ const components: Array<ComponentMetadata> = [
description: 'Request Body',
type: ComponentInputType.JSON,
required: false,
placeholder: '{"key1": "value1", "key2": "value2", ....}',
},
],
inPorts: [],

View File

@@ -0,0 +1,44 @@
import IconProp from '../../Icon/IconProp';
import ComponentMetadata, {
ComponentInputType,
ComponentType,
} from './../Component';
const components: Array<ComponentMetadata> = [
{
id: 'workflow-run',
title: 'Execute Workflow',
category: 'Utils',
description: 'Execute another workflow',
iconProp: IconProp.Workflow,
componentType: ComponentType.Component,
arguments: [
{
type: ComponentInputType.AnyValue,
name: 'Value',
description: 'Value to pass to another workflow',
required: false,
id: 'value',
},
],
returnValues: [],
inPorts: [
{
title: 'In',
description:
'Please connect components to this port for this component to work.',
id: 'in',
},
],
outPorts: [
{
title: 'Out',
description:
'Connect to this port if you want other componets to execute after the workflow is triggered',
id: 'out',
},
],
},
];
export default components;

View File

@@ -0,0 +1,9 @@
enum WorkflowStatus {
Scheduled = 'Scheduled',
Running = 'Running',
Success = 'Success',
Error = 'Error',
Timeout = 'Timeout',
}
export default WorkflowStatus;

View File

@@ -0,0 +1,44 @@
import { Queue as BullQueue, JobsOptions, Job } from 'bullmq';
import { JSONObject } from 'Common/Types/JSON';
import ObjectID from 'Common/Types/ObjectID';
import { RedisHostname, RedisPassword, RedisPort } from '../Config';
export enum QueueName {
Workflow = 'Workflow',
}
export type QueueJob = Job;
export default class Queue {
public static getQueue(queueName: QueueName): BullQueue {
return new BullQueue(queueName, {
connection: {
host: RedisHostname.toString(),
port: RedisPort.toNumber(),
password: RedisPassword,
},
});
}
public static async addJob(
queueName: QueueName,
jobId: ObjectID,
jobName: string,
data: JSONObject,
options?: {
scheduleAt?: string;
}
): Promise<void> {
const optionsObject: JobsOptions = {
jobId: jobId.toString(),
};
if (options && options.scheduleAt) {
optionsObject.repeat = {
pattern: options.scheduleAt,
};
}
await this.getQueue(queueName).add(jobName, data, { ...optionsObject });
}
}

View File

@@ -0,0 +1,42 @@
import { Worker } from 'bullmq';
import TimeoutException from 'Common/Types/Exception/TimeoutException';
import { RedisHostname, RedisPassword, RedisPort } from '../Config';
import { QueueJob, QueueName } from './Queue';
export default class QueueWorker {
public static getWorker(
queueName: QueueName,
onJobInQueue: (job: QueueJob) => Promise<void>,
options: { concurrency: number }
): Worker {
const worker: Worker = new Worker(queueName, onJobInQueue, {
connection: {
host: RedisHostname.toString(),
port: RedisPort.toNumber(),
password: RedisPassword,
},
concurrency: options.concurrency,
});
process.on('SIGINT', async () => {
await worker.close();
});
return worker;
}
public static async runJobWithTimeout(
timeout: number,
jobCallback: Function
): Promise<void> {
const timeoutPromise: Function = (ms: number): Promise<void> => {
return new Promise((_resolve: Function, reject: Function) => {
setTimeout(() => {
return reject(new TimeoutException('Job Timeout'));
}, ms);
});
};
return await Promise.race([timeoutPromise(timeout), jobCallback()]);
}
}

View File

@@ -168,6 +168,7 @@ export default class UserMiddleware {
]!
)
);
const projectPermissionsHash: string = await HashedString.hashValue(
projectValue,
null

View File

@@ -54,11 +54,6 @@ export default class AccessTokenService {
_type: 'UserGlobalAccessPermission',
};
// if user is a part of any project then, he is the project member.
if (projectIds.length > 0) {
permissionToStore.globalPermissions.push(Permission.ProjectMember);
}
await GlobalCache.setJSON('user', userId.toString(), permissionToStore);
return permissionToStore;
@@ -161,12 +156,6 @@ export default class AccessTokenService {
_type: 'UserPermission',
});
userPermissions.push({
permission: Permission.ProjectMember,
labelIds: [],
_type: 'UserPermission',
});
const permission: UserTenantAccessPermission = {
projectId,
permissions: userPermissions,

View File

@@ -576,15 +576,33 @@ class DatabaseService<TBaseModel extends BaseModel> {
): Promise<CreateBy<TBaseModel>> {
let existingItemsWithSameNameCount: number = 0;
const uniqueColumnsBy: Dictionary<string> = getUniqueColumnsBy(
createBy.data
);
const uniqueColumnsBy: Dictionary<string | Array<string>> =
getUniqueColumnsBy(createBy.data);
for (const key in uniqueColumnsBy) {
if (!uniqueColumnsBy[key]) {
continue;
}
if (typeof uniqueColumnsBy[key] === Typeof.String) {
uniqueColumnsBy[key] = [uniqueColumnsBy[key] as string];
}
const query: Query<TBaseModel> = {};
for (const uniqueByCoumnName of uniqueColumnsBy[
key
] as Array<string>) {
const columnValue: JSONValue = (createBy.data as any)[
uniqueByCoumnName as string
];
if (columnValue === null || columnValue === undefined) {
(query as any)[uniqueByCoumnName] = QueryHelper.isNull();
} else {
(query as any)[uniqueByCoumnName] = columnValue;
}
}
existingItemsWithSameNameCount = (
await this.countBy({
query: {
@@ -593,9 +611,7 @@ class DatabaseService<TBaseModel extends BaseModel> {
? ((createBy.data as any)[key]! as string)
: ''
),
[uniqueColumnsBy[key] as any]: (createBy.data as any)[
uniqueColumnsBy[key] as any
],
...query,
},
props: {
isRoot: true,

View File

@@ -0,0 +1,121 @@
import UserService from './UserService';
import ProbeService from './ProbeService';
import ProjectService from './ProjectService';
import EmailVerificationTokenService from './EmailVerificationTokenService';
// Team
import TeamService from './TeamService';
import TeamMemberService from './TeamMemberService';
import TeamPermissionService from './TeamPermissionService';
// API Keys
import ApiKeyService from './ApiKeyService';
import ApiKeyPermissionService from './ApiKeyPermissionService';
//Labels.
import LabelService from './LabelService';
// Status Page
import StatusPageService from './StatusPageService';
import StatusPageGroupService from './StatusPageGroupService';
import StatusPageDomainService from './StatusPageDomainService';
import StatusPageResourceService from './StatusPageResourceService';
import StatusPageAnnouncementService from './StatusPageAnnouncementService';
import StatusPageSubscriberService from './StatusPageSubscriberService';
import StatusPageFooterLinkService from './StatusPageFooterLinkService';
import StatusPageHeaderLinkService from './StatusPageHeaderLinkService';
import StatusPagePrivateUserService from './StatusPagePrivateUserService';
// On Call Duty
import OnCallDutyService from './OnCallDutyService';
// Monitors
import MonitorService from './MonitorService';
import MonitorStatusService from './MonitorStatusService';
import MonitorStatusTimelineService from './MonitorStatusTimelineService';
// Incidents
import IncidentService from './IncidentService';
import IncidentStateService from './IncidentStateService';
import IncidentStateTimelineService from './IncidentStateTimelineService';
import IncidentPublicNoteService from './IncidentPublicNoteService';
import IncidentInternalNoteService from './IncidentInternalNoteService';
import IncidentSeverityService from './IncidentSeverityService';
// ScheduledMaintenances
import ScheduledMaintenanceService from './ScheduledMaintenanceService';
import ScheduledMaintenanceStateService from './ScheduledMaintenanceStateService';
import ScheduledMaintenanceStateTimelineService from './ScheduledMaintenanceStateTimelineService';
import ScheduledMaintenancePublicNoteService from './ScheduledMaintenancePublicNoteService';
import ScheduledMaintenanceInternalNoteService from './ScheduledMaintenanceInternalNoteService';
import BillingPaymentMethodsService from './BillingPaymentMethodService';
// Project SMTP Config.
import ProjectSmtpConfigService from './ProjectSmtpConfigService';
import DomainService from './DomainService';
import FileService from './FileService';
import BillingInvoiceService from './BillingInvoiceService';
// Greenlock
import GreenlockChallengeService from './GreenlockChallengeService';
import GreenlockCertificateService from './GreenlockCertificateService';
// Workflows.
import WorkflowService from './WorkflowService';
import WorkflowVariablesService from './WorkflowVariableService';
import WorkflowLogService from './WorkflowLogService';
export default [
UserService,
ProbeService,
ProjectService,
EmailVerificationTokenService,
TeamService,
TeamMemberService,
TeamPermissionService,
ApiKeyService,
LabelService,
ApiKeyPermissionService,
ProjectSmtpConfigService,
StatusPageService,
OnCallDutyService,
MonitorService,
MonitorStatusService,
IncidentStateService,
IncidentService,
IncidentStateTimelineService,
MonitorStatusTimelineService,
IncidentPublicNoteService,
IncidentInternalNoteService,
FileService,
DomainService,
StatusPageGroupService,
StatusPageDomainService,
StatusPageResourceService,
IncidentSeverityService,
StatusPageAnnouncementService,
StatusPageSubscriberService,
StatusPageFooterLinkService,
StatusPageHeaderLinkService,
StatusPagePrivateUserService,
ScheduledMaintenanceStateService,
ScheduledMaintenanceService,
ScheduledMaintenanceStateTimelineService,
ScheduledMaintenancePublicNoteService,
ScheduledMaintenanceInternalNoteService,
BillingPaymentMethodsService,
BillingInvoiceService,
GreenlockChallengeService,
GreenlockCertificateService,
WorkflowService,
WorkflowVariablesService,
WorkflowLogService,
];

View File

@@ -1,10 +1,62 @@
import PostgresDatabase from '../Infrastructure/PostgresDatabase';
import Model from 'Model/Models/Workflow';
import DatabaseService from './DatabaseService';
import DatabaseService, { OnUpdate } from './DatabaseService';
import ObjectID from 'Common/Types/ObjectID';
import { JSONObject } from 'Common/Types/JSON';
import {
ComponentType,
NodeDataProp,
NodeType,
} from 'Common/Types/Workflow/Component';
export class Service extends DatabaseService<Model> {
public constructor(postgresDatabase?: PostgresDatabase) {
super(Model, postgresDatabase);
}
protected override async onUpdateSuccess(
onUpdate: OnUpdate<Model>,
_updatedItemIds: ObjectID[]
): Promise<OnUpdate<Model>> {
/// save trigger and trigger args.
let trigger: NodeDataProp | null = null;
if (
onUpdate.updateBy.data &&
(onUpdate.updateBy.data as any).graph &&
(((onUpdate.updateBy.data as any).graph as any)[
'nodes'
] as Array<JSONObject>)
) {
// check if it has a trigger node.
for (const node of ((onUpdate.updateBy.data as any).graph as any)[
'nodes'
] as Array<JSONObject>) {
const nodeData: NodeDataProp = node['data'] as NodeDataProp;
if (
nodeData.componentType === ComponentType.Trigger &&
nodeData.nodeType === NodeType.Node
) {
// found the trigger;
trigger = nodeData;
}
}
}
await this.updateOneById({
id: new ObjectID(onUpdate.updateBy.query._id! as any),
data: {
triggerId: trigger?.metadataId! || null,
triggerArguments: trigger?.arguments || {},
} as any,
props: {
isRoot: true,
ignoreHooks: true,
},
});
return onUpdate;
}
}
export default new Service();

View File

@@ -36,6 +36,18 @@ export default class QueryHelper {
});
}
public static equalToOrNull(value: string | ObjectID): FindOperator<any> {
const rid: string = Text.generateRandomText(10);
return Raw(
(alias: string) => {
return `${alias} = :${rid} or ${alias} IS NULL`;
},
{
[rid]: value.toString(),
}
);
}
public static search(name: string): FindOperator<any> {
name = name.toLowerCase().trim();
const rid: string = Text.generateRandomText(10);

View File

@@ -0,0 +1,81 @@
// this class is the base class that all the component can implement
//
import OneUptimeDate from 'Common/Types/Date';
import BadDataException from 'Common/Types/Exception/BadDataException';
import { JSONArray, JSONObject, JSONValue } from 'Common/Types/JSON';
import ObjectID from 'Common/Types/ObjectID';
import ComponentMetadata, { Port } from 'Common/Types/Workflow/Component';
import { ExpressRouter } from '../../Utils/Express';
export interface RunProps {
arguments: JSONObject;
workflowId: ObjectID;
workflowLogId: ObjectID;
timeout: number;
}
export interface RunReturnType {
returnValues: JSONObject;
executePort?: Port | undefined;
logs: Array<string>;
}
export interface ExecuteWorkflowType {
workflowId: ObjectID;
returnValues: JSONObject;
}
export interface InitProps {
router: ExpressRouter;
executeWorkflow: (executeWorkflow: ExecuteWorkflowType) => Promise<void>;
scheduleWorkflow: (
executeWorkflow: ExecuteWorkflowType,
scheduleAt: string
) => Promise<void>;
}
export default class ComponentCode {
private metadata: ComponentMetadata | null = null;
protected logs: Array<string> = [];
public constructor() {}
public setMetadata(metadata: ComponentMetadata): void {
this.metadata = metadata;
}
public getMetadata(): ComponentMetadata {
if (!this.metadata) {
throw new BadDataException('ComponentMetadata not found');
}
return this.metadata;
}
public log(data: string | JSONObject | JSONArray | JSONValue): void {
if (typeof data === 'string') {
this.logs.push(
OneUptimeDate.getCurrentDateAsFormattedString() + ': ' + data
);
} else {
this.logs.push(
OneUptimeDate.getCurrentDateAsFormattedString() +
': ' +
JSON.stringify(data)
);
}
}
public async init(_props: InitProps): Promise<void> {
return await Promise.resolve();
}
public async run(_args: JSONObject): Promise<RunReturnType> {
return await Promise.resolve({
returnValues: {},
port: undefined,
logs: [],
});
}
}

View File

@@ -0,0 +1,16 @@
import ComponentID from 'Common/Types/Workflow/ComponentID';
import WebhookTrigger from './Webhook';
import Log from './Log';
import Schedule from './Schedule';
import Dictionary from 'Common/Types/Dictionary';
import ComponentCode from '../ComponentCode';
import JavaScirptCode from './JavaScript';
const Components: Dictionary<typeof ComponentCode> = {
[ComponentID.Webhook]: WebhookTrigger,
[ComponentID.Log]: Log,
[ComponentID.Schedule]: Schedule,
[ComponentID.JavaScriptCode]: JavaScirptCode,
};
export default Components;

View File

@@ -0,0 +1,101 @@
import BadDataException from 'Common/Types/Exception/BadDataException';
import { JSONObject, JSONValue } from 'Common/Types/JSON';
import ComponentMetadata, { Port } from 'Common/Types/Workflow/Component';
import ComponentID from 'Common/Types/Workflow/ComponentID';
import JavaScriptComponents from 'Common/Types/Workflow/Components/JavaScript';
import ComponentCode, { RunReturnType } from '../ComponentCode';
import VM, { VMScript } from 'vm2';
import axios from 'axios';
import http from 'http';
import https from 'https';
export default class JavaScirptCode extends ComponentCode {
public constructor() {
super();
const JavaScirptComponent: ComponentMetadata | undefined =
JavaScriptComponents.find((i: ComponentMetadata) => {
return i.id === ComponentID.JavaScriptCode;
});
if (!JavaScirptComponent) {
throw new BadDataException(
'Custom JavaScirpt Component not found.'
);
}
this.setMetadata(JavaScirptComponent);
}
public override async run(args: JSONObject): Promise<RunReturnType> {
const successPort: Port | undefined = this.getMetadata().outPorts.find(
(p: Port) => {
return p.id === 'success';
}
);
if (!successPort) {
throw new BadDataException('Success port not found');
}
const errorPort: Port | undefined = this.getMetadata().outPorts.find(
(p: Port) => {
return p.id === 'error';
}
);
if (!errorPort) {
throw new BadDataException('Error port not found');
}
try {
// Set timeout
// Inject args
// Inject dependencies
const vm: VM.NodeVM = new VM.NodeVM({
timeout: 5000,
allowAsync: true,
sandbox: {
args: args['arguments'],
axios: axios,
http: http,
https: https,
console: {
log: (logValue: JSONValue) => {
this.log(logValue);
},
},
},
});
const script: VMScript = new VMScript(
`module.exports = async function(args) { ${
(args['code'] as string) || ''
} }`
).compile();
const functionToRun: any = vm.run(script);
const returnVal: any = await functionToRun(
JSON.parse((args['arguments'] as string) || '{}')
);
return {
returnValues: {
returnValue: returnVal,
},
executePort: successPort,
logs: this.logs,
};
} catch (err: any) {
this.log('Error running script');
this.log(err.message ? err.message : JSON.stringify(err, null, 2));
return {
returnValues: {},
executePort: errorPort,
logs: this.logs,
};
}
}
}

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