mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Fix External secrets typecheck (no-changelog) (#9434)
This commit is contained in:
parent
28e3e21177
commit
db1a40635d
|
@ -1803,18 +1803,19 @@ export interface ExternalSecretsProviderSecret {
|
||||||
|
|
||||||
export type ExternalSecretsProviderData = Record<string, IUpdateInformation['value']>;
|
export type ExternalSecretsProviderData = Record<string, IUpdateInformation['value']>;
|
||||||
|
|
||||||
|
export type ExternalSecretsProviderProperty = INodeProperties;
|
||||||
|
|
||||||
|
export type ExternalSecretsProviderState = 'connected' | 'tested' | 'initializing' | 'error';
|
||||||
|
|
||||||
export interface ExternalSecretsProvider {
|
export interface ExternalSecretsProvider {
|
||||||
icon: string;
|
icon: string;
|
||||||
name: string;
|
name: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
connectedAt: string | false;
|
connectedAt: string | false;
|
||||||
state: 'connected' | 'tested' | 'initializing' | 'error';
|
state: ExternalSecretsProviderState;
|
||||||
data?: ExternalSecretsProviderData;
|
data?: ExternalSecretsProviderData;
|
||||||
}
|
properties?: ExternalSecretsProviderProperty[];
|
||||||
|
|
||||||
export interface ExternalSecretsProviderWithProperties extends ExternalSecretsProvider {
|
|
||||||
properties: INodeProperties[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CloudUpdateLinkSourceType =
|
export type CloudUpdateLinkSourceType =
|
||||||
|
@ -1835,6 +1836,7 @@ export type CloudUpdateLinkSourceType =
|
||||||
| 'community-nodes'
|
| 'community-nodes'
|
||||||
| 'workflow-history'
|
| 'workflow-history'
|
||||||
| 'worker-view'
|
| 'worker-view'
|
||||||
|
| 'external-secrets'
|
||||||
| 'rbac';
|
| 'rbac';
|
||||||
|
|
||||||
export type UTMCampaign =
|
export type UTMCampaign =
|
||||||
|
@ -1855,6 +1857,7 @@ export type UTMCampaign =
|
||||||
| 'upgrade-workflow-history'
|
| 'upgrade-workflow-history'
|
||||||
| 'upgrade-advanced-permissions'
|
| 'upgrade-advanced-permissions'
|
||||||
| 'upgrade-worker-view'
|
| 'upgrade-worker-view'
|
||||||
|
| 'upgrade-external-secrets'
|
||||||
| 'upgrade-rbac';
|
| 'upgrade-rbac';
|
||||||
|
|
||||||
export type N8nBanners = {
|
export type N8nBanners = {
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import type {
|
import type { IRestApiContext, ExternalSecretsProvider } from '@/Interface';
|
||||||
IRestApiContext,
|
|
||||||
ExternalSecretsProvider,
|
|
||||||
ExternalSecretsProviderWithProperties,
|
|
||||||
} from '@/Interface';
|
|
||||||
import { makeRestApiRequest } from '@/utils/apiUtils';
|
import { makeRestApiRequest } from '@/utils/apiUtils';
|
||||||
|
|
||||||
export const getExternalSecrets = async (
|
export const getExternalSecrets = async (
|
||||||
|
@ -20,7 +16,7 @@ export const getExternalSecretsProviders = async (
|
||||||
export const getExternalSecretsProvider = async (
|
export const getExternalSecretsProvider = async (
|
||||||
context: IRestApiContext,
|
context: IRestApiContext,
|
||||||
id: string,
|
id: string,
|
||||||
): Promise<ExternalSecretsProviderWithProperties> => {
|
): Promise<ExternalSecretsProvider> => {
|
||||||
return await makeRestApiRequest(context, 'GET', `/external-secrets/providers/${id}`);
|
return await makeRestApiRequest(context, 'GET', `/external-secrets/providers/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { PropType, Ref } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import type { ExternalSecretsProvider } from '@/Interface';
|
import type { ExternalSecretsProvider } from '@/Interface';
|
||||||
import ExternalSecretsProviderImage from '@/components/ExternalSecretsProviderImage.ee.vue';
|
import ExternalSecretsProviderImage from '@/components/ExternalSecretsProviderImage.ee.vue';
|
||||||
import ExternalSecretsProviderConnectionSwitch from '@/components/ExternalSecretsProviderConnectionSwitch.ee.vue';
|
import ExternalSecretsProviderConnectionSwitch from '@/components/ExternalSecretsProviderConnectionSwitch.ee.vue';
|
||||||
|
@ -10,7 +10,8 @@ import { useI18n } from '@/composables/useI18n';
|
||||||
import { useExternalSecretsProvider } from '@/composables/useExternalSecretsProvider';
|
import { useExternalSecretsProvider } from '@/composables/useExternalSecretsProvider';
|
||||||
import { EXTERNAL_SECRETS_PROVIDER_MODAL_KEY } from '@/constants';
|
import { EXTERNAL_SECRETS_PROVIDER_MODAL_KEY } from '@/constants';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { computed, nextTick, onMounted, toRefs } from 'vue';
|
import { computed, nextTick, onMounted, toRef } from 'vue';
|
||||||
|
import { isDateObject } from '@/utils/typeGuards';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
provider: {
|
provider: {
|
||||||
|
@ -24,15 +25,12 @@ const i18n = useI18n();
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const { provider } = toRefs(props) as Ref<ExternalSecretsProvider>;
|
const provider = toRef(props, 'provider');
|
||||||
const providerData = computed(() => provider.value.data);
|
const providerData = computed(() => provider.value.data ?? {});
|
||||||
const {
|
const { connectionState, testConnection, setConnectionState } = useExternalSecretsProvider(
|
||||||
connectionState,
|
provider,
|
||||||
initialConnectionState,
|
providerData,
|
||||||
normalizedProviderData,
|
);
|
||||||
testConnection,
|
|
||||||
setConnectionState,
|
|
||||||
} = useExternalSecretsProvider(provider, providerData);
|
|
||||||
|
|
||||||
const actionDropdownOptions = computed(() => [
|
const actionDropdownOptions = computed(() => [
|
||||||
{
|
{
|
||||||
|
@ -50,11 +48,15 @@ const actionDropdownOptions = computed(() => [
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const canConnect = computed(() => {
|
const canConnect = computed(() => {
|
||||||
return props.provider.connected || Object.keys(props.provider.data).length > 0;
|
return props.provider.connected || Object.keys(providerData.value).length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const formattedDate = computed((provider: ExternalSecretsProvider) => {
|
const formattedDate = computed(() => {
|
||||||
return DateTime.fromISO(props.provider.connectedAt ?? new Date()).toFormat('dd LLL yyyy');
|
return DateTime.fromISO(
|
||||||
|
isDateObject(provider.value.connectedAt)
|
||||||
|
? provider.value.connectedAt.toISOString()
|
||||||
|
: provider.value.connectedAt || new Date().toISOString(),
|
||||||
|
).toFormat('dd LLL yyyy');
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import type { ExternalSecretsProvider } from '@/Interface';
|
import type { ExternalSecretsProvider } from '@/Interface';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import infisical from '../assets/images/infisical.webp';
|
import infisical from '../assets/images/infisical.webp';
|
||||||
import doppler from '../assets/images/doppler.webp';
|
import doppler from '../assets/images/doppler.webp';
|
||||||
import vault from '../assets/images/hashicorp.webp';
|
import vault from '../assets/images/hashicorp.webp';
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import Modal from './Modal.vue';
|
import Modal from './Modal.vue';
|
||||||
import { EXTERNAL_SECRETS_PROVIDER_MODAL_KEY, MODAL_CONFIRM } from '@/constants';
|
import { EXTERNAL_SECRETS_PROVIDER_MODAL_KEY, MODAL_CONFIRM } from '@/constants';
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import type { PropType, Ref } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import type { EventBus } from 'n8n-design-system/utils';
|
import type { EventBus } from 'n8n-design-system/utils';
|
||||||
import { useExternalSecretsProvider } from '@/composables/useExternalSecretsProvider';
|
import { useExternalSecretsProvider } from '@/composables/useExternalSecretsProvider';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
|
@ -10,7 +10,6 @@ import { useMessage } from '@/composables/useMessage';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
|
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import ParameterInputExpanded from '@/components/ParameterInputExpanded.vue';
|
import ParameterInputExpanded from '@/components/ParameterInputExpanded.vue';
|
||||||
import type {
|
import type {
|
||||||
IUpdateInformation,
|
IUpdateInformation,
|
||||||
|
@ -29,7 +28,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultProviderData = {
|
const defaultProviderData: Record<string, Partial<ExternalSecretsProviderData>> = {
|
||||||
infisical: {
|
infisical: {
|
||||||
siteURL: 'https://app.infisical.com',
|
siteURL: 'https://app.infisical.com',
|
||||||
},
|
},
|
||||||
|
@ -39,7 +38,6 @@ const externalSecretsStore = useExternalSecretsStore();
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const route = useRoute();
|
|
||||||
const { confirm } = useMessage();
|
const { confirm } = useMessage();
|
||||||
|
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
|
@ -50,7 +48,7 @@ const labelSize: IParameterLabel = { size: 'medium' };
|
||||||
|
|
||||||
const provider = computed<ExternalSecretsProvider | undefined>(() =>
|
const provider = computed<ExternalSecretsProvider | undefined>(() =>
|
||||||
externalSecretsStore.providers.find((p) => p.name === props.data.name),
|
externalSecretsStore.providers.find((p) => p.name === props.data.name),
|
||||||
) as Ref<ExternalSecretsProvider>;
|
);
|
||||||
const providerData = ref<ExternalSecretsProviderData>({});
|
const providerData = ref<ExternalSecretsProviderData>({});
|
||||||
const {
|
const {
|
||||||
connectionState,
|
connectionState,
|
||||||
|
@ -64,7 +62,7 @@ const {
|
||||||
const providerDataUpdated = computed(() => {
|
const providerDataUpdated = computed(() => {
|
||||||
return Object.keys(providerData.value).find((key) => {
|
return Object.keys(providerData.value).find((key) => {
|
||||||
const value = providerData.value[key];
|
const value = providerData.value[key];
|
||||||
const originalValue = provider.value.data[key];
|
const originalValue = provider.value?.data?.[key];
|
||||||
|
|
||||||
return value !== originalValue;
|
return value !== originalValue;
|
||||||
});
|
});
|
||||||
|
@ -72,7 +70,7 @@ const providerDataUpdated = computed(() => {
|
||||||
|
|
||||||
const canSave = computed(
|
const canSave = computed(
|
||||||
() =>
|
() =>
|
||||||
provider.value.properties
|
provider.value?.properties
|
||||||
?.filter((property) => property.required && shouldDisplayProperty(property))
|
?.filter((property) => property.required && shouldDisplayProperty(property))
|
||||||
.every((property) => {
|
.every((property) => {
|
||||||
const value = providerData.value[property.name];
|
const value = providerData.value[property.name];
|
||||||
|
@ -82,21 +80,22 @@ const canSave = computed(
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
const provider = await externalSecretsStore.getProvider(props.data.name);
|
const fetchedProvider = await externalSecretsStore.getProvider(props.data.name);
|
||||||
|
|
||||||
providerData.value = {
|
providerData.value = {
|
||||||
...(defaultProviderData[props.data.name] || {}),
|
...(defaultProviderData[props.data.name] || {}),
|
||||||
...provider.data,
|
...fetchedProvider.data,
|
||||||
};
|
};
|
||||||
|
|
||||||
setConnectionState(provider.state);
|
setConnectionState(fetchedProvider.state);
|
||||||
|
|
||||||
if (provider.connected) {
|
if (fetchedProvider.connected) {
|
||||||
initialConnectionState.value = provider.state;
|
initialConnectionState.value = fetchedProvider.state;
|
||||||
} else if (Object.keys(provider.data).length) {
|
} else if (Object.keys(fetchedProvider.data ?? {}).length) {
|
||||||
await testConnection();
|
await testConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (provider.state === 'connected') {
|
if (fetchedProvider.state === 'connected') {
|
||||||
void externalSecretsStore.reloadProvider(props.data.name);
|
void externalSecretsStore.reloadProvider(props.data.name);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -116,6 +115,10 @@ function onValueChange(updateInformation: IUpdateInformation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
|
if (!provider.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
saving.value = true;
|
saving.value = true;
|
||||||
await externalSecretsStore.updateProvider(provider.value.name, {
|
await externalSecretsStore.updateProvider(provider.value.name, {
|
||||||
|
@ -143,7 +146,7 @@ async function onBeforeClose() {
|
||||||
const confirmModal = await confirm(
|
const confirmModal = await confirm(
|
||||||
i18n.baseText('settings.externalSecrets.provider.closeWithoutSaving.description', {
|
i18n.baseText('settings.externalSecrets.provider.closeWithoutSaving.description', {
|
||||||
interpolate: {
|
interpolate: {
|
||||||
provider: provider.value.displayName,
|
provider: provider.value?.displayName ?? '',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -162,19 +165,23 @@ async function onBeforeClose() {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onConnectionStateChange() {
|
||||||
|
await testConnection();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
id="external-secrets-provider-modal"
|
id="external-secrets-provider-modal"
|
||||||
width="812px"
|
width="812px"
|
||||||
:title="provider.displayName"
|
:title="provider?.displayName"
|
||||||
:event-bus="data.eventBus"
|
:event-bus="data.eventBus"
|
||||||
:name="EXTERNAL_SECRETS_PROVIDER_MODAL_KEY"
|
:name="EXTERNAL_SECRETS_PROVIDER_MODAL_KEY"
|
||||||
:before-close="onBeforeClose"
|
:before-close="onBeforeClose"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div :class="$style.header">
|
<div v-if="provider" :class="$style.header">
|
||||||
<div :class="$style.providerTitle">
|
<div :class="$style.providerTitle">
|
||||||
<ExternalSecretsProviderImage :provider="provider" class="mr-xs" />
|
<ExternalSecretsProviderImage :provider="provider" class="mr-xs" />
|
||||||
<span>{{ provider.displayName }}</span>
|
<span>{{ provider.displayName }}</span>
|
||||||
|
@ -188,7 +195,7 @@ async function onBeforeClose() {
|
||||||
"
|
"
|
||||||
:event-bus="eventBus"
|
:event-bus="eventBus"
|
||||||
:provider="provider"
|
:provider="provider"
|
||||||
@change="testConnection"
|
@change="onConnectionStateChange"
|
||||||
/>
|
/>
|
||||||
<n8n-button
|
<n8n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -207,7 +214,7 @@ async function onBeforeClose() {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<div :class="$style.container">
|
<div v-if="provider" :class="$style.container">
|
||||||
<hr class="mb-l" />
|
<hr class="mb-l" />
|
||||||
<div v-if="connectionState !== 'initializing'" class="mb-l">
|
<div v-if="connectionState !== 'initializing'" class="mb-l">
|
||||||
<n8n-callout
|
<n8n-callout
|
||||||
|
|
|
@ -1,36 +1,41 @@
|
||||||
import type {
|
import type {
|
||||||
ExternalSecretsProviderWithProperties,
|
|
||||||
ExternalSecretsProvider,
|
ExternalSecretsProvider,
|
||||||
IUpdateInformation,
|
IUpdateInformation,
|
||||||
ExternalSecretsProviderData,
|
ExternalSecretsProviderData,
|
||||||
|
ExternalSecretsProviderProperty,
|
||||||
|
ExternalSecretsProviderState,
|
||||||
} from '@/Interface';
|
} from '@/Interface';
|
||||||
import type { Ref } from 'vue';
|
import type { ComputedRef, Ref } from 'vue';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
|
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
|
|
||||||
export function useExternalSecretsProvider(
|
export function useExternalSecretsProvider(
|
||||||
provider: Ref<ExternalSecretsProvider>,
|
provider:
|
||||||
|
| Ref<ExternalSecretsProvider | undefined>
|
||||||
|
| ComputedRef<ExternalSecretsProvider | undefined>,
|
||||||
providerData: Ref<ExternalSecretsProviderData>,
|
providerData: Ref<ExternalSecretsProviderData>,
|
||||||
) {
|
) {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const externalSecretsStore = useExternalSecretsStore();
|
const externalSecretsStore = useExternalSecretsStore();
|
||||||
|
|
||||||
const initialConnectionState = ref<ExternalSecretsProviderWithProperties['state'] | undefined>(
|
const initialConnectionState = ref<ExternalSecretsProvider['state'] | undefined>('initializing');
|
||||||
'initializing',
|
|
||||||
);
|
|
||||||
const connectionState = computed(
|
const connectionState = computed(
|
||||||
() => externalSecretsStore.connectionState[provider.value?.name],
|
() => externalSecretsStore.connectionState[provider.value?.name ?? ''],
|
||||||
);
|
);
|
||||||
const setConnectionState = (state: ExternalSecretsProviderWithProperties['state']) => {
|
const setConnectionState = (state: ExternalSecretsProvider['state']) => {
|
||||||
externalSecretsStore.setConnectionState(provider.value?.name, state);
|
if (!provider.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
externalSecretsStore.setConnectionState(provider.value.name, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizedProviderData = computed(() => {
|
const normalizedProviderData = computed(() => {
|
||||||
return Object.entries(providerData.value).reduce(
|
return Object.entries(providerData.value).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc, [key, value]) => {
|
||||||
const property = provider.value?.properties?.find((property) => property.name === key);
|
const property = provider.value?.properties?.find((p) => p.name === key);
|
||||||
if (shouldDisplayProperty(property)) {
|
if (property && shouldDisplayProperty(property)) {
|
||||||
acc[key] = value;
|
acc[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,16 +45,14 @@ export function useExternalSecretsProvider(
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function shouldDisplayProperty(
|
function shouldDisplayProperty(property: ExternalSecretsProviderProperty): boolean {
|
||||||
property: ExternalSecretsProviderWithProperties['properties'][0],
|
|
||||||
): boolean {
|
|
||||||
let visible = true;
|
let visible = true;
|
||||||
|
|
||||||
if (property.displayOptions?.show) {
|
if (property.displayOptions?.show) {
|
||||||
visible =
|
visible =
|
||||||
visible &&
|
visible &&
|
||||||
Object.entries(property.displayOptions.show).every(([key, value]) => {
|
Object.entries(property.displayOptions.show).every(([key, value]) => {
|
||||||
return value?.includes(providerData.value[key]);
|
return value?.includes(providerData.value[key] as string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +60,20 @@ export function useExternalSecretsProvider(
|
||||||
visible =
|
visible =
|
||||||
visible &&
|
visible &&
|
||||||
!Object.entries(property.displayOptions.hide).every(([key, value]) => {
|
!Object.entries(property.displayOptions.hide).every(([key, value]) => {
|
||||||
return value?.includes(providerData.value[key]);
|
return value?.includes(providerData.value[key] as string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testConnection(options: { showError?: boolean } = { showError: true }) {
|
async function testConnection(
|
||||||
|
options: { showError?: boolean } = { showError: true },
|
||||||
|
): Promise<ExternalSecretsProviderState> {
|
||||||
|
if (!provider.value) {
|
||||||
|
return 'initializing';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { testState } = await externalSecretsStore.testProviderConnection(
|
const { testState } = await externalSecretsStore.testProviderConnection(
|
||||||
provider.value.name,
|
provider.value.name,
|
||||||
|
|
7
packages/editor-ui/src/shims.d.ts
vendored
7
packages/editor-ui/src/shims.d.ts
vendored
|
@ -35,3 +35,10 @@ declare global {
|
||||||
findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T;
|
findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '*.svg';
|
||||||
|
declare module '*.png';
|
||||||
|
declare module '*.jpg';
|
||||||
|
declare module '*.jpeg';
|
||||||
|
declare module '*.gif';
|
||||||
|
declare module '*.webp';
|
||||||
|
|
|
@ -43,3 +43,9 @@ export const isResourceMapperValue = (value: unknown): value is string | number
|
||||||
export const isJSPlumbEndpointElement = (element: Node): element is HTMLElement => {
|
export const isJSPlumbEndpointElement = (element: Node): element is HTMLElement => {
|
||||||
return 'jtk' in element && 'endpoint' in (element.jtk as object);
|
return 'jtk' in element && 'endpoint' in (element.jtk as object);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function isDateObject(date: unknown): date is Date {
|
||||||
|
return (
|
||||||
|
!!date && Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date as number)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,13 @@
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"types": ["vitest/globals", "../workflow/src/types.d.ts"],
|
"types": [
|
||||||
|
"vitest/globals",
|
||||||
|
"src/shims.d.ts",
|
||||||
|
"src/shims-vue.d.ts",
|
||||||
|
"src/v3-infinite-loading.d.ts",
|
||||||
|
"../workflow/src/types.d.ts"
|
||||||
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["src/*"],
|
"@/*": ["src/*"],
|
||||||
"n8n-design-system/*": ["../design-system/src/*"],
|
"n8n-design-system/*": ["../design-system/src/*"],
|
||||||
|
@ -23,5 +29,5 @@
|
||||||
"useUnknownInCatchVariables": false,
|
"useUnknownInCatchVariables": false,
|
||||||
"experimentalDecorators": true
|
"experimentalDecorators": true
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.vue"]
|
"include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue