Merge branch 'features/deits' into deits/engine-tests

This commit is contained in:
Ben Irvin 2022-11-22 10:29:25 +01:00
commit 1b7222a16a
5 changed files with 51 additions and 44 deletions

View File

@ -6,12 +6,13 @@ import { Readable } from 'stream';
export const collect = <T = unknown>(stream: Readable): Promise<T[]> => { export const collect = <T = unknown>(stream: Readable): Promise<T[]> => {
const chunks: T[] = []; const chunks: T[] = [];
return new Promise((resolve) => { return new Promise((resolve, reject) => {
stream.on('data', (chunk) => chunks.push(chunk)); stream
stream.on('end', () => { .on('data', (chunk) => chunks.push(chunk))
stream.destroy(); .on('close', () => {
resolve(chunks); resolve(chunks);
}); })
.on('error', reject);
}); });
}; };

View File

@ -1,4 +1,4 @@
import { Duplex } from 'stream'; import { Readable } from 'stream';
import { createLinksStream } from '../links'; import { createLinksStream } from '../links';
import { getDeepPopulateQuery } from '../links/utils'; import { getDeepPopulateQuery } from '../links/utils';
@ -15,7 +15,7 @@ describe('Local Strapi Source Provider - Entities Streaming', () => {
const stream = createLinksStream(strapi); const stream = createLinksStream(strapi);
expect(stream).toBeInstanceOf(Duplex); expect(stream).toBeInstanceOf(Readable);
const links = await collect(stream); const links = await collect(stream);
@ -60,7 +60,7 @@ describe('Local Strapi Source Provider - Entities Streaming', () => {
const stream = createLinksStream(strapi); const stream = createLinksStream(strapi);
expect(stream).toBeInstanceOf(Duplex); expect(stream).toBeInstanceOf(Readable);
const links = await collect(stream); const links = await collect(stream);
@ -140,7 +140,7 @@ describe('Local Strapi Source Provider - Entities Streaming', () => {
const stream = createLinksStream(strapi); const stream = createLinksStream(strapi);
expect(stream).toBeInstanceOf(Duplex); expect(stream).toBeInstanceOf(Readable);
const links = await collect(stream); const links = await collect(stream);
@ -238,7 +238,7 @@ describe('Local Strapi Source Provider - Entities Streaming', () => {
const stream = createLinksStream(strapi); const stream = createLinksStream(strapi);
expect(stream).toBeInstanceOf(Duplex); expect(stream).toBeInstanceOf(Readable);
const links = await collect(stream); const links = await collect(stream);

View File

@ -1,11 +1,11 @@
import { Duplex } from 'stream';
import { chain } from 'stream-chain'; import { chain } from 'stream-chain';
import { Readable } from 'stream';
import { set } from 'lodash/fp'; import { set } from 'lodash/fp';
/** /**
* Create a readable stream that export the Strapi app configuration * Create a readable stream that export the Strapi app configuration
*/ */
export const createConfigurationStream = (strapi: Strapi.Strapi): Duplex => { export const createConfigurationStream = (strapi: Strapi.Strapi): Readable => {
// Core Store // Core Store
const coreStoreStream = chain([ const coreStoreStream = chain([
strapi.db.queryBuilder('strapi::core-store').stream(), strapi.db.queryBuilder('strapi::core-store').stream(),
@ -22,13 +22,15 @@ export const createConfigurationStream = (strapi: Strapi.Strapi): Duplex => {
const streams = [coreStoreStream, webhooksStream]; const streams = [coreStoreStream, webhooksStream];
// Readable configuration stream // Readable configuration stream
return Duplex.from(async function* () { return Readable.from(
for (const stream of streams) { (async function* () {
for await (const item of stream) { for (const stream of streams) {
yield item; for await (const item of stream) {
yield item;
}
} }
} })()
}); );
}; };
const wrapConfigurationItem = (type: 'core-store' | 'webhook') => (value: unknown) => ({ const wrapConfigurationItem = (type: 'core-store' | 'webhook') => (value: unknown) => ({

View File

@ -1,11 +1,11 @@
import type { ContentTypeSchema } from '@strapi/strapi'; import type { ContentTypeSchema } from '@strapi/strapi';
import { Readable, Duplex, PassThrough } from 'stream'; import { Readable, PassThrough } from 'stream';
/** /**
* Generate and consume content-types streams in order to stream each entity individually * Generate and consume content-types streams in order to stream each entity individually
*/ */
export const createEntitiesStream = (strapi: Strapi.Strapi): Duplex => { export const createEntitiesStream = (strapi: Strapi.Strapi): Readable => {
const contentTypes: ContentTypeSchema[] = Object.values(strapi.contentTypes); const contentTypes: ContentTypeSchema[] = Object.values(strapi.contentTypes);
async function* contentTypeStreamGenerator() { async function* contentTypeStreamGenerator() {
@ -22,15 +22,17 @@ export const createEntitiesStream = (strapi: Strapi.Strapi): Duplex => {
} }
} }
return Duplex.from(async function* () { return Readable.from(
for await (const { stream, contentType } of contentTypeStreamGenerator()) { (async function* () {
for await (const entity of stream) { for await (const { stream, contentType } of contentTypeStreamGenerator()) {
yield { entity, contentType }; for await (const entity of stream) {
} yield { entity, contentType };
}
stream.destroy(); stream.destroy();
} }
}); })()
);
}; };
/** /**

View File

@ -1,6 +1,6 @@
import type { ContentTypeSchema, GetAttributesValues, RelationsType } from '@strapi/strapi'; import type { ContentTypeSchema, GetAttributesValues, RelationsType } from '@strapi/strapi';
import { Duplex } from 'stream'; import { Readable } from 'stream';
import { castArray } from 'lodash/fp'; import { castArray } from 'lodash/fp';
import { getDeepPopulateQuery, parseEntityLinks } from './utils'; import { getDeepPopulateQuery, parseEntityLinks } from './utils';
@ -8,7 +8,7 @@ import { getDeepPopulateQuery, parseEntityLinks } from './utils';
/** /**
* Create a Duplex instance which will stream all the links from a Strapi instance * Create a Duplex instance which will stream all the links from a Strapi instance
*/ */
export const createLinksStream = (strapi: Strapi.Strapi): Duplex => { export const createLinksStream = (strapi: Strapi.Strapi): Readable => {
const schemas: ContentTypeSchema[] = Object.values(strapi.contentTypes); const schemas: ContentTypeSchema[] = Object.values(strapi.contentTypes);
// Destroy the Duplex stream instance // Destroy the Duplex stream instance
@ -19,25 +19,27 @@ export const createLinksStream = (strapi: Strapi.Strapi): Duplex => {
}; };
// Async generator stream that returns every link from a Strapi instance // Async generator stream that returns every link from a Strapi instance
const stream = Duplex.from(async function* () { const stream = Readable.from(
for (const schema of schemas) { (async function* () {
const populate = getDeepPopulateQuery(schema, strapi); for (const schema of schemas) {
const query = { fields: ['id'], populate }; const populate = getDeepPopulateQuery(schema, strapi);
const query = { fields: ['id'], populate };
// TODO: Replace with the DB stream API // TODO: Replace with the DB stream API
const results = await strapi.entityService.findMany(schema.uid, query); const results = await strapi.entityService.findMany(schema.uid, query);
for (const entity of castArray(results)) { for (const entity of castArray(results)) {
const links = parseEntityLinks(entity, populate, schema, strapi); const links = parseEntityLinks(entity, populate, schema, strapi);
for (const link of links) { for (const link of links) {
yield link; yield link;
}
} }
} }
}
destroy(); destroy();
}); })()
);
return stream; return stream;
}; };