@candoimage/prisma-extension-nested-operations

中文文档
1.6.4发布于 2026/03/30Apache-2.0TypeScriptESM + CJS近 30 天下载 2.2万

用于创建带有嵌入操作的 Prisma 客户端扩展的 Utils

中文使用文档
文档目录15 节
  1. 目录
  2. 安装
  3. 使用量
  4. $rootOperation()
  5. $allNestedOperations() 参数
  6. 嵌入式写作
  7. 何处
  8. 包含
  9. 选择
  10. 关系
  11. 修改嵌入式书写参数
  12. 修改参数位置
  13. 修改结果
  14. 错误
  15. 自由主义

Prisma 扩展嵌入操作

Prisma 扩展库允许在 Prisma 查询中修改嵌入关系上的操作 .

Vanilla Prisma 扩展对修改顶级查询很有帮助,但是 当它们必须处理时仍然难以使用 筑巢写作, (中文(简体) ), includes, (中文(简体) ), selects, (中文(简体) ), 或修改 where 对象的参考关系. 更深入地讨论这个问题 关于嵌入式中间软件的问题,则 同样的问题也适用于扩展.

此库输出 a withNestedOperations() 拆分一个 $allOperations() 钩入 $rootOperation() 财务报告和审定财务报表 $allNestedOperations() 钩子.


Build Status version MIT License semantic-release PRs Welcome

目录

安装

此模块通过 无 与 节点 财务报告和审定财务报表 应当安装为您的项目依赖性之一 :

npm install @candoimage/prisma-extension-nested-operations

@prisma/client 是此库的对等依赖, 因此您需要 如果您还没有安装它 :

npm install @prisma/client

您必须至少安装了 @ prisma/ 客户端的7. 0.0 版本 .

使用量

这个 withNestedOperations() 函数取用和反对两个属性, $rootOperation() 财务报告和审定财务报表 $allNestedOperations()。 。 。 . 返回值为 $allOperations 钩子,可以直接传递到扩展 $allOperations 钩.

import { Prisma } from "@prisma/client";
import { withNestedOperations } from "@candoimage/prisma-extension-nested-operations";

client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          // update root params here
          const result = params.query(params.args);
          // update root result here
          return result;
        },
        async $allNestedOperations(params) {
          // update nested params here
          const result = await params.query(params.args);
          // update nested result here
          return result;
        },
      }),
    },
  },
});

$rootOperation()

这个 $rootOperation() 钩子叫同一段 $allOperations() 钩子,但 params.args 对象 已更新 $allNestedOperations() 查询功能。 同样的模式适用于 返回结果,它是通过返回结果更新的查询的结果 $allNestedOperations() 打电话.

$allNestedOperations() 参数

参数对象传递到 $allNestedOperations() 函数与传递到 $allOperations()。 。 。 . 它已经 args, (中文(简体) ), model, (中文(简体) ), operation,以及 query 字段,但有一些关键差异:

  • 页:1 operation 字段添加以下选项:"连接 OrCreate","连接","断开","包含","选择"和"在哪里"

  • 页:1 query 字段需要第二个参数,即 operation 执行中。 这在巢穴操作的类型应该被改变的地方是有用的.

  • 还有一个 scope 字段,其中包含与嵌入关系相关的特定信息:

    • 页:1 parentParams 字段包含父关系参数对象
    • 页:1 modifier 字段中包含任何修改符,例如包含参数 some 或者说 every。 。 。 .
    • 页:1 logicalOperators 字段包含当前关系与其父关系之间的任何逻辑运算符,例如 AND 或者说 NOT。 。 。 .
    • 页:1 relations 字段包含一个与关系相关的对象 to 当前模式和 from 模特儿回到父母身边.

详情请查阅 modifier 财务报告和审定财务报表 logicalOperators 字段见 何处 节.

详情请查阅 relations 见 关系 节.

参数对象的类型是:

type NestedParams<ExtArgs> = {
  query: (args: any, operation?: NestedOperation) => Prisma.PrismaPromise<any>;
  model: keyof Prisma.TypeMap<ExtArgs>["model"];
  args: any;
  operation: NestedOperation;
  scope?: Scope<ExtArgs>;
};

export type Scope<ExtArgs> = {
  parentParams: Omit<NestedParams<ExtArgs>, "query">;
  relations: { to: Prisma.DMMF.Field; from: Prisma.DMMF.Field };
  modifier?: Modifier;
  logicalOperators?: LogicalOperator[];
};

type Modifier = "is" | "isNot" | "some" | "none" | "every";

type LogicalOperator = "AND" | "OR" | "NOT";

type Operation =
  | "create"
  | "createMany"
  | "update"
  | "updateMany"
  | "upsert"
  | "delete"
  | "deleteMany"
  | "where"
  | "include"
  | "select"
  | "connect"
  | "connectOrCreate"
  | "disconnect";

嵌入式写作

这个 $allNestedOperations() 函数为每个 嵌入式写作 在查询中操作。 这个 operation 字段设定为正在执行的操作,例如“创建”或“更新”. 这个 model 字段设定为正在运行的模型,例如“用户”或“后”.

例如,请查询如下:

const result = await client.user.update({
  data: {
    posts: {
      update: {
        where: { id: 1 },
        data: { title: "Hello World" },
      },
    },
  },
});

这个 $allNestedOperations() 函数将调用:

{
  operation: 'update',
  model: 'Post',
  args: {
    where: { id: 1 },
    data: { title: 'Hello World' }
  },
  relations: {
    to: { kind: 'object', name: 'posts', isList: true, ... },
    from: { kind: 'object', name: 'author', isList: false, ... },
  },
  scope: [root params],
}

一些被嵌入的写作可以作为一系列操作来传递. 在这种情况下 $allNestedOperations() 对每个函数都要求 在数组中操作。 例如,请查询如下:

const result = await client.user.update({
  data: {
    posts: {
      update: [
        { where: { id: 1 }, data: { title: "Hello World" } },
        { where: { id: 2 }, data: { title: "Hello World 2" } },
      ],
    },
  },
});

这个 $allNestedOperations() 函数将调用:

 {
  operation: 'update',
  model: 'Post',
  args: {
    where: { id: 1 },
    data: { title: 'Hello World' }
  },
  relations: {
    to: { kind: 'object', name: 'posts', isList: true, ... },
    from: { kind: 'object', name: 'author', isList: false, ... },
  },
  scope: [root params],
}

财务报告和审定财务报表

 {
  operation: 'update',
  model: 'Post',
  args: {
    where: { id: 2 },
    data: { title: 'Hello World 2' }
  },
  relations: {
    to: { kind: 'object', name: 'posts', isList: true, ... },
    from: { kind: 'object', name: 'author', isList: false, ... },
  },
  scope: [root params],
}

更改嵌入式写操作

这个 $allNestedOperations() 函数可以改变模型上的操作。 例如,请查询如下:

const result = await client.user.update({
  data: {
    posts: {
      update: {
        where: { id: 1 }
        data: { title: 'Hello World' }
      },
    },
  },
});

这个 $allNestedOperations() 函数可用于将操作更改为 upsert数字 :

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        $rootOperation: (params) => {
          return params.query(params.args);
        },
        $allNestedOperations: (params) => {
          if (params.model === "Post" && params.operation === "update") {
            return params.query(
              {
                where: params.args.where,
                create: params.args.data,
                update: params.args.data,
              },
              "upsert"
            );
          }
          return params.query(params);
        },
      }),
    },
  },
});

以上将修改最后查询 $allNestedOperations() 改为:

const result = await client.user.update({
  data: {
    posts: {
      upsert: {
        where: { id: 1 },
        create: { title: "Hello World" },
        update: { title: "Hello World" },
      },
    },
  },
});

当改变操作时,操作有可能已经存在. 在这种情况下,由此产生的业务将合并. 例如,请查询如下:

const result = await client.user.update({
  data: {
    posts: {
      update: {
        where: { id: 1 },
        data: { title: "Hello World" },
      },
      upsert: {
        where: { id: 2 },
        create: { title: "Hello World 2" },
        update: { title: "Hello World 2" },
      },
    },
  },
});

使用同样的 $allNestedOperations() 在更新操作改为更新操作之前定义,但有 已经是一个上调操作,所以将两个操作合并为上调操作阵列,并添加到新的操作中 数组的结尾。 当现有的操作已经是操作列表时,新的操作会被添加到结尾 名单 在这种情况下,最后的询问是:

const result = await client.user.update({
  data: {
    posts: {
      upsert: [
        {
          where: { id: 2 },
          create: { title: "Hello World 2" },
          update: { title: "Hello World 2" },
        },
        {
          where: { id: 1 },
          create: { title: "Hello World" },
          update: { title: "Hello World" },
        },
      ],
    },
  },
});

有时无法以这种方式合并操作. 这个 createMany 操作不支持 操作阵列 data 报告 createMany 操作被合并。 例如,请查询如下:

const result = await client.user.create({
  data: {
    posts: {
      createMany: {
        data: [{ title: "Hello World" }, { title: "Hello World 2" }],
      },
      create: {
        title: "Hello World 3",
      },
    },
  },
});

如果 create 操作改为 a createMany 操作 data 字段将添加到现有 createMany 操作。 最后的询问是:

const result = await client.user.create({
  data: {
    posts: {
      createMany: {
        data: [
          { title: "Hello World" },
          { title: "Hello World 2" },
          { title: "Hello World 3" },
        ],
      },
    },
  },
});

也不可能通过为非列表关系创建一系列操作来将操作合并. 对于 示例如下:

const result = await client.user.update({
  data: {
    profile: {
      create: {
        bio: "My personal bio",
        age: 30,
      },
      update: {
        where: { id: 1 },
        data: { bio: "Updated bio" },
      },
    },
  },
});

如果 update 操作改为 a create 使用下列扩展操作:

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        $rootOperation: (params) => {
          return params.query(params.args);
        },
        $allNestedOperations: (params) => {
          if (params.model === "Profile" && params.operation === "update") {
            return params.query(params.args.data, "create");
          }
          return params.query(params);
        },
      }),
    },
  },
});

这个 create 从操作 update 业务需要与现有的 create 业务,但自 profile 不是一个列表关系, 我们必须合并 最终生成的对象 :

const result = await client.user.create({
  data: {
    profile: {
      create: {
        bio: "Updated bio",
        age: 30,
      },
    },
  },
});

写入结果

这个 query 函数 $allNestedOperations() 要求嵌入式写入操作总是返回 undefined 因为他们的结果. 这是因为从根查询中返回的结果可能不包括特定嵌入式写入的数据.

例如,请查询如下:

const result = await client.user.update({
  data: {
    profile: {
      create: {
        bio: "My personal bio",
        age: 30,
      },
    }
    posts: {
      updateMany: {
        where: {
          published: false,
        },
        data: {
          published: true,
        },
      },
    },
  },
  select: {
    id: true,
    posts: {
      where: {
        title: {
          contains: "Hello",
        },
      },
      select: {
        id: true,
      },
    },
  }
});

这个 profile 字段不包含在 select 对象所以结果 create 操作不包含在 根结果。 这个 posts 字段包含在 select 对象但 where 对象仅包含带有 标题中包含“你好”并仅返回“id”字段,在此情况下,无法匹配 updateMany 返回的员额.

见 修改结果 以了解如何更新查询结果的更多信息.

何处

这个 where 操作用于在参数内发现对象的任何关系.

注意 where 操作不用于对象所在的根, 这是因为您需要根操作来知道 何为对象接受的根属性 。 对于巢穴的物体,这不是一个问题,因为他们总是跟随 同样的模式.

看这里 where 操作使用下列查询:

const result = await client.user.findMany({
  where: {
    posts: {
      some: {
        published: true,
      },
    },
  },
});

上面对象产生在对象所在处发现的"后"关系的调用. 这个 modifier 字段设置为 "某"从物体所在"某"字段内.

{
  operation: 'where',
  model: 'Post',
  args: {
    published: true,
  },
  scope: {
    parentParams: {...}
    modifier: 'some',
    relations: {...}
  },
}

在发现和调用And、OR和NOT逻辑运算符时发现的关系 $allNestedOperations() 函数, 不过 where 对逻辑运算符本身不要求操作。 例如,请查询如下:

const result = await client.user.findMany({
  where: {
    posts: {
      some: {
        published: true,
        AND: [
          {
            title: "Hello World",
          },
          {
            comments: {
              every: {
                text: "Great post!",
              },
            },
          },
        ],
      },
    },
  },
});

这个 $allNestedOperations() 函数将使用类似“ post” 的参数调用, 但是它也会被调用 附有下列段落:

{
  operation: 'where',
  model: 'Comment',
  args: {
    text: "Great post!",
  },
  scope: {
    parentParams: {...}
    modifier: 'every',
    logicalOperators: ['AND'],
    relations: {...}
  },
}

由于“注释”关系在“AND”逻辑运算符内找到 要求开展全美行动 这个 modifier 字段设置为“每个”,因为对象位于“每个”字段,并且 页:1 logicalOperators 字段设置为 ['AND'] 因为物体在“AND”逻辑运算符内.

注意到 $allNestedOperations() 函数不为“ AND” 数组中的第一个项目调用, 这是因为第一个项目 不包含任何关系.

这个 logicalOperators 字段跟踪在 parentParams 和当前参数。 对于 示例如下:

const result = await client.user.findMany({
  where: {
    AND: [
      {
        NOT: {
          OR: [
            {
              posts: {
                some: {
                  published: true,
                },
              },
            },
          ],
        },
      },
    ],
  },
});

这个 $allNestedOperations() 函数将调用以下段落:

{
  operation: 'where',
  model: 'Post',
  args: {
    published: true,
  },
  scope: {
    parentParams: {...}
    modifier: 'some',
    logicalOperators: ['AND', 'NOT', 'OR'],
    relations: {...},
  },
}

这个 where 操作也用于在 where 包含和选择区域。 例如:

const result = await client.user.findMany({
  select: {
    posts: {
      where: {
        published: true,
      },
    },
  },
});

这个 $allNestedOperations() 函数将调用以下段落:

{
  operation: 'where',
  model: 'Post',
  args: {
    published: true,
  },
  scope: {...}
}

成果

这个 query a 函数 where 操作总是用 undefined。 。 。 .

包含

这个 include 操作需要包含任何关系。 这个 args 字段将包含对象或布尔 关系。 例如,请查询如下:

const result = await client.user.findMany({
  include: {
    profile: true,
    posts: {
      where: {
        published: true,
      },
    },
  },
});

对于"相片"关系 $allNestedOperations() 函数将调用:

{
  operation: 'include',
  model: 'Profile',
  args: true,
  scope: {...}
}

而对于"后"关系 $allNestedOperations() 函数将调用:

{
  operation: 'include',
  model: 'Post',
  args: {
    where: {
      published: true,
    },
  },
  scope: {...}
}

包含结果

这个 query 函数 include 操作结果 include 操作。 举个例子 查询如下:

const result = await client.user.findMany({
  include: {
    profile: true,
  },
});

这个 $allNestedOperations() 用于“ profile” 关系的函数将调用:

{
  operation: 'include',
  model: 'Profile',
  args: true,
  scope: {...}
}

还有 query 函数将随 include 操作,在这种情况下,诸如:

{
  id: 2,
  bio: 'My personal bio',
  age: 30,
  userId: 1,
}

对于被列入父母结果清单的关系 query 函数将用平整的阵列解决 每一个母公司的所有模型的结果。 例如,请查询如下:

const result = await client.user.findMany({
  include: {
    posts: true,
  },
});

如果根结果看起来像如下:

[
  {
    id: 1,
    name: "Alice",
    posts: [
      {
        id: 1,
        title: "Hello World",
        published: false,
        userId: 1,
      },
      {
        id: 2,
        title: "My first published post",
        published: true,
        userId: 1,
      },
    ],
  },
  {
    id: 2,
    name: "Bob",
    posts: [
      {
        id: 3,
        title: "Clean Code",
        published: true,
        userId: 2,
      },
    ],
  },
];

这个 query 函数用于“ posts” 关系,将解决以下问题:

[
  {
    id: 1,
    title: "Hello World",
    published: false,
    userId: 1,
  },
  {
    id: 2,
    title: "My first published post",
    published: true,
    userId: 1,
  },
  {
    id: 3,
    title: "Clean Code",
    published: true,
    userId: 2,
  },
];

欲了解更多关于如何修改一项公约的结果的信息 include 操作参见 修改结果

选择

与 include 操作 select 操作将被调用到与 args 字段 中包含对象或布尔随关系选择而通过。 例如,请查询如下:

const result = await client.user.findMany({
  select: {
    posts: true,
    profile: {
      select: {
        bio: true,
      },
    },
  },
});

而对于"后"关系 $allNestedOperations() 函数将调用:

{
  operation: 'select',
  model: 'Post',
  args: true,
  scope: {...}
}

对于"相片"关系 $allNestedOperations() 函数将调用:

{
  operation: 'select',
  model: 'Profile',
  args: {
    bio: true,
  },
  scope: {...}
}

选择结果

这个 query a 函数 select 操作结果 select 操作。 这跟那个一样 include 操作。 见 包含结果 用于提供更多信息.

关系

这个 relations 报告 scope 对象包含与当前模型相关的关系。 举个例子 查询如下:

const result = await client.user.create({
  data: {
    email: "[email protected]",
    profile: {
      create: {
        bio: "Hello World",
      },
    },
    posts: {
      create: {
        title: "Hello World",
      },
    },
  },
});

这个 $allNestedOperations() 函数将调用“ profile” 关系的下列参数:

{
  operation: 'create',
  model: 'Profile',
  args: {
    bio: "Hello World",
  },
  scope: {
    parentParams: {...}
    relations: {
      to: { name: 'profile', kind: 'object', isList: false, ... },
      from: { name: 'user', kind: 'object', isList: false, ... },
    },
  },
}

和以下关于“邮政”关系的段落:

{
  operation: 'create',
  model: 'Post',
  args: {
    title: "Hello World",
  },
  scope: {
    parentParams: {...}
    relations: {
      to: { name: 'posts', kind: 'object', isList: true, ... },
      from: { name: 'author', kind: 'object', isList: false, ... },
    },
  },
}

修改嵌入式书写参数

当写入修改查询参数的扩展名时, 您应该首先写入 $rootOperation() 像钩子一样 a 一个 $allOperations() 钩子,然后添加 $allNestedOperations() 钩.

假设您在为特定模型创建模型时正在写入设置默认值的中间软件:

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          // we only want to add default values for the "Invite" model
          if (params.model !== "Invite") {
            return params.query(params.args);
          }

          if (params.operation === "create" && !params.args.data.code) {
            params.args.data.code = createCode();
          }

          if (params.operation === "upsert" && !params.args.create.code) {
            params.args.create.code = createCode();
          }

          if (params.operation === "createMany") {
            params.args.data.forEach((data) => {
              if (!data.code) {
                data.code = createCode();
              }
            });
          }

          return params.query(params.args);
        },
        async $allNestedOperations(params) {
          return params.query(params.args);
        },
      }),
    },
  },
});

然后加入在巢中可以找到的不同参数和操作的条件:

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          [...]
        },
        async $allNestedOperations(params) {
          // we only want to add default values for the "Invite" model
          if (params.model !== "Invite") {
            return params.query(params.args);
          }

          // when the "create" operation is from a nested write the data is not in the "data" field
          if (params.operation === "create" && !params.args.code) {
            params.args.code = createCode();
          }

          // handle the "connectOrCreate" operation
          if (params.operation === "connectOrCreate" && !params.args.create.code) {
            params.args.create.code = createCode();
          }

          // pass args to query
          return params.query(params.args);
        },
      }),
    },
  },
});

修改参数位置

当写入修改查询参数的扩展时, 您应当首先写入 $rootOperation() 钩为 如果它是一个 $allOperations() 钩子,这是因为 where 操作不用于对象所在的根, 因此您 需要手动处理.

假设你正在写一个扩展, 排除模型与特定的领域, 让我们称之为"隐形"而不是 "取出"使这更不熟悉:

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          // don't handle operations that only accept unique fields such as findUnique or upsert
          if (
            params.operation === "findFirst" ||
            params.operation === "findFirstOrThrow" ||
            params.operation === "findMany" ||
            params.operation === "updateMany" ||
            params.operation === "deleteMany" ||
            params.operation === "count" ||
            params.operation === "aggregate"
          ) {
            return params.query({
              ...params.args,
              where: {
                ...params.args.where,
                invisible: false,
              },
            });
          }

          return params.query(params.args);
        },
        async $allNestedOperations(params) {
          return params.query(params.args);
        },
      }),
    },
  },
});

然后添加条件 where 操作 :

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          [...]
        },
        async $allNestedOperations(params) {
          // handle the "where" operation
          if (params.operation === "where") {
            return params.query({
              ...params.args,
              invisible: false,
            });
          }

          return params.query(params.args);
        },
      }),
    },
  },
});

修改结果

在写入修改查询结果的扩展名时,您应当遵循以下程序:

  • 处理 $rootOperation() 钩一样,你会与一个 $allOperations() 钩.
  • 使用 include 财务报告和审定财务报表 select 业务活动 $allNestedOperations() 钩.

说你正在写中间软件 给查询结果添加了时间戳 你将首先处理根源案件:

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          const result = await params.query(params.args);

          // ensure result is defined
          if (!result) return result;

          // handle root operations
          if (
            params.operation === "findFirst" ||
            params.operation === "findFirstOrThrow" ||
            params.operation === "findUnique" ||
            params.operation === "findUniqueOrThrow" ||
            params.operation === "create" ||
            params.operation === "update" ||
            params.operation === "upsert" ||
            params.operation === "delete"
          ) {
            result.timestamp = Date.now();
            return result;
          }

          if (params.operation === "findMany") {
            const result = await params.query(params.args);
            result.forEach((model) => {
              model.timestamp = Date.now();
            });
            return result;
          }

          return result;
        },
        async $allNestedOperations(params) {
          return params.query(params.args);
        },
      }),
    },
  },
});

然后,你会处理 巢的结果使用 include 财务报告和审定财务报表 select 操作 :

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          [...]
        },
        async $allNestedOperations(params) {
          const result = await next(params);

          // ensure result is defined
          if (!result) return result;

          // handle nested operations
          if (params.operation === "include" || params.operation === "select") {
            if (Array.isArray(result)) {
              result.forEach((model) => {
                model.timestamp = Date.now();
              });
            } else {
              result.timestamp = Date.now();
            }
            return result;
          }

          return result;
        },
      }),
    },
  },
});

您也可以通过为每个结果创建新对象来写入上面的中间软件,而不是改变现有的 对象 :

const client = _client.$extends({
  query: {
    $allModels: {
      $allOperations: withNestedOperations({
        dmmf: Prisma.dmmf,
        inlineSchema: (client as any)._engineConfig?.inlineSchema,
        async $rootOperation(params) {
          [...]
        },
        async $allNestedOperations(params) {
          const result = await next(params);

          // ensure result is defined
          if (!result) return result;

          // handle nested operations
          if (params.operation === "include" || params.operation === "select") {
            if (Array.isArray(result)) {
              return result.map((model) => ({
                ...model,
                timestamp: Date.now(),
              });
            }

            return {
              ...result,
              timestamp: Date.now(),
            };
          }

          return result;
        },
      }),
    },
  },
});

注:当修改结果来自 include 或者说 select 操作中必须变换现有对象或 将已有对象扩展为新对象。 这是因为 createNestedMiddleware 需要从 原始对象以修正更新根结果.

错误

如果任何中间软件在任何一点投出出出错,则根查询会随该出错一起投出. 任何中间软件 等待会让承诺在那时遭到拒绝.

自由主义

Apache 2.0 (英语)

版本与发布记录

@candoimage/prisma-extension-nested-operations 共发布 5 个版本,首次发布于 2026/03/02;过去 12 个月发布了 5 个版本。

版本发布日期距今
1.6.4latest2026/03/307 个月前
1.6.32026/03/028 个月前
1.6.22026/03/028 个月前
1.6.12026/03/028 个月前
1.6.02026/03/028 个月前

关于 @candoimage/prisma-extension-nested-operations 的常见问题

@candoimage/prisma-extension-nested-operations 是什么?

用于创建带有嵌入操作的 Prisma 客户端扩展的 Utils

如何安装 @candoimage/prisma-extension-nested-operations?

在项目目录运行 npm install @candoimage/prisma-extension-nested-operations,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@prisma/client(>=7.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@candoimage/prisma-extension-nested-operations 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@candoimage/prisma-extension-nested-operations 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@candoimage/prisma-extension-nested-operations 可以商用吗?

@candoimage/prisma-extension-nested-operations 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@candoimage/prisma-extension-nested-operations 的下载量有多少?

根据 npm 官方下载统计,@candoimage/prisma-extension-nested-operations 在 2026/10/09 – 2026/11/07 这 30 天内被下载 22,244 次,日均约 741 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@candoimage/prisma-extension-nested-operations 还在维护吗?

最新版本 1.6.4 发布于 2026/03/30(7 个月前);至今共发布 5 个版本,其中过去 12 个月发布了 5 个;首次发布于 2026/03/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。