diff --git a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html
deleted file mode 100644
index e98d84bea..000000000
--- a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html
+++ /dev/null
@@ -1,109 +0,0 @@
-
diff --git a/app/docker/components/datatables/tasks-datatable/tasksDatatable.html b/app/docker/components/datatables/tasks-datatable/tasksDatatable.html
index 7af8b6fd1..ea2a4e679 100644
--- a/app/docker/components/datatables/tasks-datatable/tasksDatatable.html
+++ b/app/docker/components/datatables/tasks-datatable/tasksDatatable.html
@@ -89,13 +89,7 @@
>
-
+
= []) {
return command.join(' ');
}
+
+export function taskStatusBadge(text?: TaskState) {
+ const status = _.toLower(text);
+ if (
+ [
+ 'new',
+ 'allocated',
+ 'assigned',
+ 'accepted',
+ 'preparing',
+ 'ready',
+ 'starting',
+ 'remove',
+ ].includes(status)
+ ) {
+ return 'info';
+ }
+
+ if (['pending'].includes(status)) {
+ return 'warning';
+ }
+
+ if (['shutdown', 'failed', 'rejected', 'orphaned'].includes(status)) {
+ return 'danger';
+ }
+
+ if (['complete'].includes(status)) {
+ return 'primary';
+ }
+
+ if (['running'].includes(status)) {
+ return 'success';
+ }
+ return 'default';
+}
diff --git a/app/docker/models/task.js b/app/docker/models/task.js
deleted file mode 100644
index 6e16b3a56..000000000
--- a/app/docker/models/task.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export function TaskViewModel(data) {
- this.Id = data.ID;
- this.Created = data.CreatedAt;
- this.Updated = data.UpdatedAt;
- this.Slot = data.Slot;
- this.Spec = data.Spec;
- this.Status = data.Status;
- this.DesiredState = data.DesiredState;
- this.ServiceId = data.ServiceID;
- this.NodeId = data.NodeID;
- if (data.Status && data.Status.ContainerStatus && data.Status.ContainerStatus.ContainerID) {
- this.ContainerId = data.Status.ContainerStatus.ContainerID;
- }
-}
diff --git a/app/docker/models/task.ts b/app/docker/models/task.ts
new file mode 100644
index 000000000..c67a41171
--- /dev/null
+++ b/app/docker/models/task.ts
@@ -0,0 +1,36 @@
+import { Task, TaskSpec, TaskState } from 'docker-types/generated/1.41';
+
+export class TaskViewModel {
+ Id: string;
+
+ Created: string;
+
+ Updated: string;
+
+ Slot: number;
+
+ Spec?: TaskSpec;
+
+ Status: Task['Status'];
+
+ DesiredState: TaskState;
+
+ ServiceId: string;
+
+ NodeId: string;
+
+ ContainerId: string = '';
+
+ constructor(data: Task) {
+ this.Id = data.ID || '';
+ this.Created = data.CreatedAt || '';
+ this.Updated = data.UpdatedAt || '';
+ this.Slot = data.Slot || 0;
+ this.Spec = data.Spec;
+ this.Status = data.Status;
+ this.DesiredState = data.DesiredState || 'pending';
+ this.ServiceId = data.ServiceID || '';
+ this.NodeId = data.NodeID || '';
+ this.ContainerId = data.Status?.ContainerStatus?.ContainerID || '';
+ }
+}
diff --git a/app/docker/react/components/index.ts b/app/docker/react/components/index.ts
index df5338c60..781281e7f 100644
--- a/app/docker/react/components/index.ts
+++ b/app/docker/react/components/index.ts
@@ -21,8 +21,10 @@ import { ConfigsDatatable } from '@/react/docker/configs/ListView/ConfigsDatatab
import { AgentHostBrowser } from '@/react/docker/host/BrowseView/AgentHostBrowser';
import { AgentVolumeBrowser } from '@/react/docker/volumes/BrowseView/AgentVolumeBrowser';
+import { servicesModule } from './services';
+
const ngModule = angular
- .module('portainer.docker.react.components', [])
+ .module('portainer.docker.react.components', [servicesModule])
.component('dockerfileDetails', r2a(DockerfileDetails, ['image']))
.component('dockerHealthStatus', r2a(HealthStatus, ['health']))
.component(
@@ -32,7 +34,6 @@ const ngModule = angular
'nodeName',
'state',
'status',
- 'taskId',
])
)
.component('templateListDropdown', TemplateListDropdownAngular)
diff --git a/app/docker/react/components/services.ts b/app/docker/react/components/services.ts
new file mode 100644
index 000000000..ec4634823
--- /dev/null
+++ b/app/docker/react/components/services.ts
@@ -0,0 +1,21 @@
+import angular from 'angular';
+
+import { r2a } from '@/react-tools/react2angular';
+import { withUIRouter } from '@/react-tools/withUIRouter';
+import { TasksDatatable } from '@/react/docker/services/ListView/ServicesDatatable/TasksDatatable';
+import { withCurrentUser } from '@/react-tools/withCurrentUser';
+import { TaskTableQuickActions } from '@/react/docker/services/common/TaskTableQuickActions';
+
+export const servicesModule = angular
+ .module('portainer.docker.react.components.services', [])
+ .component(
+ 'dockerServiceTasksDatatable',
+ r2a(withUIRouter(withCurrentUser(TasksDatatable)), ['dataset', 'search'])
+ )
+ .component(
+ 'dockerTaskTableQuickActions',
+ r2a(withUIRouter(withCurrentUser(TaskTableQuickActions)), [
+ 'state',
+ 'taskId',
+ ])
+ ).name;
diff --git a/app/react/components/datatables/NestedDatatable.tsx b/app/react/components/datatables/NestedDatatable.tsx
index 1b0eaaa3b..6569435d5 100644
--- a/app/react/components/datatables/NestedDatatable.tsx
+++ b/app/react/components/datatables/NestedDatatable.tsx
@@ -23,6 +23,11 @@ interface Props {
initialTableState?: Partial;
isLoading?: boolean;
initialSortBy?: BasicTableSettings['sortBy'];
+
+ /**
+ * keyword to filter by
+ */
+ search?: string;
}
export function NestedDatatable({
@@ -33,6 +38,7 @@ export function NestedDatatable({
initialTableState = {},
isLoading,
initialSortBy,
+ search,
}: Props) {
const tableInstance = useReactTable({
columns,
@@ -45,6 +51,9 @@ export function NestedDatatable({
enableColumnFilter: false,
enableHiding: false,
},
+ state: {
+ globalFilter: search,
+ },
getRowId,
autoResetExpanded: false,
getCoreRowModel: getCoreRowModel(),
@@ -55,7 +64,7 @@ export function NestedDatatable({
return (
-
+
tableInstance={tableInstance}
isLoading={isLoading}
diff --git a/app/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions.tsx b/app/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions.tsx
index 81ac473d8..891f40a7a 100644
--- a/app/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions.tsx
+++ b/app/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions.tsx
@@ -9,7 +9,7 @@ import { Link } from '@@/Link';
import styles from './ContainerQuickActions.module.css';
-interface QuickActionsState {
+export interface QuickActionsState {
showQuickActionAttach: boolean;
showQuickActionExec: boolean;
showQuickActionInspect: boolean;
@@ -17,31 +17,25 @@ interface QuickActionsState {
showQuickActionStats: boolean;
}
-interface Props {
- taskId?: string;
- containerId?: string;
- nodeName: string;
- state: QuickActionsState;
- status: ContainerStatus;
-}
-
export function ContainerQuickActions({
- taskId,
+ status,
containerId,
nodeName,
state,
- status,
-}: Props) {
- if (taskId) {
- return ;
- }
-
- const isActive = [
- ContainerStatus.Starting,
- ContainerStatus.Running,
- ContainerStatus.Healthy,
- ContainerStatus.Unhealthy,
- ].includes(status);
+}: {
+ containerId: string;
+ nodeName: string;
+ status: ContainerStatus;
+ state: QuickActionsState;
+}) {
+ const isActive =
+ !!status &&
+ [
+ ContainerStatus.Starting,
+ ContainerStatus.Running,
+ ContainerStatus.Healthy,
+ ContainerStatus.Unhealthy,
+ ].includes(status);
return (
@@ -107,34 +101,3 @@ export function ContainerQuickActions({
);
}
-
-interface TaskProps {
- taskId: string;
- state: QuickActionsState;
-}
-
-function TaskQuickActions({ taskId, state }: TaskProps) {
- return (
-
- {state.showQuickActionLogs && (
-
-
-
-
-
- )}
-
- {state.showQuickActionInspect && (
-
-
-
-
-
- )}
-
- );
-}
diff --git a/app/react/docker/proxy/queries/nodes/build-url.ts b/app/react/docker/proxy/queries/nodes/build-url.ts
new file mode 100644
index 000000000..2c422d18e
--- /dev/null
+++ b/app/react/docker/proxy/queries/nodes/build-url.ts
@@ -0,0 +1,15 @@
+import { EnvironmentId } from '@/react/portainer/environments/types';
+
+import { buildUrl as buildProxyUrl } from '../build-url';
+
+export function buildUrl(
+ environmentId: EnvironmentId,
+ action?: string,
+ subAction = ''
+) {
+ return buildProxyUrl(
+ environmentId,
+ 'nodes',
+ subAction ? `${action}/${subAction}` : action
+ );
+}
diff --git a/app/react/docker/proxy/queries/nodes/query-keys.ts b/app/react/docker/proxy/queries/nodes/query-keys.ts
new file mode 100644
index 000000000..3f599e1d8
--- /dev/null
+++ b/app/react/docker/proxy/queries/nodes/query-keys.ts
@@ -0,0 +1,8 @@
+import { EnvironmentId } from '@/react/portainer/environments/types';
+
+import { queryKeys as proxyQueryKeys } from '../query-keys';
+
+export const queryKeys = {
+ base: (environmentId: EnvironmentId) =>
+ [...proxyQueryKeys.base(environmentId), 'nodes'] as const,
+};
diff --git a/app/react/docker/proxy/queries/nodes/useNodes.ts b/app/react/docker/proxy/queries/nodes/useNodes.ts
new file mode 100644
index 000000000..cc52ffae1
--- /dev/null
+++ b/app/react/docker/proxy/queries/nodes/useNodes.ts
@@ -0,0 +1,21 @@
+import { Node } from 'docker-types/generated/1.41';
+import { useQuery } from 'react-query';
+
+import axios, { parseAxiosError } from '@/portainer/services/axios';
+import { EnvironmentId } from '@/react/portainer/environments/types';
+
+import { buildUrl } from './build-url';
+import { queryKeys } from './query-keys';
+
+export function useNodes(environmentId: EnvironmentId) {
+ return useQuery(queryKeys.base(environmentId), () => getNodes(environmentId));
+}
+
+async function getNodes(environmentId: EnvironmentId) {
+ try {
+ const { data } = await axios.get>(buildUrl(environmentId));
+ return data;
+ } catch (error) {
+ throw parseAxiosError(error, 'Unable to retrieve nodes');
+ }
+}
diff --git a/app/react/docker/proxy/queries/query-keys.ts b/app/react/docker/proxy/queries/query-keys.ts
new file mode 100644
index 000000000..2439c835e
--- /dev/null
+++ b/app/react/docker/proxy/queries/query-keys.ts
@@ -0,0 +1,6 @@
+import { EnvironmentId } from '@/react/portainer/environments/types';
+
+export const queryKeys = {
+ base: (environmentId: EnvironmentId) =>
+ [environmentId, 'docker', 'proxy'] as const,
+};
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/TasksDatatable.tsx b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/TasksDatatable.tsx
new file mode 100644
index 000000000..8f1e906fd
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/TasksDatatable.tsx
@@ -0,0 +1,21 @@
+import { NestedDatatable } from '@@/datatables/NestedDatatable';
+
+import { columns } from './columns';
+import { DecoratedTask } from './types';
+
+export function TasksDatatable({
+ dataset,
+ search,
+}: {
+ dataset: DecoratedTask[];
+ search?: string;
+}) {
+ return (
+
+ );
+}
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/actions.tsx b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/actions.tsx
new file mode 100644
index 000000000..fe672dc74
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/actions.tsx
@@ -0,0 +1,45 @@
+import { CellContext } from '@tanstack/react-table';
+
+import { ContainerQuickActions } from '@/react/docker/containers/components/ContainerQuickActions';
+import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
+import { isAgentEnvironment } from '@/react/portainer/environments/utils';
+import { QuickActionsState } from '@/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions';
+import { TaskTableQuickActions } from '@/react/docker/services/common/TaskTableQuickActions';
+
+import { DecoratedTask } from '../types';
+
+import { columnHelper } from './helper';
+
+export const actions = columnHelper.display({
+ header: 'Actions',
+ cell: Cell,
+});
+
+function Cell({
+ row: { original: item },
+}: CellContext) {
+ const environmentQuery = useCurrentEnvironment();
+
+ if (!environmentQuery.data) {
+ return null;
+ }
+ const state: QuickActionsState = {
+ showQuickActionAttach: true,
+ showQuickActionExec: true,
+ showQuickActionInspect: true,
+ showQuickActionLogs: true,
+ showQuickActionStats: true,
+ };
+ const isAgent = isAgentEnvironment(environmentQuery.data.Type);
+
+ return isAgent && item.Container ? (
+
+ ) : (
+
+ );
+}
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/helper.ts b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/helper.ts
new file mode 100644
index 000000000..34343b077
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/helper.ts
@@ -0,0 +1,5 @@
+import { createColumnHelper } from '@tanstack/react-table';
+
+import { DecoratedTask } from '../types';
+
+export const columnHelper = createColumnHelper();
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/index.ts b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/index.ts
new file mode 100644
index 000000000..aaca2fa3f
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/index.ts
@@ -0,0 +1,19 @@
+import { isoDate } from '@/portainer/filters/filters';
+
+import { actions } from './actions';
+import { columnHelper } from './helper';
+import { node } from './node';
+import { status } from './status';
+import { task } from './task';
+
+export const columns = [
+ status,
+ task,
+ actions,
+ columnHelper.accessor((item) => item.Slot || '-', { header: 'Slot' }),
+ node,
+ columnHelper.accessor('Updated', {
+ header: 'Last Update',
+ cell: ({ getValue }) => isoDate(getValue()),
+ }),
+];
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/node.tsx b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/node.tsx
new file mode 100644
index 000000000..56ae02877
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/node.tsx
@@ -0,0 +1,32 @@
+import { Node } from 'docker-types/generated/1.41';
+import { CellContext } from '@tanstack/react-table';
+
+import { useNodes } from '@/react/docker/proxy/queries/nodes/useNodes';
+import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
+
+import { DecoratedTask } from '../types';
+
+import { columnHelper } from './helper';
+
+export const node = columnHelper.accessor('NodeId', {
+ header: 'Node',
+ cell: Cell,
+});
+
+function Cell({ getValue }: CellContext) {
+ const environmentId = useEnvironmentId();
+
+ const nodesQuery = useNodes(environmentId);
+
+ const nodes = nodesQuery.data || [];
+ return getNodeName(getValue(), nodes);
+}
+
+function getNodeName(nodeId: string, nodes: Array) {
+ const node = nodes.find((node) => node.ID === nodeId);
+ if (node?.Description?.Hostname) {
+ return node.Description.Hostname;
+ }
+
+ return '';
+}
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/status.tsx b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/status.tsx
new file mode 100644
index 000000000..7f1bc39ea
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/status.tsx
@@ -0,0 +1,27 @@
+import clsx from 'clsx';
+
+import { taskStatusBadge } from '@/docker/filters/utils';
+
+import { multiple } from '@@/datatables/filter-types';
+import { filterHOC } from '@@/datatables/Filter';
+
+import { columnHelper } from './helper';
+
+export const status = columnHelper.accessor((item) => item.Status?.State, {
+ header: 'Status',
+ enableColumnFilter: true,
+ filterFn: multiple,
+ meta: {
+ filter: filterHOC('Filter by state'),
+ width: 100,
+ },
+ cell({ getValue }) {
+ const value = getValue();
+
+ return (
+
+ {value}
+
+ );
+ },
+});
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/task.tsx b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/task.tsx
new file mode 100644
index 000000000..1a94f5947
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/columns/task.tsx
@@ -0,0 +1,47 @@
+import { CellContext } from '@tanstack/react-table';
+
+import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
+import { isAgentEnvironment } from '@/react/portainer/environments/utils';
+
+import { Link } from '@@/Link';
+
+import { DecoratedTask } from '../types';
+
+import { columnHelper } from './helper';
+
+export const task = columnHelper.accessor('Id', {
+ header: 'Task',
+ cell: Cell,
+});
+
+function Cell({
+ getValue,
+ row: { original: item },
+}: CellContext) {
+ const environmentQuery = useCurrentEnvironment();
+
+ if (!environmentQuery.data) {
+ return null;
+ }
+
+ const value = getValue();
+ const isAgent = isAgentEnvironment(environmentQuery.data.Type);
+
+ return isAgent && item.Container ? (
+
+ {value}
+
+ ) : (
+
+ {value}
+
+ );
+}
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/index.ts b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/index.ts
new file mode 100644
index 000000000..f95acf3ac
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/index.ts
@@ -0,0 +1 @@
+export { TasksDatatable } from './TasksDatatable';
diff --git a/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/types.ts b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/types.ts
new file mode 100644
index 000000000..fdff024a9
--- /dev/null
+++ b/app/react/docker/services/ListView/ServicesDatatable/TasksDatatable/types.ts
@@ -0,0 +1,6 @@
+import { TaskViewModel } from '@/docker/models/task';
+import { DockerContainer } from '@/react/docker/containers/types';
+
+export type DecoratedTask = TaskViewModel & {
+ Container?: DockerContainer;
+};
diff --git a/app/react/docker/services/common/TaskTableQuickActions.tsx b/app/react/docker/services/common/TaskTableQuickActions.tsx
new file mode 100644
index 000000000..367c4bc27
--- /dev/null
+++ b/app/react/docker/services/common/TaskTableQuickActions.tsx
@@ -0,0 +1,46 @@
+import { FileText, Info } from 'lucide-react';
+
+import { Authorized } from '@/react/hooks/useUser';
+
+import { Icon } from '@@/Icon';
+import { Link } from '@@/Link';
+
+interface State {
+ showQuickActionInspect: boolean;
+ showQuickActionLogs: boolean;
+}
+
+export function TaskTableQuickActions({
+ taskId,
+ state = {
+ showQuickActionInspect: true,
+ showQuickActionLogs: true,
+ },
+}: {
+ taskId: string;
+ state?: State;
+}) {
+ return (
+
+ {state.showQuickActionLogs && (
+
+
+
+
+
+ )}
+
+ {state.showQuickActionInspect && (
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/package.json b/package.json
index 1c7c8d179..6d14dec98 100644
--- a/package.json
+++ b/package.json
@@ -85,6 +85,7 @@
"codemirror": "^6.0.1",
"core-js": "^3.19.3",
"date-fns": "^2.29.3",
+ "docker-types": "^1.42.2",
"fast-json-patch": "^3.1.1",
"file-saver": "^2.0.5",
"filesize": "~3.3.0",
diff --git a/yarn.lock b/yarn.lock
index 7d5d20d7d..22789dd84 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -15,7 +15,7 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
-"@apidevtools/json-schema-ref-parser@^9.0.6":
+"@apidevtools/json-schema-ref-parser@9.0.9", "@apidevtools/json-schema-ref-parser@^9.0.6":
version "9.0.9"
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b"
integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==
@@ -6807,6 +6807,13 @@ buffer@^6.0.3:
base64-js "^1.3.1"
ieee754 "^1.2.1"
+busboy@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
+ integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
+ dependencies:
+ streamsearch "^1.1.0"
+
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -6879,7 +6886,7 @@ camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-camelcase@^6.2.0:
+camelcase@^6.2.0, camelcase@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
@@ -8099,6 +8106,14 @@ dns-packet@^5.2.2:
dependencies:
"@leichtgewicht/ip-codec" "^2.0.1"
+docker-types@^1.42.2:
+ version "1.42.2"
+ resolved "https://registry.yarnpkg.com/docker-types/-/docker-types-1.42.2.tgz#40a3626abf99030abe306966d51b3fdae9c77408"
+ integrity sha512-Il8PAGTZpgRu8vMg+MnRTAD/FdEsTN2LYEFLHhhmiAWdGYkJHxDHWYSeBIIQMR6pJ/biHaF9qsTnYsJHX3OPTw==
+ dependencies:
+ openapi-typescript "5.4.1"
+ openapi-typescript-codegen "^0.24.0"
+
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -9383,7 +9398,7 @@ fs-constants@^1.0.0:
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
-fs-extra@11.1.1, fs-extra@^11.1.0:
+fs-extra@11.1.1, fs-extra@^11.1.0, fs-extra@^11.1.1:
version "11.1.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d"
integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==
@@ -9653,6 +9668,11 @@ globalthis@^1.0.3:
dependencies:
define-properties "^1.1.3"
+globalyzer@0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465"
+ integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==
+
globby@^11.0.1:
version "11.0.4"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
@@ -9699,6 +9719,11 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+globrex@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
+ integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
+
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@@ -11313,6 +11338,13 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+json-schema-ref-parser@^9.0.9:
+ version "9.0.9"
+ resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#66ea538e7450b12af342fa3d5b8458bc1e1e013f"
+ integrity sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==
+ dependencies:
+ "@apidevtools/json-schema-ref-parser" "9.0.9"
+
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -11897,6 +11929,11 @@ mime@^2.0.3:
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
+mime@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
+ integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
+
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@@ -12543,6 +12580,29 @@ open@^8.4.0:
is-docker "^2.1.1"
is-wsl "^2.2.0"
+openapi-typescript-codegen@^0.24.0:
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/openapi-typescript-codegen/-/openapi-typescript-codegen-0.24.0.tgz#b3e6ade5bae75cd47868e5e3e4dc3bcf899cadab"
+ integrity sha512-rSt8t1XbMWhv6Db7GUI24NNli7FU5kzHLxcE8BpzgGWRdWyWt9IB2YoLyPahxNrVA7yOaVgnXPkrcTDRMQtJYg==
+ dependencies:
+ camelcase "^6.3.0"
+ commander "^10.0.0"
+ fs-extra "^11.1.1"
+ handlebars "^4.7.7"
+ json-schema-ref-parser "^9.0.9"
+
+openapi-typescript@5.4.1:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/openapi-typescript/-/openapi-typescript-5.4.1.tgz#38b4b45244acc1361f3c444537833a9e9cb03bf6"
+ integrity sha512-AGB2QiZPz4rE7zIwV3dRHtoUC/CWHhUjuzGXvtmMQN2AFV8xCTLKcZUHLcdPQmt/83i22nRE7+TxXOXkK+gf4Q==
+ dependencies:
+ js-yaml "^4.1.0"
+ mime "^3.0.0"
+ prettier "^2.6.2"
+ tiny-glob "^0.2.9"
+ undici "^5.4.0"
+ yargs-parser "^21.0.1"
+
opener@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
@@ -13326,7 +13386,7 @@ prettier-plugin-tailwindcss@^0.2.6:
resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.8.tgz#e9c0356680331f909a86fefe8fc2b247c21e23a2"
integrity sha512-KgPcEnJeIijlMjsA6WwYgRs5rh3/q76oInqtMXBA/EMcamrcYJpyhtRhyX1ayT9hnHlHTuO8sIifHF10WuSDKg==
-prettier@^2.8.0, prettier@^2.8.8:
+prettier@^2.6.2, prettier@^2.8.0, prettier@^2.8.8:
version "2.8.8"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
@@ -14870,6 +14930,11 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
+streamsearch@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
+ integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
+
strict-event-emitter@^0.2.4, strict-event-emitter@^0.2.6:
version "0.2.8"
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.8.tgz#b4e768927c67273c14c13d20e19d5e6c934b47ca"
@@ -15344,6 +15409,14 @@ thunky@^1.0.2:
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+tiny-glob@^0.2.9:
+ version "0.2.9"
+ resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2"
+ integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==
+ dependencies:
+ globalyzer "0.1.0"
+ globrex "^0.1.2"
+
tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
@@ -15634,6 +15707,13 @@ unc-path-regex@^0.1.2:
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
+undici@^5.4.0:
+ version "5.23.0"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-5.23.0.tgz#e7bdb0ed42cebe7b7aca87ced53e6eaafb8f8ca0"
+ integrity sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==
+ dependencies:
+ busboy "^1.6.0"
+
unfetch@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be"
@@ -16451,7 +16531,7 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.9:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-yargs-parser@^21.0.0, yargs-parser@^21.1.1:
+yargs-parser@^21.0.0, yargs-parser@^21.0.1, yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
|