added config override crud

This commit is contained in:
Zai Shi 2025-07-24 17:39:38 -07:00
parent bc069b083c
commit 9ceb0acac3
2 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1,61 @@
import { getRenderedEnvironmentConfigQuery, overrideEnvironmentConfigOverride } from "@/lib/config";
import { getPrismaClientForTenancy, rawQuery } from "@/prisma-client";
import { createCrudHandlers } from "@/route-handlers/crud-handler";
import { configOverridesCrud } from "@stackframe/stack-shared/dist/interface/crud/config-overrides";
import { yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
import { createLazyProxy } from "@stackframe/stack-shared/dist/utils/proxies";
export const configOverridesCrudHandlers = createLazyProxy(() => createCrudHandlers(configOverridesCrud, {
paramsSchema: yupObject({
emailId: yupString().optional(),
}),
onRead: async ({ auth }) => {
return {
id: auth.project.id,
branch_id: auth.tenancy.branchId,
organization_id: auth.tenancy.organization?.id,
project_id: auth.project.id,
config: JSON.stringify(auth.tenancy.config),
};
},
onUpdate: async ({ auth, data }) => {
if (auth.tenancy.organization) {
throw new StatusError(StatusError.BadRequest, 'Organizational config overrides are not yet supported');
}
const prisma = await getPrismaClientForTenancy(auth.tenancy);
if (data.config) {
let parsedConfig;
try {
parsedConfig = JSON.parse(data.config);
} catch (e) {
if (e instanceof SyntaxError) {
throw new StatusError(StatusError.BadRequest, 'Invalid config JSON');
}
throw e;
}
await overrideEnvironmentConfigOverride({
projectId: auth.project.id,
branchId: auth.tenancy.branchId,
environmentConfigOverrideOverride: parsedConfig,
tx: prisma,
});
}
const updatedConfig = await rawQuery(prisma, getRenderedEnvironmentConfigQuery({
projectId: auth.project.id,
branchId: auth.tenancy.branchId,
}));
return {
id: auth.project.id,
branch_id: auth.tenancy.branchId,
// @ts-expect-error: remove this once we support organizational config overrides
organization_id: auth.tenancy.organization?.id,
project_id: auth.project.id,
config: JSON.stringify(updatedConfig),
};
},
}));

View File

@ -0,0 +1,33 @@
import { CrudTypeOf, createCrud } from "../../crud";
import * as schemaFields from "../../schema-fields";
import { yupObject } from "../../schema-fields";
export const configOverridesCrudAdminReadSchema = yupObject({
project_id: schemaFields.yupString().defined(),
branch_id: schemaFields.yupString().defined(),
organization_id: schemaFields.yupString().optional(),
id: schemaFields.yupString().defined(),
config: schemaFields.yupString().defined(),
}).defined();
export const configOverridesCrudAdminUpdateSchema = yupObject({
config: schemaFields.yupString().optional(),
}).defined();
export const configOverridesCrud = createCrud({
adminReadSchema: configOverridesCrudAdminReadSchema,
adminUpdateSchema: configOverridesCrudAdminUpdateSchema,
docs: {
adminRead: {
summary: 'Get the current config overrides',
description: 'Get the current config overrides with the specified project id and branch id',
tags: ['Config'],
},
adminUpdate: {
summary: 'Update the current config overrides',
description: 'Update the current config overrides with the specified project id and branch id',
tags: ['Config'],
},
},
});
export type ConfigOverridesCrud = CrudTypeOf<typeof configOverridesCrud>;