diff --git a/eslint.config.js b/eslint.config.js index 69130fd..5f717bb 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -18,5 +18,16 @@ export default tseslint.config( }, }, ...layerRules, + // domain is bundled into the browser with web: Node-only globals break there at runtime, not in Vitest (Node). + { + files: ['src/domain/**/*.ts', 'src/web/**/*.{ts,tsx}'], + ignores: ['**/*.test.{ts,tsx}'], + rules: { + 'no-restricted-globals': ['error', + { name: 'Buffer', message: 'Not in the browser: use TextEncoder/TextDecoder.' }, + { name: 'process', message: 'Not in the browser.' }, + ], + }, + }, { files: ['*.config.js'], ...tseslint.configs.disableTypeChecked }, ); diff --git a/src/domain/workflow-function.ts b/src/domain/workflow-function.ts index 9a0040a..670cda6 100644 --- a/src/domain/workflow-function.ts +++ b/src/domain/workflow-function.ts @@ -43,7 +43,7 @@ export type FunctionTestCase = z.infer; export const WorkflowFunctionDocumentV1 = z.object({ schemaVersion: z.literal(1), language: z.enum(['typescript', 'posix']), - source: z.string().min(1).refine((value) => !value.includes('\0'), 'source cannot contain NUL').refine((value) => Buffer.byteLength(value, 'utf8') <= FUNCTION_MAX_SOURCE_BYTES, 'source is too large'), + source: z.string().min(1).refine((value) => !value.includes('\0'), 'source cannot contain NUL').refine((value) => new TextEncoder().encode(value).length <= FUNCTION_MAX_SOURCE_BYTES, 'source is too large'), capabilities: FunctionCapabilitySetV1, cases: z.array(FunctionTestCase).min(1).max(FUNCTION_MAX_CASES), }).strict().superRefine((document, context) => {