UNPKG

@appsemble/node-utils

Version:

NodeJS utilities used by Appsemble internally.

106 lines 5.18 kB
import { randomUUID } from 'node:crypto'; import { isDeepStrictEqual } from 'node:util'; import { getResourceDefinition, processResourceBody, uploadAssets, } from '../../../../../index.js'; /** * Create a controller for resource creation. * * The created controller handles resource creation of one or more resources, * extracted from the request body. * * The controller can be used to seed resources into an app when the endpoint is * called from the CLI with the `seed` parameter equal to `true`. * * @param options The options object to use for resource creation * @returns A middleware function that handles resource creation. */ export function createCreateAppResourceController(options) { return async (ctx) => { const { pathParams: { appId, resourceType }, query, queryParams: { selectedGroupId }, } = ctx; const { checkAppPermissions, createAppResourcesWithAssets, getApp, getAppAssets } = options; const app = await getApp({ context: ctx, query: { where: { id: appId } } }); await checkAppPermissions({ context: ctx, permissions: [`$resource:${resourceType}:create`], app, groupId: selectedGroupId, }); const resourceDefinition = getResourceDefinition(app.definition, resourceType, ctx); const appAssets = await getAppAssets({ app, context: ctx }); const [processedBody, preparedAssets] = processResourceBody(ctx, resourceDefinition, undefined, undefined, // @ts-expect-error 2345 argument of type is not assignable to parameter of type // (strictNullChecks) appAssets.map((appAsset) => ({ id: appAsset.id, name: appAsset.name }))); if (Array.isArray(processedBody) && !processedBody.length) { ctx.body = []; return; } const resources = Array.isArray(processedBody) ? processedBody : [processedBody]; const assetsToUpload = []; if (!(ctx.client && 'app' in ctx.client) && query?.seed === 'true') { const preparedSeedAssets = structuredClone(preparedAssets); const preparedSeedResources = resources.map((resource) => { const cleanResource = { ...resource }; if (app.demoMode) { for (const referencedProperty of Object.keys(resourceDefinition.references ?? {})) { delete cleanResource[referencedProperty]; } } return { ...cleanResource, $seed: true, $ephemeral: false, }; }); for (const preparedSeedAsset of preparedSeedAssets) { const index = resources.findIndex(({ $clonable: clonable, $ephemeral: ephemeral, $seed: unused, ...cleanResource }) => { // @ts-expect-error Messed up const { $clonable, $ephemeral, $seed, ...cleanAssetResource } = preparedSeedAsset.resource; return isDeepStrictEqual(cleanResource, cleanAssetResource); }); const previousAssetId = preparedSeedAsset.id; const newAssetId = randomUUID(); const updatedResource = JSON.parse(JSON.stringify(preparedSeedResources[index]).replace(previousAssetId, newAssetId)); preparedSeedAsset.id = newAssetId; preparedSeedAsset.resource = updatedResource; preparedSeedResources[index] = updatedResource; } const createdSeedResources = await createAppResourcesWithAssets({ app, groupId: selectedGroupId, context: ctx, resources: preparedSeedResources, preparedAssets: preparedSeedAssets, resourceType, options, }); if (!app.demoMode) { ctx.body = Array.isArray(processedBody) ? createdSeedResources : createdSeedResources[0]; // @ts-expect-error 2345 argument of type is not assignable to parameter of type // (strictNullChecks) await uploadAssets(app.id, preparedSeedAssets); return; } assetsToUpload.push(...preparedSeedAssets); } const createdResources = await createAppResourcesWithAssets({ app, groupId: selectedGroupId, context: ctx, resources: resources.map((resource) => ({ ...resource, $seed: false, $ephemeral: app.demoMode, ...(app.demoMode ? { $clonable: false } : {}), })), preparedAssets, resourceType, options, }); assetsToUpload.push(...preparedAssets); // @ts-expect-error 2345 argument of type is not assignable to parameter of type // (strictNullChecks) await uploadAssets(app.id, assetsToUpload); ctx.body = Array.isArray(processedBody) ? createdResources : createdResources[0]; }; } //# sourceMappingURL=createCreateAppResourceController.js.map