UNPKG

@iexec/dataprotector

Version:

This product enables users to confidentially store data–such as mail address, documents, personal information ...

146 lines 5.5 kB
import { gql } from 'graphql-request'; import { ensureSearchableDataSchemaIsValid, reverseSafeSchema, } from '../../utils/data.js'; import { ValidationError, WorkflowError } from '../../utils/errors.js'; import { getMultiaddrAsString } from '../../utils/getMultiaddrAsString.js'; import { resolveENS } from '../../utils/resolveENS.js'; import { addressOrEnsSchema, numberBetweenSchema, positiveNumberSchema, throwIfMissing, } from '../../utils/validators.js'; export const getProtectedData = async ({ iexec = throwIfMissing(), graphQLClient = throwIfMissing(), protectedDataAddress, requiredSchema = {}, owner, createdAfterTimestamp, page = 0, pageSize = 1000, }) => { const vCreatedAfterTimestamp = positiveNumberSchema() .label('createdAfterTimestamp') .validateSync(createdAfterTimestamp); const vProtectedDataAddress = addressOrEnsSchema() .label('protectedDataAddress') .validateSync(protectedDataAddress); let vRequiredSchema; try { ensureSearchableDataSchemaIsValid(requiredSchema); vRequiredSchema = requiredSchema; } catch (e) { throw new ValidationError(`requiredSchema is not valid: ${e.message}`); } const vPage = positiveNumberSchema().label('page').validateSync(page); const vPageSize = numberBetweenSchema(10, 1000) .label('pageSize') .validateSync(pageSize); let vOwner = addressOrEnsSchema().label('owner').validateSync(owner); vOwner = await resolveENS(iexec, vOwner); try { const start = vPage * vPageSize; const range = vPageSize; const { requiredSchemas, anyOfSchemas } = flattenSchema(vRequiredSchema); const whereFilters = []; if (vProtectedDataAddress) { whereFilters.push({ id: vProtectedDataAddress }); } if (vOwner) { whereFilters.push({ owner: vOwner }); } if (vCreatedAfterTimestamp) { whereFilters.push({ creationTimestamp_gte: vCreatedAfterTimestamp }); } if (requiredSchemas.length > 0) { whereFilters.push({ schema_contains: requiredSchemas }); } anyOfSchemas.forEach((anyOfSchema) => { whereFilters.push({ or: anyOfSchema.map((schemaFragment) => ({ schema_contains: [schemaFragment], })), }); }); const filteredProtectedDataQuery = gql ` query ($start: Int!, $range: Int!, $where: ProtectedData_filter) { protectedDatas( where: $where skip: $start first: $range orderBy: creationTimestamp orderDirection: desc ) { id name owner { id } schema { id } creationTimestamp multiaddr } } `; const variables = { where: whereFilters.length > 0 ? { and: whereFilters, } : undefined, start, range, }; const protectedDataResultQuery = await graphQLClient.request(filteredProtectedDataQuery, variables); const protectedDataArray = transformGraphQLResponse(protectedDataResultQuery); return protectedDataArray; } catch (e) { console.error('[getProtectedData] ERROR', e); throw new WorkflowError({ message: 'Failed to fetch protected data', errorCause: e, }); } }; function flattenSchema(schema, parentKey) { return Object.entries(schema).reduce((acc, [key, value]) => { const newKey = parentKey ? `${parentKey}.${key}` : key; // Array of possible types if (Array.isArray(value)) { if (value.length > 1) { // one of many acc.anyOfSchemas.push(value.map((entry) => `${newKey}:${entry}`)); } else { // Array of only one type. Similar to single type. acc.requiredSchemas.push(`${newKey}:${value[0]}`); } } // nested schema else if (typeof value === 'object') { const { requiredSchemas, anyOfSchemas } = flattenSchema(value, newKey); acc.requiredSchemas.push(...requiredSchemas); acc.anyOfSchemas.push(...anyOfSchemas); } // single type else { acc.requiredSchemas.push(`${newKey}:${value}`); } return acc; }, { requiredSchemas: [], anyOfSchemas: [] }); } function transformGraphQLResponse(response) { return response.protectedDatas .map((protectedData) => { try { const schema = reverseSafeSchema(protectedData.schema); const readableMultiAddr = getMultiaddrAsString({ multiaddrAsHexString: protectedData.multiaddr, }); return { name: protectedData.name, address: protectedData.id, owner: protectedData.owner.id, schema, creationTimestamp: Number(protectedData.creationTimestamp), multiaddr: readableMultiAddr, }; } catch (error) { // Silently ignore the error to not return multiple errors in the console of the user return null; } }) .filter((item) => item !== null); } //# sourceMappingURL=getProtectedData.js.map