refactor(core): Move node type policy DTOs to @n8n/api-types (#38238)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Rúben Castro 2026-09-10 11:52:25 +00:00 committed by GitHub
parent 0380ffccfd
commit ef77996df1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 82 additions and 41 deletions

View File

@ -236,6 +236,27 @@ export {
} from './log-streaming/public-destination.dto';
export { PaginationDto, MAX_ITEMS_PER_PAGE } from './pagination/pagination.dto';
export type {
NonDelegatingPolicyAction,
NonDelegatingPolicyRule,
PolicyAction,
PolicyRule,
PolicySelector,
} from './node-type-policies/policy-rule.types';
export { policySelectorSchema } from './node-type-policies/policy-selector.schema';
export {
nonDelegatingPolicyActionSchema,
nonDelegatingPolicyRuleListSchema,
policyActionSchema,
policyRuleListSchema,
policyRuleSchema,
} from './node-type-policies/policy-rule.schema';
export { PutInstancePolicyDto } from './node-type-policies/put-instance-policy.dto';
export { PutProjectPolicyDto } from './node-type-policies/put-project-policy.dto';
export { CreatePolicyDocumentDto } from './node-type-policies/create-policy-document.dto';
export { UpdatePolicyDocumentDto } from './node-type-policies/update-policy-document.dto';
export { ReplaceAttachmentsDto } from './node-type-policies/replace-attachments.dto';
export {
UsersListFilterDto,
type UsersListSortOptions,

View File

@ -1,6 +1,5 @@
import { Z } from '@n8n/api-types';
import { policyRuleListSchema } from './policy-rule.schema';
import { Z } from '../../zod-class';
/** Request body for creating a policy document. */
export class CreatePolicyDocumentDto extends Z.class({

View File

@ -5,11 +5,11 @@ import type {
NonDelegatingPolicyRule,
PolicyAction,
PolicyRule,
} from '../policy-rule.types';
} from './policy-rule.types';
import { policySelectorSchema } from './policy-selector.schema';
/**
* Zod counterpart of `PolicyAction` in `../policy-rule.types.ts`. The `satisfies` check
* Zod counterpart of `PolicyAction` in `./policy-rule.types.ts`. The `satisfies` check
* keeps this schema honest against that type.
*/
export const policyActionSchema = z.enum([
@ -19,7 +19,7 @@ export const policyActionSchema = z.enum([
]) satisfies z.ZodType<PolicyAction>;
/**
* Zod counterpart of `PolicyRule` in `../policy-rule.types.ts`. The `satisfies` check
* Zod counterpart of `PolicyRule` in `./policy-rule.types.ts`. The `satisfies` check
* keeps this schema honest against that type.
*/
export const policyRuleSchema = z.object({

View File

@ -0,0 +1,29 @@
/**
* Domain types for node type availability policies, shared by the internal and public API
* request DTOs and by the backend evaluator.
*/
/** Matches a node type by its exact full name, or by its package segment. */
export type PolicySelector =
| { readonly kind: 'name'; readonly value: string }
| { readonly kind: 'package'; readonly value: string };
export type PolicyAction = 'allow' | 'deny' | 'delegate';
/** One first-match rule within a policy document, in document order. */
export type PolicyRule = {
readonly id: string;
readonly action: PolicyAction;
readonly selector: PolicySelector;
};
/**
* The actions a project scope accepts. `delegate` defers to a narrower scope, and none exists
* below project, so project-scope writes never accept it.
*/
export type NonDelegatingPolicyAction = Exclude<PolicyAction, 'delegate'>;
/** A `PolicyRule` as a project scope accepts it. */
export type NonDelegatingPolicyRule = Omit<PolicyRule, 'action'> & {
readonly action: NonDelegatingPolicyAction;
};

View File

@ -1,9 +1,9 @@
import { z } from 'zod';
import type { PolicySelector } from '../policy-rule.types';
import type { PolicySelector } from './policy-rule.types';
/**
* Zod counterpart of `PolicySelector` in `../policy-rule.types.ts`. The `satisfies` check
* Zod counterpart of `PolicySelector` in `./policy-rule.types.ts`. The `satisfies` check
* keeps this schema honest against that type — it fails to compile if this schema ever
* accepts a shape `PolicySelector` doesn't.
*/

View File

@ -1,7 +1,7 @@
import { Z } from '@n8n/api-types';
import { z } from 'zod';
import { policyActionSchema, policyRuleListSchema } from './policy-rule.schema';
import { Z } from '../../zod-class';
/** Request body for setting the composed instance policy. */
export class PutInstancePolicyDto extends Z.class({

View File

@ -1,10 +1,10 @@
import { Z } from '@n8n/api-types';
import { z } from 'zod';
import {
nonDelegatingPolicyActionSchema,
nonDelegatingPolicyRuleListSchema,
} from './policy-rule.schema';
import { Z } from '../../zod-class';
/**
* Request body for setting a project's composed policy. Same shape as

View File

@ -1,6 +1,7 @@
import { Z } from '@n8n/api-types';
import { z } from 'zod';
import { Z } from '../../zod-class';
const policyAttachmentInputSchema = z.object({
policyId: z.string().min(1),
priority: z.number().int(),

View File

@ -1,7 +1,7 @@
import { Z } from '@n8n/api-types';
import { z } from 'zod';
import { policyRuleListSchema } from './policy-rule.schema';
import { Z } from '../../zod-class';
/** Request body for replacing a policy document's rules. */
export class UpdatePolicyDocumentDto extends Z.class({

View File

@ -1,35 +1,24 @@
/**
* Domain types for node type availability policies.
*
* The rule/selector/action shapes live in `@n8n/api-types` so the public and internal request
* DTOs share them; they are re-exported here so the module keeps one import path. The types
* below are backend-only.
*
* Deliberately independent of the `policy`/`policy_scope`/`policy_attachment` TypeORM
* entities (not yet built) — the repository layer will map DB rows into these shapes so
* the evaluator never depends on the persistence layer.
* entities — the repository layer maps DB rows into these shapes so the evaluator never
* depends on the persistence layer.
*/
/** Matches a node type by its exact full name, or by its package segment. */
export type PolicySelector =
| { readonly kind: 'name'; readonly value: string }
| { readonly kind: 'package'; readonly value: string };
import type { PolicyAction, PolicyRule } from '@n8n/api-types';
export type PolicyAction = 'allow' | 'deny' | 'delegate';
/** One first-match rule within a policy document, in document order. */
export type PolicyRule = {
readonly id: string;
readonly action: PolicyAction;
readonly selector: PolicySelector;
};
/**
* The actions a project scope accepts. `delegate` defers to a narrower scope, and none exists
* below project, so project-scope writes never accept it.
*/
export type NonDelegatingPolicyAction = Exclude<PolicyAction, 'delegate'>;
/** A `PolicyRule` as a project scope accepts it. */
export type NonDelegatingPolicyRule = Omit<PolicyRule, 'action'> & {
readonly action: NonDelegatingPolicyAction;
};
export type {
NonDelegatingPolicyAction,
NonDelegatingPolicyRule,
PolicyAction,
PolicyRule,
PolicySelector,
} from '@n8n/api-types';
/** One policy document as attached to a scope, with its evaluation-order metadata. */
export type PolicyAttachment = {

View File

@ -1,3 +1,9 @@
import {
CreatePolicyDocumentDto,
PutInstancePolicyDto,
ReplaceAttachmentsDto,
UpdatePolicyDocumentDto,
} from '@n8n/api-types';
import { LICENSE_FEATURES } from '@n8n/constants';
import { AuthenticatedRequest } from '@n8n/db';
import {
@ -17,10 +23,6 @@ import type { Response } from 'express';
import { NotFoundError } from '@/errors/response-errors/not-found.error';
import { NODE_TYPES_KIND } from './constants';
import { CreatePolicyDocumentDto } from './dto/create-policy-document.dto';
import { PutInstancePolicyDto } from './dto/put-instance-policy.dto';
import { ReplaceAttachmentsDto } from './dto/replace-attachments.dto';
import { UpdatePolicyDocumentDto } from './dto/update-policy-document.dto';
import { TypeAvailabilityPolicyService } from './type-availability-policy.service';
/**

View File

@ -1,10 +1,10 @@
import { PutProjectPolicyDto } from '@n8n/api-types';
import { LICENSE_FEATURES } from '@n8n/constants';
import { AuthenticatedRequest } from '@n8n/db';
import { Body, Get, Licensed, ProjectScope, Put, RestController } from '@n8n/decorators';
import type { Response } from 'express';
import { NODE_TYPES_KIND } from './constants';
import { PutProjectPolicyDto } from './dto/put-project-policy.dto';
import { TypeAvailabilityPolicyService } from './type-availability-policy.service';
/**