@tailor-platform/sdk 2.18.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/{application-DEkgf2w1.mjs → application-BYlhYQyh.mjs} +2 -2
- package/dist/{application-DEkgf2w1.mjs.map → application-BYlhYQyh.mjs.map} +1 -1
- package/dist/application-KZRJHv2j.mjs +1 -0
- package/dist/cli/commands/deploy/event-subscriptions.d.mts +1 -0
- package/dist/cli/commands/generate/service.d.mts +1 -0
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/main.mjs +3 -3
- package/dist/cli/services/executor/service.d.mts +1 -0
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/configure/index.d.mts +7 -7
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/types/field.types.d.mts +24 -4
- package/dist/configure/types/type.d.mts +1 -0
- package/dist/date-B7-oyTGE.mjs +2 -0
- package/dist/date-B7-oyTGE.mjs.map +1 -0
- package/dist/field-parse-BbNyotv5.mjs +2 -0
- package/dist/field-parse-BbNyotv5.mjs.map +1 -0
- package/dist/{manager-C26Gi1bX.mjs → manager-qfbUL7ru.mjs} +2 -2
- package/dist/{manager-C26Gi1bX.mjs.map → manager-qfbUL7ru.mjs.map} +1 -1
- package/dist/parser/service/auth/schema.d.mts +1 -0
- package/dist/plugin/index.mjs +1 -1
- package/dist/{register-ts-hook-BD3ArLqY.mjs → register-ts-hook-Djjnj5R8.mjs} +3 -3
- package/dist/{register-ts-hook-BD3ArLqY.mjs.map → register-ts-hook-Djjnj5R8.mjs.map} +1 -1
- package/dist/runtime/date.d.mts +3 -3
- package/dist/runtime/field-parse.d.mts +1 -0
- package/dist/runtime/index.d.mts +2 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/temporal.d.mts +31 -0
- package/dist/{schema-DRyQEabV.mjs → schema-BKvcWdVf.mjs} +2 -2
- package/dist/{schema-DRyQEabV.mjs.map → schema-BKvcWdVf.mjs.map} +1 -1
- package/dist/service-BgrEteZ2.mjs +1 -0
- package/dist/service-CuqkHP1r.mjs +7 -0
- package/dist/service-CuqkHP1r.mjs.map +1 -0
- package/dist/types/field.generated.d.mts +1 -1
- package/dist/types/helpers.d.mts +8 -6
- package/dist/utils/test/index.mjs +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/environment.mjs.map +1 -1
- package/docs/github-actions.md +22 -15
- package/docs/migration/v3.md +0 -33
- package/docs/services/resolver.md +53 -1
- package/docs/testing.md +17 -0
- package/package.json +5 -3
- package/dist/application-Dl94fzpm.mjs +0 -1
- package/dist/date-CGBZbMW5.mjs +0 -2
- package/dist/date-CGBZbMW5.mjs.map +0 -1
- package/dist/field-parse-CzlKC4b7.mjs +0 -2
- package/dist/field-parse-CzlKC4b7.mjs.map +0 -1
- package/dist/service-B3OiWCYg.mjs +0 -1
- package/dist/service-eM7Fd8zS.mjs +0 -7
- package/dist/service-eM7Fd8zS.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-CuqkHP1r.mjs","names":["AllowedValueSchema"],"sources":["../src/parser/service/common.ts","../src/cli/shared/user-modules.ts","../src/cli/services/file-loader.ts","../src/parser/service/field-types.ts","../src/parser/service/tailordb/relation.ts","../src/parser/service/tailordb/schema.ts","../src/parser/service/tailordb/builder-helpers.ts","../src/parser/service/auth-connection/schema.ts","../src/parser/service/field/schema.ts","../src/parser/service/auth/schema.ts","../src/parser/service/executor/schema.ts","../src/cli/services/executor/loader.ts","../src/cli/services/executor/service.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// Use `z.custom` instead of `z.function`, since `z.function` changes `toString` representation.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const functionSchema: z.ZodType<Function, Function> = z.custom<Function>(\n (val) => typeof val === \"function\",\n);\n","import { pathToFileURL } from \"node:url\";\n\nexport const IMPORT_NONCE_PARAM = \"tailorImportNonce\";\n\nlet runCounter = 0;\n\n/**\n * Start a fresh user-module run. Modules imported through\n * {@link importUserModule} after this call bypass the ESM cache entries of\n * earlier runs, so a repeated in-process run re-evaluates user code instead\n * of reusing stale modules.\n */\nexport function beginUserModuleRun(): void {\n runCounter += 1;\n}\n\n/**\n * Read the cache-busting nonce of the current user-module run.\n * @returns The nonce, or undefined when no run was started\n */\nexport function currentImportNonce(): string | undefined {\n return runCounter === 0 ? undefined : String(runCounter);\n}\n\n/**\n * Import a user module (config, workflow, resolver, executor, ...) with the\n * current run's cache-busting nonce applied. Outside a run this is a plain\n * import.\n * @param filePath - Absolute path of the user module\n * @returns The imported module namespace\n */\nexport function importUserModule(filePath: string): Promise<Record<string, unknown>> {\n const url = pathToFileURL(filePath);\n const nonce = currentImportNonce();\n if (nonce) {\n url.searchParams.set(IMPORT_NONCE_PARAM, nonce);\n }\n return import(url.href);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { logger } from \"#/cli/shared/logger\";\n\nexport interface FileLoadConfig {\n files: string[];\n ignores?: string[];\n}\n\nconst DEFAULT_IGNORE_PATTERNS = [\"**/*.test.ts\", \"**/*.spec.ts\"];\n\n// loadFilesWithIgnores is called once per service/bundler, so a single\n// generate/apply run can call it multiple times for the same baseDir (once\n// per resolver/executor/tailordb/etc. config sharing that directory). Track\n// which (baseDir, patterns) pairs have already warned so each one only warns\n// once per run — keyed by patterns too, since different services sharing a\n// baseDir can have different `files` patterns each needing their own warning.\nconst warnedFallbacks = new Set<string>();\n\n/**\n * Load files matching the given patterns, excluding files that match ignore patterns.\n * By default, test files (*.test.ts, *.spec.ts) are excluded unless ignores is explicitly specified.\n * @param config - Configuration with files patterns and optional ignores patterns\n * @param baseDir - Directory relative patterns are resolved against\n * @returns Array of absolute file paths\n */\nexport function loadFilesWithIgnores(config: FileLoadConfig, baseDir: string): string[] {\n if (config.files.length === 0) {\n return [];\n }\n\n const resolved = resolveFiles(config, baseDir);\n const allPatternsAbsolute = config.files.every((pattern) => path.isAbsolute(pattern));\n if (resolved.matchedAnyPattern || baseDir === process.cwd() || allPatternsAbsolute) {\n return resolved.files;\n }\n\n // v1 compatibility fallback: pre-existing configs may have relative\n // patterns written against the invocation cwd rather than baseDir. Only\n // triggers when baseDir's patterns matched nothing at all (not merely\n // \"matched, but every hit got filtered out by ignores\") — otherwise this\n // fallback would reintroduce the same cross-app file bleed this baseDir\n // resolution is meant to prevent. Also skipped when every pattern is\n // already absolute, since baseDir can't change an absolute pattern's\n // resolution — re-running against cwd would just repeat the same glob.\n // Remove this fallback in v2, once such configs are expected to have\n // migrated.\n const fallbackKey = `${baseDir}\\0${config.files.join(\"\\0\")}`;\n if (!warnedFallbacks.has(fallbackKey)) {\n warnedFallbacks.add(fallbackKey);\n logger.warn(\n `No files matched \"${config.files.join(\", \")}\" relative to \"${baseDir}\"; falling back to ` +\n `process.cwd(). Update this config's file patterns to be relative to its own directory ` +\n `before v2, when this fallback will be removed.`,\n );\n }\n return resolveFiles(config, process.cwd()).files;\n}\n\ninterface ResolvedFiles {\n files: string[];\n /** Whether any `files` pattern matched anything under baseDir, before ignore filtering. */\n matchedAnyPattern: boolean;\n}\n\nfunction resolveFiles(config: FileLoadConfig, baseDir: string): ResolvedFiles {\n // Use user-provided patterns if specified, otherwise use defaults. Default\n // patterns are left unanchored (\"**/*.test.ts\") so they match a test file\n // regardless of which directory a `files` pattern's matches actually came\n // from — this matters when a pattern is absolute or otherwise escapes\n // baseDir. User-provided patterns are baseDir-relative, matching `files`.\n const isDefaultIgnores = config.ignores === undefined;\n const ignorePatterns = config.ignores ?? DEFAULT_IGNORE_PATTERNS;\n const resolvedIgnorePatterns = isDefaultIgnores\n ? ignorePatterns\n : ignorePatterns.map((ignorePattern) => path.resolve(baseDir, ignorePattern));\n\n const files: string[] = [];\n let matchedAnyPattern = false;\n for (const pattern of config.files) {\n const absolutePattern = path.resolve(baseDir, pattern);\n try {\n const matchedFiles = fs.globSync(absolutePattern);\n if (matchedFiles.length > 0) {\n matchedAnyPattern = true;\n }\n // Filter out ignored files\n const filteredFiles = matchedFiles.filter(\n (file) =>\n !resolvedIgnorePatterns.some((ignorePattern) => path.matchesGlob(file, ignorePattern)),\n );\n files.push(...filteredFiles);\n } catch (error) {\n // A glob failure means we don't know whether baseDir has matching\n // files, not that it has none — treat it as a match so it can't\n // trigger the v1 compatibility fallback below.\n matchedAnyPattern = true;\n logger.warn(`Failed to glob pattern \"${pattern}\": ${String(error)}`);\n }\n }\n\n return { files, matchedAnyPattern };\n}\n","import { z } from \"zod\";\nimport type { TailorFieldType } from \"#/configure/types/field.types\";\nimport type { UnionToTuple } from \"type-fest\";\n\nconst tailorFieldTypes: Record<TailorFieldType, true> = {\n uuid: true,\n string: true,\n boolean: true,\n integer: true,\n float: true,\n decimal: true,\n enum: true,\n date: true,\n datetime: true,\n time: true,\n nested: true,\n};\n\nconst tailorFieldTypeKeys = Object.keys(tailorFieldTypes) as UnionToTuple<TailorFieldType>;\n\nexport const TailorFieldTypeSchema = z.enum(tailorFieldTypeKeys);\n","import type { RawRelationConfig } from \"#/configure/services/tailordb/types\";\nimport type { OperatorFieldConfig } from \"#/parser/service/tailordb/types\";\nimport type { UnionToTuple } from \"type-fest\";\n\nconst relationTypes = {\n \"1-1\": \"1-1\",\n oneToOne: \"1-1\",\n \"n-1\": \"n-1\",\n manyToOne: \"n-1\",\n \"N-1\": \"n-1\",\n keyOnly: \"keyOnly\",\n} as const;\nexport const relationTypesKeys = Object.keys(relationTypes) as UnionToTuple<\n keyof typeof relationTypes\n>;\n\nexport interface RelationProcessingContext {\n tableName: string;\n fieldName: string;\n allTableNames: Set<string>;\n}\n\nexport interface ProcessedRelationMetadata {\n index: boolean;\n foreignKey: boolean;\n relationType: string;\n unique: boolean;\n foreignKeyType: string;\n foreignKeyField: string;\n}\n\nexport interface RelationInfo {\n targetType: string;\n forwardName: string;\n backwardName: string;\n key: string;\n unique: boolean;\n}\n\nfunction fieldRef(context: RelationProcessingContext): string {\n return `Field \"${context.fieldName}\" on table \"${context.tableName}\"`;\n}\n\n/**\n * Validate relation configuration.\n * @param rawRelation - Raw relation configuration from TailorDB table definition\n * @param context - Context information for the relation (table name, field name, all type names)\n */\nexport function validateRelationConfig(\n rawRelation: RawRelationConfig,\n context: RelationProcessingContext,\n): void {\n // raw user config may omit the field\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!rawRelation.type) {\n throw new Error(\n `${fieldRef(context)} has a relation but is missing the required 'type' property. ` +\n `Valid values: ${relationTypesKeys.join(\", \")}.`,\n );\n }\n if (!(rawRelation.type in relationTypes)) {\n throw new Error(\n `${fieldRef(context)} has invalid relation type '${rawRelation.type}'. ` +\n `Valid values: ${relationTypesKeys.join(\", \")}.`,\n );\n }\n\n // Validate target table exists (for non-self relations)\n if (rawRelation.toward.table !== \"self\" && !context.allTableNames.has(rawRelation.toward.table)) {\n throw new Error(`${fieldRef(context)} references unknown table \"${rawRelation.toward.table}\".`);\n }\n}\n\n/**\n * Process raw relation config and compute derived metadata values.\n * @param rawRelation - Raw relation configuration\n * @param context - Context information for the relation\n * @param isArrayField - Whether the target field is an array field\n * @returns Computed relation metadata to apply to field config\n */\nexport function processRelationMetadata(\n rawRelation: RawRelationConfig,\n context: RelationProcessingContext,\n isArrayField: boolean = false,\n): ProcessedRelationMetadata {\n const isUnique = relationTypes[rawRelation.type] === \"1-1\";\n const key = rawRelation.toward.key ?? \"id\";\n\n // Resolve target table name (handle \"self\" reference)\n const targetTypeName =\n rawRelation.toward.table === \"self\" ? context.tableName : rawRelation.toward.table;\n\n // Index and unique are not supported on array fields\n const shouldSetIndex = !isArrayField;\n const shouldSetUnique = !isArrayField && isUnique;\n\n return {\n index: shouldSetIndex,\n foreignKey: true,\n relationType: rawRelation.type,\n unique: shouldSetUnique,\n foreignKeyType: targetTypeName,\n foreignKeyField: key,\n };\n}\n\n/**\n * Build relation info for creating forward/backward relationships.\n * Returns undefined for keyOnly relations.\n * @param rawRelation - Raw relation configuration\n * @param context - Context information for the relation\n * @returns Relation information or undefined for keyOnly relations\n */\nexport function buildRelationInfo(\n rawRelation: RawRelationConfig,\n context: RelationProcessingContext,\n): RelationInfo | undefined {\n // keyOnly relations don't create forward/backward relationships\n if (rawRelation.type === \"keyOnly\") {\n return undefined;\n }\n\n const isUnique = relationTypes[rawRelation.type] === \"1-1\";\n const key = rawRelation.toward.key ?? \"id\";\n\n // Resolve target table name (handle \"self\" reference)\n const targetTypeName =\n rawRelation.toward.table === \"self\" ? context.tableName : rawRelation.toward.table;\n\n let forwardName = rawRelation.toward.as;\n if (!forwardName) {\n forwardName = context.fieldName.replace(/(ID|Id|id)$/u, \"\");\n }\n\n return {\n targetType: targetTypeName,\n forwardName,\n backwardName: rawRelation.backward ?? \"\",\n key,\n unique: isUnique,\n };\n}\n\n/**\n * Apply processed relation metadata to field config.\n * @param fieldConfig - Original operator field configuration\n * @param metadata - Processed relation metadata to apply\n * @returns Field config with relation metadata applied\n */\nexport function applyRelationMetadataToFieldConfig(\n fieldConfig: OperatorFieldConfig,\n metadata: ProcessedRelationMetadata,\n): OperatorFieldConfig {\n return {\n ...fieldConfig,\n index: metadata.index,\n foreignKey: metadata.foreignKey,\n unique: metadata.unique,\n foreignKeyType: metadata.foreignKeyType,\n foreignKeyField: metadata.foreignKeyField,\n };\n}\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\nimport { TailorFieldTypeSchema } from \"../field-types\";\nimport { relationTypesKeys } from \"./relation\";\nimport type { TailorDBFieldOutput } from \"#/parser/service/tailordb/types\";\n\n/**\n * Normalize GqlOperationsConfig (alias or object) to GqlOperations object.\n * \"query\" alias expands to read-only mode: { create: false, update: false, delete: false, read: true }\n * @param config - The config to normalize\n * @returns The normalized GqlOperations object\n */\nfunction normalizeGqlOperations(\n config: \"query\" | { create?: boolean; update?: boolean; delete?: boolean; read?: boolean },\n) {\n if (config === \"query\") {\n return { create: false, update: false, delete: false, read: true };\n }\n return config;\n}\n\n/**\n * Zod schema for GqlOperations configuration with normalization transform.\n * Accepts \"query\" alias or detailed object, normalizes to GqlOperations object.\n */\nexport const GqlOperationsSchema = z\n .union([\n z.literal(\"query\"),\n z.strictObject({\n create: z.boolean().optional().describe(\"Enable create mutation (default: true)\"),\n update: z.boolean().optional().describe(\"Enable update mutation (default: true)\"),\n delete: z.boolean().optional().describe(\"Enable delete mutation (default: true)\"),\n read: z\n .boolean()\n .optional()\n .describe(\"Enable read queries - get, list, aggregation (default: true)\"),\n }),\n ])\n .describe(\n \"Configuration for GraphQL operations on a TailorDB table.\\nAll operations are enabled by default (undefined or true = enabled, false = disabled).\",\n )\n .transform((val) => normalizeGqlOperations(val));\n\nconst AllowedValueSchema = z.strictObject({\n value: z.string(),\n description: z.string().optional(),\n});\n\nexport const DBFieldMetadataSchema = z.strictObject({\n required: z.boolean().optional().describe(\"Whether the field is required\"),\n array: z.boolean().optional().describe(\"Whether the field is an array\"),\n description: z.string().optional().describe(\"Field description\"),\n typeName: z.string().optional().describe(\"Type name for nested or enum fields\"),\n allowedValues: z.array(AllowedValueSchema).optional().describe(\"Allowed values for enum fields\"),\n index: z.boolean().optional().describe(\"Whether the field is indexed for faster queries\"),\n unique: z.boolean().optional().describe(\"Whether the field value must be unique\"),\n vector: z\n .boolean()\n .optional()\n .describe(\"Whether the field is a vector field for similarity search\"),\n foreignKey: z.boolean().optional().describe(\"Whether the field is a foreign key\"),\n foreignKeyType: z.string().optional().describe(\"Target table name for foreign key relations\"),\n foreignKeyField: z.string().optional().describe(\"Target field name for foreign key relations\"),\n hooks: z\n .strictObject({\n create: functionSchema.optional().describe(\"Hook function called on record creation\"),\n update: functionSchema.optional().describe(\"Hook function called on record update\"),\n })\n .optional()\n .describe(\"Lifecycle hooks for the field\"),\n validate: z.array(functionSchema).optional().describe(\"Validation functions for the field\"),\n serial: z\n .strictObject({\n start: z.number().describe(\"Starting value for the serial sequence\"),\n maxValue: z.number().optional().describe(\"Maximum value for the serial sequence\"),\n format: z.string().optional().describe(\"Format string for serial value (string type only)\"),\n })\n .optional()\n .describe(\"Serial (auto-increment) configuration\"),\n scale: z\n .number()\n .int()\n .min(0)\n .max(12)\n .optional()\n .describe(\"Decimal scale (number of digits after decimal point, 0-12)\"),\n default: z.unknown().optional().describe(\"Default value for the field on create\"),\n});\n\nconst RelationTypeSchema = z.enum(relationTypesKeys);\n\nexport const RawRelationConfigSchema = z.strictObject({\n type: RelationTypeSchema.describe(\"Relation cardinality type\"),\n toward: z.strictObject({\n table: z.string().describe(\"Target table name, or 'self' for self-relations\"),\n as: z.string().optional().describe(\"Custom forward relation name\"),\n key: z.string().optional().describe(\"Target field to join on (default: 'id')\"),\n }),\n backward: z.string().optional().describe(\"Backward relation name on the target table\"),\n});\n\nconst TailorDBFieldSchema: z.ZodType<TailorDBFieldOutput> = z.lazy(() =>\n // strip unknown keys\n z.object({\n type: TailorFieldTypeSchema,\n fields: z.record(z.string(), TailorDBFieldSchema).optional(),\n metadata: DBFieldMetadataSchema,\n rawRelation: RawRelationConfigSchema.optional(),\n }),\n);\n\n/**\n * Schema for TailorDB table settings.\n * Normalizes gqlOperations from alias (\"query\") to object format.\n */\nexport const TailorDBTypeSettingsSchema = z.strictObject({\n pluralForm: z.string().optional().describe(\"Custom plural form of the table name for GraphQL\"),\n aggregation: z.boolean().optional().describe(\"Enable aggregation queries for this table\"),\n bulkUpsert: z.boolean().optional().describe(\"Enable bulk upsert mutation for this table\"),\n gqlOperations: GqlOperationsSchema.optional().describe(\n 'Configure GraphQL operations for this table. Use \"query\" for read-only mode, or an object for granular control.',\n ),\n publishEvents: z\n .boolean()\n .optional()\n .describe(\n \"Enable publishing events for this table.\\nWhen enabled, record creation/update/deletion events are published.\\nIf not specified, this is automatically set to true when an executor uses this table\\nwith recordCreated/recordUpdated/recordDeleted triggers. If explicitly set to false\\nwhile an executor uses this table, an error will be thrown during apply.\",\n ),\n});\n\nexport const GQL_PERMISSION_INVALID_OPERAND_MESSAGE =\n \"operand is not supported in gqlPermission. Use permission() for record-level conditions.\";\n\nconst GqlPermissionOperandSchema = z.union(\n [\n z.strictObject({ user: z.string() }),\n z.string(),\n z.boolean(),\n z.array(z.string()),\n z.array(z.boolean()),\n ],\n {\n error: (issue) => {\n if (typeof issue.input === \"object\" && issue.input !== null) {\n const keys = Object.keys(issue.input);\n if (keys.length === 1) {\n return `\"${keys[0]}\" ${GQL_PERMISSION_INVALID_OPERAND_MESSAGE}`;\n }\n return \"Operand object must have exactly 1 key\";\n }\n return \"Invalid operand in gqlPermission\";\n },\n },\n);\n\nconst RecordPermissionOperandSchema = z.union([\n GqlPermissionOperandSchema,\n z.strictObject({ record: z.string() }),\n z.strictObject({ oldRecord: z.string() }),\n z.strictObject({ newRecord: z.string() }),\n]);\n\nconst PermissionOperatorSchema = z.enum([\"=\", \"!=\", \"in\", \"not in\", \"hasAny\", \"not hasAny\"]);\n\nconst RecordPermissionConditionSchema = z\n .tuple([RecordPermissionOperandSchema, PermissionOperatorSchema, RecordPermissionOperandSchema])\n .readonly();\n\nconst GqlPermissionConditionSchema = z\n .tuple([GqlPermissionOperandSchema, PermissionOperatorSchema, GqlPermissionOperandSchema])\n .readonly();\n\nconst ActionPermissionSchema = z.union([\n // Object format: { conditions, description?, permit? }\n z.strictObject({\n conditions: z.union([\n RecordPermissionConditionSchema,\n z.array(RecordPermissionConditionSchema).readonly(),\n ]),\n description: z.string().optional(),\n permit: z.boolean().optional(),\n }),\n // Single condition tuple: [operand, operator, operand]\n z\n .tuple([RecordPermissionOperandSchema, PermissionOperatorSchema, RecordPermissionOperandSchema])\n .readonly(),\n // Single condition tuple with permit: [operand, operator, operand, permit]\n z\n .tuple([\n RecordPermissionOperandSchema,\n PermissionOperatorSchema,\n RecordPermissionOperandSchema,\n z.boolean(),\n ])\n .readonly(),\n // Multiple conditions with optional trailing permit\n z\n .array(z.union([RecordPermissionConditionSchema, z.boolean()]))\n .refine(\n (arr) => {\n const boolIndex = arr.findIndex((item) => typeof item === \"boolean\");\n return boolIndex === -1 || boolIndex === arr.length - 1;\n },\n { message: \"Boolean permit flag must only appear at the end\" },\n )\n .readonly(),\n]);\n\nconst GqlPermissionActionSchema = z.enum([\n \"read\",\n \"create\",\n \"update\",\n \"delete\",\n \"aggregate\",\n \"bulkUpsert\",\n]);\n\nconst GqlPermissionPolicySchema = z.strictObject({\n conditions: z.array(GqlPermissionConditionSchema).readonly(),\n actions: z.union([z.literal(\"all\"), z.array(GqlPermissionActionSchema).readonly()]),\n permit: z.boolean().optional(),\n description: z.string().optional(),\n});\n\nexport const RawPermissionsSchema = z.strictObject({\n record: z\n .strictObject({\n create: z.array(ActionPermissionSchema).readonly(),\n read: z.array(ActionPermissionSchema).readonly(),\n update: z.array(ActionPermissionSchema).readonly(),\n delete: z.array(ActionPermissionSchema).readonly(),\n })\n .optional(),\n gql: z.array(GqlPermissionPolicySchema).readonly().optional(),\n});\n\nexport const TailorDBTypeSchema = z.strictObject({\n name: z.string(),\n fields: z.record(z.string(), TailorDBFieldSchema),\n // oxlint-disable-next-line zod/prefer-strict-object, tailor-zod/require-object-policy-comment -- Keep z.object().strict() so zinfer preserves the RawPermissions alias in generated types.\n metadata: z\n .object({\n name: z.string(),\n description: z.string().optional(),\n settings: TailorDBTypeSettingsSchema.optional(),\n permissions: RawPermissionsSchema,\n files: z.record(z.string(), z.string()),\n indexes: z\n .record(\n z.string(),\n z.strictObject({\n fields: z.array(z.string()),\n unique: z.boolean().optional(),\n }),\n )\n .optional(),\n typeHook: z\n .strictObject({\n create: functionSchema.optional(),\n update: functionSchema.optional(),\n })\n .optional(),\n typeValidate: functionSchema.optional(),\n })\n .strict(),\n});\n\nconst TailorDBMigrationConfigSchema = z.strictObject({\n directory: z.string().describe(\"Directory containing migration files\"),\n machineUser: z.string().optional().describe(\"Machine user name for migration execution\"),\n});\n\n/**\n * Schema for TailorDB service configuration.\n * Normalizes gqlOperations from alias (\"query\") to object format.\n */\nexport const TailorDBServiceConfigSchema = z.strictObject({\n files: z.array(z.string()).describe(\"Glob patterns for TailorDB table definition files\"),\n ignores: z.array(z.string()).optional().describe(\"Glob patterns to exclude from table discovery\"),\n migration: TailorDBMigrationConfigSchema.optional().describe(\"Migration configuration\"),\n gqlOperations: GqlOperationsSchema.optional().describe(\n \"Default GraphQL operations for all tables in this service\",\n ),\n});\n","import { isSdkBranded } from \"#/utils/brand\";\nimport { TailorDBTypeSchema } from \"./schema\";\n\nconst TAILORDB_TYPE_SCHEMA_KEYS = TailorDBTypeSchema.keyof().options;\n\nexport function stripTailorDBTypeBuilderHelpers(type: unknown): unknown {\n if (!isSdkBranded(type, \"tailordb-type\")) {\n return type;\n }\n\n return pickTailorDBTypeSchemaKeys(type);\n}\n\n/**\n * Keep only the TailorDBTypeSchema keys of an object, regardless of SDK\n * branding. Structural copies of builder tables (e.g. spread clones from\n * plugins) lose the non-enumerable brand but still carry builder helper\n * methods that a strict schema parse would reject.\n * @param type - Candidate table value\n * @returns An object with only schema keys, or the value itself when it is not an object\n */\nexport function pickTailorDBTypeSchemaKeys(type: unknown): unknown {\n if (typeof type !== \"object\" || type === null) {\n return type;\n }\n\n const config: Record<string, unknown> = {};\n const input = type as Record<string, unknown>;\n for (const key of TAILORDB_TYPE_SCHEMA_KEYS) {\n if (Object.prototype.hasOwnProperty.call(input, key)) {\n config[key] = input[key];\n }\n }\n return config;\n}\n","import { z } from \"zod\";\n\nexport const AuthConnectionOAuth2ConfigSchema = z.strictObject({\n providerUrl: z.string().describe(\"OAuth2 provider URL\"),\n issuerUrl: z.string().describe(\"OAuth2 issuer URL\"),\n clientId: z.string().describe(\"OAuth2 client ID\"),\n clientSecret: z.string().describe(\"OAuth2 client secret\"),\n authUrl: z.string().optional().describe(\"OAuth2 authorization endpoint override\"),\n tokenUrl: z.string().optional().describe(\"OAuth2 token endpoint override\"),\n});\n\nexport const AuthConnectionConfigSchema = AuthConnectionOAuth2ConfigSchema.extend({\n type: z.literal(\"oauth2\").describe(\"Connection type\"),\n});\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\nimport { TailorFieldTypeSchema } from \"../field-types\";\n\nconst AllowedValueSchema = z.strictObject({\n value: z.string().describe(\"The allowed value\"),\n description: z.string().optional().describe(\"Description of the allowed value\"),\n});\n\nconst FieldMetadataSchema = z.strictObject({\n as: z.enum([\"string\", \"date\", \"temporal\"]).optional().describe(\"Date value representation\"),\n required: z.boolean().optional().describe(\"Whether the field is required\"),\n array: z.boolean().optional().describe(\"Whether the field is an array\"),\n description: z.string().optional().describe(\"Field description\"),\n allowedValues: z.array(AllowedValueSchema).optional().describe(\"Allowed values for enum fields\"),\n hooks: z\n .strictObject({\n create: functionSchema.optional().describe(\"Hook function called on creation\"),\n update: functionSchema.optional().describe(\"Hook function called on update\"),\n })\n .optional()\n .describe(\"Lifecycle hooks\"),\n validate: z.array(functionSchema).optional().describe(\"Validation functions for the field\"),\n typeName: z.string().optional().describe(\"Type name for nested or enum fields\"),\n default: z.unknown().optional().describe(\"Default value for the field on create\"),\n});\n\n// strip unknown keys\nexport const TailorFieldSchema = z.object({\n type: TailorFieldTypeSchema.describe(\"Field data type\"),\n metadata: FieldMetadataSchema.describe(\"Field metadata configuration\"),\n get fields() {\n return z.record(z.string(), TailorFieldSchema);\n },\n});\n","import { z } from \"zod\";\nimport { AuthConnectionConfigSchema } from \"#/parser/service/auth-connection/index\";\nimport { TailorFieldSchema } from \"#/parser/service/field/schema\";\nimport { stripTailorDBTypeBuilderHelpers } from \"#/parser/service/tailordb/builder-helpers\";\nimport { TailorDBTypeSchema } from \"#/parser/service/tailordb/index\";\nimport type { ValueOperand } from \"#/configure/services/auth/types\";\nimport type { TailorDBInstance } from \"#/configure/services/tailordb/types\";\n\nexport const AuthInvokerObjectSchema = z.strictObject({\n namespace: z.string().describe(\"Auth namespace\"),\n machineUserName: z.string().describe(\"Machine user name for authentication\"),\n});\n\nexport const AuthInvokerSchema = z.union([\n z.string().describe(\"Machine user name (namespace auto-resolved from auth service)\"),\n AuthInvokerObjectSchema,\n]);\n\nconst secretValueSchema = z.strictObject({\n vaultName: z.string().describe(\"Vault name containing the secret\"),\n secretKey: z.string().describe(\"Key of the secret in the vault\"),\n});\n\nexport const OIDCSchema = z.strictObject({\n name: z.string().describe(\"Identity provider name\"),\n kind: z.literal(\"OIDC\"),\n clientID: z.string().describe(\"OAuth2 client ID\"),\n clientSecret: secretValueSchema.describe(\"OAuth2 client secret\"),\n providerURL: z.string().describe(\"OIDC provider URL\"),\n issuerURL: z.string().optional().describe(\"OIDC issuer URL (defaults to providerURL)\"),\n usernameClaim: z.string().optional().describe(\"JWT claim to use as username\"),\n});\n\nexport const SAMLSchema = z\n .strictObject({\n name: z.string().describe(\"Identity provider name\"),\n kind: z.literal(\"SAML\"),\n enableSignRequest: z.boolean().default(false).describe(\"Enable signing of SAML requests\"),\n metadataURL: z\n .string()\n .optional()\n .describe(\"URL to fetch SAML metadata (mutually exclusive with rawMetadata)\"),\n rawMetadata: z\n .string()\n .optional()\n .describe(\"Raw SAML metadata XML (mutually exclusive with metadataURL)\"),\n defaultRedirectURL: z\n .string()\n .optional()\n .describe(\"URL to redirect to when SAML ACS receives a response with an empty RelayState.\"),\n })\n\n .refine((value) => {\n const hasMetadata = value.metadataURL !== undefined;\n const hasRaw = value.rawMetadata !== undefined;\n return hasMetadata !== hasRaw;\n }, \"Provide either metadataURL or rawMetadata\");\n\nexport const IDTokenSchema = z.strictObject({\n name: z.string().describe(\"Identity provider name\"),\n kind: z.literal(\"IDToken\"),\n providerURL: z.string().describe(\"ID token provider URL\"),\n issuerURL: z.string().optional().describe(\"ID token issuer URL\"),\n clientID: z.string().describe(\"Client ID for ID token validation\"),\n usernameClaim: z.string().optional().describe(\"JWT claim to use as username\"),\n});\n\nexport const BuiltinIdPSchema = z.strictObject({\n name: z.string().describe(\"Identity provider name\"),\n kind: z.literal(\"BuiltInIdP\"),\n namespace: z.string().describe(\"IdP namespace\"),\n clientName: z.string().describe(\"OAuth2 client name in the IdP\"),\n});\n\nexport const IdProviderSchema = z.discriminatedUnion(\"kind\", [\n OIDCSchema,\n SAMLSchema,\n IDTokenSchema,\n BuiltinIdPSchema,\n]);\n\nexport const OAuth2ClientGrantTypeSchema = z\n .union([z.literal(\"authorization_code\"), z.literal(\"refresh_token\")])\n .describe(\"OAuth2 grant type\");\n\nexport const OAuth2ClientSchema = z\n .strictObject({\n description: z.string().optional().describe(\"Client description\"),\n grantTypes: z\n .array(OAuth2ClientGrantTypeSchema)\n .default([\"authorization_code\", \"refresh_token\"])\n .describe(\"Allowed OAuth2 grant types\"),\n redirectURIs: z\n .array(\n z.union([\n z.templateLiteral([\"https://\", z.string()]),\n z.templateLiteral([\"http://\", z.string()]),\n z.templateLiteral([z.string(), \":url\"]),\n z.templateLiteral([z.string(), \":url/\", z.string()]),\n ]),\n )\n .describe(\"Allowed redirect URIs\"),\n clientType: z\n .union([z.literal(\"confidential\"), z.literal(\"public\"), z.literal(\"browser\")])\n .optional()\n .describe(\"OAuth2 client type\"),\n accessTokenLifetimeSeconds: z\n .number()\n .int()\n .min(60, \"Minimum access token lifetime is 60 seconds\")\n .max(86400, \"Maximum access token lifetime is 1 day (86400 seconds)\")\n .optional()\n .describe(\"Access token lifetime in seconds (60-86400)\")\n .transform((val) => (val ? { seconds: BigInt(val), nanos: 0 } : undefined)),\n refreshTokenLifetimeSeconds: z\n .number()\n .int()\n .min(60, \"Minimum refresh token lifetime is 60 seconds\")\n .max(604800, \"Maximum refresh token lifetime is 7 days (604800 seconds)\")\n .optional()\n .describe(\"Refresh token lifetime in seconds (60-604800)\")\n .transform((val) => (val ? { seconds: BigInt(val), nanos: 0 } : undefined)),\n requireDpop: z\n .boolean()\n .optional()\n .describe(\"Require DPoP (Demonstrating Proof-of-Possession) for token requests\"),\n })\n\n .refine((data) => !(data.clientType === \"browser\" && data.requireDpop === true), {\n message: \"requireDpop cannot be set to true for browser clients as they don't support DPoP\",\n path: [\"requireDpop\"],\n });\n\nexport const SCIMAuthorizationSchema = z.strictObject({\n type: z.union([z.literal(\"oauth2\"), z.literal(\"bearer\")]).describe(\"SCIM authorization type\"),\n bearerSecret: secretValueSchema\n .optional()\n .describe(\"Bearer token secret (required for bearer type)\"),\n});\n\nexport const SCIMAttributeTypeSchema = z\n .union([\n z.literal(\"string\"),\n z.literal(\"number\"),\n z.literal(\"boolean\"),\n z.literal(\"datetime\"),\n z.literal(\"complex\"),\n ])\n .describe(\"SCIM attribute data type\");\n\nexport const SCIMAttributeSchema = z.strictObject({\n type: SCIMAttributeTypeSchema.describe(\"Attribute data type\"),\n name: z.string().describe(\"Attribute name\"),\n description: z.string().optional().describe(\"Attribute description\"),\n mutability: z\n .union([z.literal(\"readOnly\"), z.literal(\"readWrite\"), z.literal(\"writeOnly\")])\n .optional()\n .describe(\"Attribute mutability\"),\n required: z.boolean().optional().describe(\"Whether the attribute is required\"),\n multiValued: z.boolean().optional().describe(\"Whether the attribute can have multiple values\"),\n uniqueness: z\n .union([z.literal(\"none\"), z.literal(\"server\"), z.literal(\"global\")])\n .optional()\n .describe(\"Uniqueness constraint\"),\n canonicalValues: z.array(z.string()).nullable().optional().describe(\"List of canonical values\"),\n get subAttributes() {\n return z.array(SCIMAttributeSchema).nullable().optional();\n },\n});\n\nconst SCIMSchemaSchema = z.strictObject({\n name: z.string().describe(\"SCIM schema name\"),\n attributes: z.array(SCIMAttributeSchema).describe(\"Schema attributes\"),\n});\n\nexport const SCIMAttributeMappingSchema = z.strictObject({\n tailorDBField: z.string().describe(\"TailorDB field name to map to\"),\n scimPath: z.string().describe(\"SCIM attribute path\"),\n});\n\nexport const SCIMResourceSchema = z.strictObject({\n name: z.string().describe(\"SCIM resource name\"),\n tailorDBNamespace: z.string().describe(\"TailorDB namespace for the resource\"),\n tailorDBType: z.string().describe(\"TailorDB table name for the resource\"),\n coreSchema: SCIMSchemaSchema.describe(\"Core SCIM schema definition\"),\n attributeMapping: z.array(SCIMAttributeMappingSchema).describe(\"Attribute mapping configuration\"),\n});\n\nexport const SCIMSchema = z.strictObject({\n machineUserName: z.string().describe(\"Machine user name for SCIM operations\"),\n authorization: SCIMAuthorizationSchema.describe(\"SCIM authorization configuration\"),\n resources: z.array(SCIMResourceSchema).describe(\"SCIM resource definitions\"),\n});\n\nexport const TenantProviderSchema = z.strictObject({\n namespace: z.string().describe(\"TailorDB namespace for the tenant table\"),\n type: z.string().describe(\"TailorDB table name for tenants\"),\n signatureField: z.string().describe(\"Field used as the tenant signature\"),\n});\n\nconst UserProfileSchema = z.strictObject({\n namespace: z.string().optional().describe(\"TailorDB namespace where the user table is defined\"),\n type: z\n .custom<TailorDBInstance>()\n .transform(stripTailorDBTypeBuilderHelpers)\n .pipe(TailorDBTypeSchema),\n usernameField: z.string(),\n attributes: z.record(z.string(), z.literal(true)).optional(),\n attributeList: z.array(z.string()).optional(),\n});\n\nconst ValueOperandSchema: z.ZodType<ValueOperand> = z.union([\n z.string(),\n z.boolean(),\n z.array(z.string()),\n z.array(z.boolean()),\n]);\n\nconst MachineUserSchema = z.strictObject({\n // null/undefined values mean \"attribute not set\" and are dropped so\n // downstream (deploy, drift diff) only ever sees concrete values.\n attributes: z\n .record(z.string(), ValueOperandSchema.nullish())\n .transform((attributes): Record<string, ValueOperand> =>\n Object.fromEntries(\n Object.entries(attributes).filter(\n (entry): entry is [string, ValueOperand] => entry[1] != null,\n ),\n ),\n )\n .optional(),\n attributeList: z.array(z.uuid()).optional(),\n});\n\nconst BeforeLoginHookSchema = z.strictObject({\n handler: z.function(),\n invoker: z.string(),\n});\n\nconst AuthConfigBaseSchema = z.strictObject({\n name: z.string().describe(\"Auth service name\"),\n hooks: z\n .strictObject({\n beforeLogin: BeforeLoginHookSchema.optional().describe(\"Before login auth hook\"),\n })\n .optional()\n .describe(\"Auth hooks\"),\n machineUsers: z\n .record(z.string(), MachineUserSchema)\n .optional()\n .describe(\"Machine user definitions\"),\n oauth2Clients: z\n .record(z.string(), OAuth2ClientSchema)\n .optional()\n .describe(\"OAuth2 client definitions\"),\n idProvider: IdProviderSchema.optional().describe(\"Identity provider configuration\"),\n scim: SCIMSchema.optional().describe(\"SCIM provisioning configuration\"),\n tenantProvider: TenantProviderSchema.optional().describe(\"Multi-tenant provider configuration\"),\n connections: z\n .record(z.string(), AuthConnectionConfigSchema)\n .optional()\n .describe(\"Auth connection definitions for external OAuth2 providers\"),\n publishSessionEvents: z.boolean().optional().describe(\"Enable publishing session events\"),\n});\n\nexport const AuthConfigSchema = z.xor(\n [\n AuthConfigBaseSchema.extend({\n userProfile: UserProfileSchema.optional().describe(\"User profile configuration\"),\n machineUserAttributes: z.undefined().optional(),\n }),\n AuthConfigBaseSchema.extend({\n userProfile: z.undefined().optional(),\n machineUserAttributes: z\n .record(z.string(), TailorFieldSchema)\n .describe(\"Machine user attribute fields\"),\n }),\n ],\n {\n error: (iss) => {\n // zod may report error codes not covered by its type definitions\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (iss.code !== \"invalid_union\") return undefined;\n // zod may report error codes not covered by its type definitions\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (iss.errors.length < 2) return undefined;\n const isOnlyMutexViolation = iss.errors.every((variantErrors) =>\n variantErrors.every(\n (e) =>\n e.path.length === 1 &&\n (e.path[0] === \"userProfile\" || e.path[0] === \"machineUserAttributes\"),\n ),\n );\n if (isOnlyMutexViolation) {\n return \"Specify either `userProfile` or `machineUserAttributes`, not both.\";\n }\n return undefined;\n },\n },\n);\n","import { z } from \"zod\";\nimport { AuthInvokerSchema } from \"../auth\";\nimport { functionSchema } from \"../common\";\nimport type { JsonValue } from \"#/types/helpers\";\n\nexport const TailorDBTriggerSchema = z.strictObject({\n kind: z.literal(\"tailordb\").describe(\"TailorDB record event trigger\"),\n events: z\n .array(\n z.enum([\n \"tailordb.type_record.created\",\n \"tailordb.type_record.updated\",\n \"tailordb.type_record.deleted\",\n ]),\n )\n .min(1)\n .transform((arr) => [...new Set(arr)])\n .describe(\"TailorDB event types to trigger on\"),\n tableName: z.string().describe(\"TailorDB table name to watch for events\"),\n condition: functionSchema.optional().describe(\"Condition function to filter events\"),\n});\n\nexport const ResolverExecutedTriggerSchema = z.strictObject({\n kind: z.literal(\"resolverExecuted\"),\n resolverName: z.string().describe(\"Name of the resolver to trigger on\"),\n condition: functionSchema.optional().describe(\"Condition function to filter events\"),\n});\n\nexport const ScheduleTriggerSchema = z.strictObject({\n kind: z.literal(\"schedule\"),\n cron: z.string().describe(\"CRON expression for the schedule\"),\n timezone: z\n .string()\n .optional()\n .default(\"UTC\")\n .describe(\"Timezone for the CRON schedule (default: UTC)\"),\n});\n\nexport const IncomingWebhookTriggerResponseSchema = z.strictObject({\n body: functionSchema.optional().describe(\"Function returning the response body\"),\n statusCode: z.number().int().optional().describe(\"HTTP status code for the response\"),\n});\n\nexport const IncomingWebhookTriggerSchema = z.strictObject({\n kind: z.literal(\"incomingWebhook\"),\n response: IncomingWebhookTriggerResponseSchema.optional().describe(\"Response configuration\"),\n});\n\nexport const IdpUserTriggerSchema = z.strictObject({\n kind: z.literal(\"idpUser\").describe(\"IdP user event trigger\"),\n events: z\n .array(z.enum([\"idp.user.created\", \"idp.user.updated\", \"idp.user.deleted\"]))\n .min(1)\n .transform((arr) => [...new Set(arr)])\n .describe(\"IdP user event types to trigger on\"),\n idp: z\n .string()\n .optional()\n .describe(\n \"IdP namespace name to subscribe to. If omitted, the project's only IdP is used; throws when multiple IdPs exist.\",\n ),\n});\n\nexport const AuthAccessTokenTriggerSchema = z.strictObject({\n kind: z.literal(\"authAccessToken\").describe(\"Auth access token event trigger\"),\n events: z\n .array(\n z.enum([\n \"auth.access_token.issued\",\n \"auth.access_token.refreshed\",\n \"auth.access_token.revoked\",\n ]),\n )\n .min(1)\n .transform((arr) => [...new Set(arr)])\n .describe(\"Auth access token event types to trigger on\"),\n});\n\nconst workflowNameSchema = z\n .string()\n .refine((value) => value.trim().length > 0, \"Workflow name cannot be blank\")\n .describe(\"Workflow name to subscribe to.\");\n\nexport const WorkflowExecutionTriggerSchema = z.strictObject({\n kind: z.literal(\"workflowExecution\").describe(\"Workflow execution event trigger\"),\n events: z\n .array(\n z.enum([\n \"workflow.workflow_execution.started\",\n \"workflow.workflow_execution.completed\",\n \"workflow.workflow_execution.retried\",\n \"workflow.workflow_execution.resumed\",\n \"workflow.workflow_execution.wait_started\",\n \"workflow.workflow_execution.wait_resolved\",\n ]),\n )\n .min(1)\n .transform((arr) => [...new Set(arr)])\n .describe(\"Workflow execution event types to trigger on\"),\n workflowName: workflowNameSchema,\n condition: functionSchema.optional().describe(\"Condition function to filter events\"),\n});\n\nexport const WorkflowJobExecutionTriggerSchema = z.strictObject({\n kind: z.literal(\"workflowJobExecution\").describe(\"Workflow job execution event trigger\"),\n events: z\n .array(\n z.enum([\n \"workflow.workflow_execution.job_execution.started\",\n \"workflow.workflow_execution.job_execution.completed\",\n \"workflow.workflow_execution.job_execution.wait_started\",\n \"workflow.workflow_execution.job_execution.wait_resolved\",\n ]),\n )\n .min(1)\n .transform((arr) => [...new Set(arr)])\n .describe(\"Workflow job execution event types to trigger on\"),\n workflowName: workflowNameSchema,\n condition: functionSchema.optional().describe(\"Condition function to filter events\"),\n});\n\nexport const TriggerSchema = z.discriminatedUnion(\"kind\", [\n TailorDBTriggerSchema,\n ResolverExecutedTriggerSchema,\n ScheduleTriggerSchema,\n IncomingWebhookTriggerSchema,\n IdpUserTriggerSchema,\n AuthAccessTokenTriggerSchema,\n WorkflowExecutionTriggerSchema,\n WorkflowJobExecutionTriggerSchema,\n]);\n\nexport const FunctionOperationSchema = z.strictObject({\n kind: z.enum([\"function\", \"jobFunction\"]),\n body: functionSchema.describe(\"Function implementation\"),\n invoker: AuthInvokerSchema.optional().describe(\"Invoker for the function execution\"),\n});\n\nexport const GqlOperationSchema = z.strictObject({\n kind: z.literal(\"graphql\"),\n appName: z.string().optional().describe(\"Target application name for the GraphQL query\"),\n query: z.preprocess((val) => String(val), z.string().describe(\"GraphQL query string\")),\n variables: functionSchema.optional().describe(\"Function to compute GraphQL variables\"),\n invoker: AuthInvokerSchema.optional().describe(\"Invoker for the GraphQL execution\"),\n});\n\nexport const WebhookOperationSchema = z.strictObject({\n kind: z.literal(\"webhook\"),\n url: functionSchema.describe(\"Function returning the webhook URL\"),\n requestBody: functionSchema.optional().describe(\"Function to compute the request body\"),\n headers: z\n .record(\n z.string(),\n z.union([z.string(), z.strictObject({ vault: z.string(), key: z.string() })]),\n )\n .optional()\n .describe(\"HTTP headers for the webhook request\"),\n});\n\nexport const JsonValueSchema: z.ZodType<JsonValue, JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(JsonValueSchema),\n z.record(z.string(), JsonValueSchema),\n ]),\n);\n\nexport const WorkflowInputSchema: z.ZodType<\n Exclude<JsonValue, null>,\n Exclude<JsonValue, null>\n> = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.array(JsonValueSchema),\n z.record(z.string(), JsonValueSchema),\n]);\n\nexport const WorkflowOperationArgsSchema = z\n .union([WorkflowInputSchema, functionSchema])\n .describe(\"Arguments to pass to the workflow\");\n\nconst workflowOperationShape = {\n kind: z.literal(\"workflow\"),\n args: WorkflowOperationArgsSchema.optional(),\n invoker: AuthInvokerSchema.optional().describe(\"Invoker for the workflow execution\"),\n};\n\nconst WorkflowOperationByNameSchema = z.strictObject({\n ...workflowOperationShape,\n workflowName: z.string().describe(\"Name of the workflow to execute\"),\n workflow: z.never().optional(),\n});\n\nconst WorkflowOperationByReferenceSchema = z\n .strictObject({\n ...workflowOperationShape,\n workflow: z.looseObject({ name: z.string() }),\n workflowName: z.string().optional(),\n })\n .transform(({ workflow, ...operation }) => ({\n ...operation,\n workflowName: workflow.name,\n }));\n\nexport const WorkflowOperationSchema = z.union([\n WorkflowOperationByReferenceSchema,\n WorkflowOperationByNameSchema,\n]);\n\nexport const OperationSchema = z.union([\n FunctionOperationSchema,\n GqlOperationSchema,\n WebhookOperationSchema,\n WorkflowOperationSchema,\n]);\n\nexport const ExecutorSchema = z.strictObject({\n name: z.string().describe(\"Executor name\"),\n description: z.string().optional().describe(\"Executor description\"),\n disabled: z.boolean().optional().default(false).describe(\"Whether the executor is disabled\"),\n trigger: TriggerSchema.describe(\"Event trigger configuration\"),\n operation: OperationSchema.describe(\"Operation to execute when triggered\"),\n});\n","import { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ExecutorSchema } from \"#/parser/service/executor/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport type { Executor } from \"#/types/executor.generated\";\n\nexport function stripExecutorTriggerArgs(executor: unknown): unknown {\n if (!isSdkBranded(executor, \"executor\")) {\n return executor;\n }\n\n const trigger = (executor as { trigger?: unknown }).trigger;\n if (trigger === null || typeof trigger !== \"object\" || !(\"__args\" in trigger)) {\n return executor;\n }\n\n const { __args: _args, ...triggerConfig } = trigger as Record<string, unknown>;\n return { ...(executor as Record<string, unknown>), trigger: triggerConfig };\n}\n\n/**\n * Load and validate an executor definition from a file.\n * @param executorFilePath - Path to the executor file\n * @returns Parsed executor or null if invalid\n */\nexport async function loadExecutor(executorFilePath: string): Promise<Executor | null> {\n const executorModule = await importUserModule(executorFilePath);\n const executor = executorModule.default;\n\n const parseResult = ExecutorSchema.safeParse(stripExecutorTriggerArgs(executor));\n if (!parseResult.success) {\n return null;\n }\n\n return parseResult.data;\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ExecutorSchema } from \"#/parser/service/executor/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport { stripExecutorTriggerArgs } from \"./loader\";\nimport type { ExecutorServiceConfig } from \"#/configure/config/types\";\nimport type { Executor } from \"#/types/executor.generated\";\n\n/**\n * Information about a plugin-generated executor converted to Executor format\n */\nexport interface PluginExecutor {\n /** The executor in standard Executor format */\n executor: Executor;\n /** Plugin ID that generated this executor */\n pluginId: string;\n /** Source table name (for table-attached executors) */\n sourceTableName?: string;\n}\n\nexport type ExecutorService = {\n readonly config: ExecutorServiceConfig;\n readonly executors: Record<string, Executor>;\n readonly pluginExecutors: ReadonlyArray<PluginExecutor>;\n /**\n * Loads executor files once and resolves to the executor record loaded so\n * far. Resolves to undefined only when the config declares no files and no\n * plugin executor has been loaded yet; plugin executors appear in calls\n * made after loadPluginExecutorFiles() has completed.\n */\n loadExecutors: () => Promise<Record<string, Executor> | undefined>;\n loadPluginExecutorFiles: (filePaths: string[]) => Promise<void>;\n};\n\n/**\n * Parameters for creating an ExecutorService\n */\nexport interface CreateExecutorServiceParams {\n /** The executor service configuration */\n config: ExecutorServiceConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\n/**\n * Creates a new ExecutorService instance.\n * @param params - Parameters for creating the service\n * @returns A new ExecutorService instance\n */\nexport function createExecutorService(params: CreateExecutorServiceParams): ExecutorService {\n const { config, baseDir } = params;\n const executors: Record<string, Executor> = {};\n const pluginExecutors: PluginExecutor[] = [];\n let loadPromise: Promise<Record<string, Executor> | undefined> | undefined;\n\n const loadExecutorForFile = async (executorFile: string): Promise<Executor | undefined> => {\n try {\n const executorModule = await importUserModule(executorFile);\n const result = ExecutorSchema.safeParse(stripExecutorTriggerArgs(executorModule.default));\n if (result.success) {\n const relativePath = path.relative(process.cwd(), executorFile);\n logger.debug(\n `Executor: ${styles.successBright(`\"${result.data.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n executors[executorFile] = result.data;\n return result.data;\n }\n if (isSdkBranded(executorModule.default, \"executor\")) {\n throw result.error;\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), executorFile);\n logger.error(`Failed to load executor from ${styles.bold(relativePath)}`);\n logger.error(String(error));\n throw error;\n }\n return undefined;\n };\n\n return {\n config,\n get executors() {\n return executors;\n },\n get pluginExecutors() {\n return pluginExecutors;\n },\n loadExecutors: async () => {\n if (!loadPromise) {\n loadPromise = (async () => {\n if (config.files.length === 0) {\n return undefined;\n }\n\n const executorFiles = loadFilesWithIgnores(config, baseDir);\n\n logger.newline();\n logger.log(`Found ${styles.highlight(executorFiles.length.toString())} executor files`);\n\n await Promise.all(executorFiles.map((executorFile) => loadExecutorForFile(executorFile)));\n assertUniqueExecutorNames(executors);\n return executors;\n })();\n }\n const loaded = await loadPromise;\n // Files are loaded only once, but plugin executors registered by\n // loadPluginExecutorFiles() after that first load must reach callers\n // that re-invoke loadExecutors(), such as deployment planning.\n return loaded ?? (Object.keys(executors).length > 0 ? executors : undefined);\n },\n loadPluginExecutorFiles: async (filePaths: string[]) => {\n if (filePaths.length === 0) return;\n\n logger.newline();\n logger.log(\n `Loading ${styles.highlight(filePaths.length.toString())} plugin-generated executor files`,\n );\n\n for (const filePath of filePaths) {\n const executor = await loadExecutorForFile(filePath);\n if (executor) {\n // Track as plugin executor (plugin ID is extracted from file path)\n // File path format: .tailor/plugin/{executor-name}.ts\n pluginExecutors.push({\n executor,\n pluginId: \"plugin-generated\",\n sourceTableName: undefined,\n });\n }\n }\n assertUniqueExecutorNames(executors);\n },\n };\n}\n\n/**\n * Assert that every loaded executor has a unique name.\n * Executors are stored by source file, so two files declaring the same\n * `name` would otherwise silently share a single bundle cache entry.\n * @param executors - Loaded executors keyed by source file\n */\nfunction assertUniqueExecutorNames(executors: Record<string, Executor>): void {\n const seenNames = new Map<string, string>();\n for (const [file, executor] of Object.entries(executors)) {\n const relativePath = path.relative(process.cwd(), file);\n const existing = seenNames.get(executor.name);\n if (existing) {\n throw new Error(\n `Duplicate executor name \"${executor.name}\" found:\\n` +\n ` - ${existing}\\n` +\n ` - ${relativePath}\\n` +\n `Each executor must have a unique name.`,\n );\n }\n seenNames.set(executor.name, relativePath);\n }\n}\n"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ export type TailorField = {
|
|
|
5
5
|
/** Field metadata configuration */
|
|
6
6
|
metadata: {
|
|
7
7
|
/** Date value representation */
|
|
8
|
-
as?: "string" | "date" | undefined;
|
|
8
|
+
as?: "string" | "date" | "temporal" | undefined;
|
|
9
9
|
/** Whether the field is required */
|
|
10
10
|
required?: boolean | undefined;
|
|
11
11
|
/** Whether the field is an array */
|
package/dist/types/helpers.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Temporal } from "temporal-spec";
|
|
1
2
|
declare namespace helpers_d_exports {
|
|
2
3
|
export { DeepReadonly, DeepWritable, InferFieldsOutput, IsUnion, JsonCompatible, JsonValue, NullableToOptional, Prettify, SerializeDates, TypeLevelError, UnionToIntersection, output };
|
|
3
4
|
}
|
|
@@ -7,19 +8,20 @@ export type TypeLevelError<Message extends string> = {
|
|
|
7
8
|
};
|
|
8
9
|
export type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
9
10
|
export type IsUnion<T, U extends T = T> = T extends unknown ? [U] extends [T] ? false : true : never;
|
|
10
|
-
export type DeepWritable<T> = T extends Date | RegExp | Function ? T : T extends object ? { -readonly [P in keyof T]: DeepWritable<T[P]>; } & {} : T;
|
|
11
|
-
export type DeepReadonly<T> = T extends Date | RegExp | Function ? T : T extends readonly (infer E)[] ? readonly DeepReadonly<E>[] : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]>; } : T;
|
|
11
|
+
export type DeepWritable<T> = T extends Date | Temporal.PlainDate | Temporal.Instant | Temporal.PlainTime | RegExp | Function ? T : T extends object ? { -readonly [P in keyof T]: DeepWritable<T[P]>; } & {} : T;
|
|
12
|
+
export type DeepReadonly<T> = T extends Date | Temporal.PlainDate | Temporal.Instant | Temporal.PlainTime | RegExp | Function ? T : T extends readonly (infer E)[] ? readonly DeepReadonly<E>[] : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]>; } : T;
|
|
12
13
|
export type output<T> = T extends {
|
|
13
14
|
_output: infer U;
|
|
14
15
|
} ? DeepWritable<U> : never;
|
|
15
16
|
/**
|
|
16
|
-
* Replace `Date` with `string` throughout a type.
|
|
17
|
+
* Replace `Date` and supported Temporal values with `string` throughout a type.
|
|
17
18
|
*
|
|
18
19
|
* Values that reach user code as a parsed JSON payload cannot carry a `Date`
|
|
19
|
-
* instance, so a type describing such a payload must
|
|
20
|
-
* form even when the type it derives from uses
|
|
20
|
+
* or Temporal instance, so a type describing such a payload must
|
|
21
|
+
* report the serialized form even when the type it derives from uses one of
|
|
22
|
+
* those representations.
|
|
21
23
|
*/
|
|
22
|
-
export type SerializeDates<T> = T extends Date ? string : T extends RegExp | Function ? T : T extends object ? { [K in keyof T]: SerializeDates<T[K]>; } : T;
|
|
24
|
+
export type SerializeDates<T> = T extends Date | Temporal.PlainDate | Temporal.Instant | Temporal.PlainTime ? string : T extends RegExp | Function ? T : T extends object ? { [K in keyof T]: SerializeDates<T[K]>; } : T;
|
|
23
25
|
export type NullableToOptional<T> = { [K in keyof T as null extends T[K] ? never : K]: T[K]; } & { [K in keyof T as null extends T[K] ? K : never]?: T[K]; };
|
|
24
26
|
export type InferFieldsOutput<F extends Record<string, {
|
|
25
27
|
_output: any;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"../../field-parse-
|
|
1
|
+
import{t as e}from"../../field-parse-BbNyotv5.mjs";function setField(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0})}function createTailorDBHook(t){return(n,r=new Date)=>{let i=n&&typeof n==`object`?n:void 0,a=Object.entries(t.fields).reduce((t,[n,a])=>{let o=a,s=i&&Object.hasOwn(i,n)?i[n]:void 0,c;if(n===`id`)c=s??crypto.randomUUID();else if(o.type===`nested`){let t=createTailorDBHook({fields:o.fields});c=o.metadata.array?Array.isArray(s)?s.map(n=>e(n)?t(n,r):n):s:e(s)?t(s,r):s}else o.metadata.hooks?.create?(c=o.metadata.hooks.create({input:s,invoker:null,now:r}),c instanceof Date&&(c=c.toISOString())):c=s;if(c==null&&o.metadata.default!==void 0){let e=o.type===`datetime`||o.type===`date`||o.type===`time`;c=o.metadata.default===`now`&&e?r.toISOString():o.metadata.default}return setField(t,n,c),t},{});if(t.metadata?.typeHook?.create){let{id:e,...n}=a,i=t.metadata.typeHook.create({input:n,invoker:null,now:r});if(i&&typeof i==`object`)for(let[e,t]of Object.entries(i))setField(a,e,t instanceof Date?t.toISOString():t)}return a}}function typeLevelIssues(e,t){let n=e?.metadata?.typeValidate;if(!n)return[];let{id:r,...i}=t,a=[];return n({newRecord:i,oldRecord:null,invoker:null},(e,t)=>{a.push({message:t,path:[e]})}),a}function undeclaredFieldMessage(e){return`Field "${e}" is not declared by the table. Remove it from the row, or add it to the table definition and run \`tailor generate\`.`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function collectUndeclaredFieldIssues(e,t,n,r){if(isRecord(e))for(let i of Object.keys(e)){if(!Object.hasOwn(t,i)){r.push({message:undeclaredFieldMessage(i),path:n.concat(i)});continue}let a=t[i];if(a?.type!==`nested`)continue;let o=e[i],s=a.fields;a.metadata.array?Array.isArray(o)&&o.forEach((e,t)=>{collectUndeclaredFieldIssues(e,s,n.concat(i,`[${t}]`),r)}):collectUndeclaredFieldIssues(o,s,n.concat(i),r)}}function createStandardSchema(e,t,n){let validateHooked=t=>{let r=typeLevelIssues(n,t);if(r.length>0)return{issues:r};let i=e.parse({value:t,data:t,invoker:null});return i.issues?i:{value:t}};return{"~standard":{version:1,vendor:`@tailor-platform/sdk`,validate:e=>{let r=t(e),i=[];n&&collectUndeclaredFieldIssues(e,n.fields,[],i);let a=validateHooked(r),o=[...i,...a.issues??[]];return o.length>0?{issues:o}:a}}}}export{createStandardSchema,createTailorDBHook};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"../es-builtins-BHCXINQp.mjs";import{n as t,r as n,t as r}from"../globals-CMHSnj4w.mjs";const i=new Set([...e,r,`process`,`require`,`module`,`exports`,`__vitest_worker__`,`__vitest_mocker__`,`VITEST_POOL_ID`]);var a={name:`tailor-runtime`,viteEnvironment:`ssr`,async setup(e){let r=e,a={};for(let e of Object.getOwnPropertyNames(r))if(!i.has(e)){let t=Object.getOwnPropertyDescriptor(r,e);t?.configurable&&(
|
|
1
|
+
import{t as e}from"../es-builtins-BHCXINQp.mjs";import{n as t,r as n,t as r}from"../globals-CMHSnj4w.mjs";const i=new Set([...e,r,`process`,`require`,`module`,`exports`,`__vitest_worker__`,`__vitest_mocker__`,`VITEST_POOL_ID`]);var a={name:`tailor-runtime`,viteEnvironment:`ssr`,async setup(e){let r=e,a=Object.getOwnPropertyDescriptor(r,`Temporal`),o=r.Temporal===void 0,s=o?(await import(`temporal-polyfill/full/implementation`)).Temporal:void 0,c={};for(let e of Object.getOwnPropertyNames(r))if(!i.has(e)){let t=Object.getOwnPropertyDescriptor(r,e);t?.configurable&&(c[e]=t,delete r[e])}return n(e),o&&Object.defineProperty(r,"Temporal",{value:s,writable:!0,configurable:!0}),{teardown(e){t(e),o&&(a?Object.defineProperty(e,"Temporal",a):Reflect.deleteProperty(e,`Temporal`));let n=e;for(let[e,t]of Object.entries(c))Object.defineProperty(n,e,t)}}}};export{a as default};
|
|
2
2
|
//# sourceMappingURL=environment.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.mjs","names":[],"sources":["../../src/vitest/environment.ts"],"sourcesContent":["import { ES_BUILTINS } from \"#/utils/es-builtins\";\n// Import from ./globals (NOT ./mock): this module runs in the Vitest environment\n// realm where `vi` is unavailable, and ./mock imports `vi`. ./globals is\n// dependency-free of vitest.\nimport { RUNTIME_FLAG_KEY, cleanupPlatformGlobals, installPlatformGlobals } from \"./globals\";\n\n// Globals allowed in the Tailor Platform runtime.\n// ES_BUILTINS is the free-variable allowlist the deploy-time check uses, so\n// the emulated runtime exposes exactly the same identifiers as the production\n// platform (ECMAScript builtins + shared Node/browser runtime globals like\n// console, fetch, setTimeout).\n// Platform API mocks (tailor, tailordb, etc.) are not listed here — the base\n// surface is injected by installPlatformGlobals() after the whitelist cleanup,\n// and per-namespace mocks are layered on at `using xMock()` acquisition time.\nconst ALLOWED_GLOBALS = new Set([\n ...ES_BUILTINS,\n\n // The environment-active flag (set in installPlatformGlobals, used by\n // setup.ts to detect the tailor-runtime environment).\n RUNTIME_FLAG_KEY,\n\n // Used by Vitest internally — not in the platform runtime, but removing breaks the test runner\n \"process\",\n \"require\",\n \"module\",\n \"exports\",\n \"__vitest_worker__\",\n \"__vitest_mocker__\",\n \"VITEST_POOL_ID\",\n]);\n\nexport default {\n name: \"tailor-runtime\",\n viteEnvironment: \"ssr\",\n\n async setup(global: typeof globalThis) {\n const g = global as Record<string, unknown>;\n\n // Save and remove all non-whitelisted globals\n const saved: Record<string, PropertyDescriptor> = {};\n for (const key of Object.getOwnPropertyNames(g)) {\n if (!ALLOWED_GLOBALS.has(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(g, key);\n if (descriptor?.configurable) {\n saved[key] = descriptor;\n delete g[key];\n }\n }\n }\n\n // Install the base platform surface after whitelist cleanup. Per-namespace\n // mocks (workflow, tailordb, …) are installed on demand by `using xMock()`.\n installPlatformGlobals(global);\n\n return {\n teardown(global: typeof globalThis) {\n cleanupPlatformGlobals(global);\n\n // Restore removed globals\n const g = global as Record<string, unknown>;\n for (const [key, descriptor] of Object.entries(saved)) {\n Object.defineProperty(g, key, descriptor);\n }\n },\n };\n },\n};\n"],"mappings":"0GAcA,MAAM,EAAkB,IAAI,IAAI,CAC9B,GAAG,EAIH,EAGA,UACA,UACA,SACA,UACA,oBACA,oBACA,gBACF,CAAC,EAED,IAAA,EAAe,CACb,KAAM,iBACN,gBAAiB,MAEjB,MAAM,MAAM,EAA2B,CACrC,IAAM,EAAI,
|
|
1
|
+
{"version":3,"file":"environment.mjs","names":[],"sources":["../../src/vitest/environment.ts"],"sourcesContent":["import { ES_BUILTINS } from \"#/utils/es-builtins\";\n// Import from ./globals (NOT ./mock): this module runs in the Vitest environment\n// realm where `vi` is unavailable, and ./mock imports `vi`. ./globals is\n// dependency-free of vitest.\nimport { RUNTIME_FLAG_KEY, cleanupPlatformGlobals, installPlatformGlobals } from \"./globals\";\n\n// Globals allowed in the Tailor Platform runtime.\n// ES_BUILTINS is the free-variable allowlist the deploy-time check uses, so\n// the emulated runtime exposes exactly the same identifiers as the production\n// platform (ECMAScript builtins + shared Node/browser runtime globals like\n// console, fetch, setTimeout).\n// Platform API mocks (tailor, tailordb, etc.) are not listed here — the base\n// surface is injected by installPlatformGlobals() after the whitelist cleanup,\n// and per-namespace mocks are layered on at `using xMock()` acquisition time.\nconst ALLOWED_GLOBALS = new Set([\n ...ES_BUILTINS,\n\n // The environment-active flag (set in installPlatformGlobals, used by\n // setup.ts to detect the tailor-runtime environment).\n RUNTIME_FLAG_KEY,\n\n // Used by Vitest internally — not in the platform runtime, but removing breaks the test runner\n \"process\",\n \"require\",\n \"module\",\n \"exports\",\n \"__vitest_worker__\",\n \"__vitest_mocker__\",\n \"VITEST_POOL_ID\",\n]);\n\nexport default {\n name: \"tailor-runtime\",\n viteEnvironment: \"ssr\",\n\n async setup(global: typeof globalThis) {\n const g = global as Record<string, unknown>;\n\n const temporalDescriptor = Object.getOwnPropertyDescriptor(g, \"Temporal\");\n const needsTemporal = g.Temporal === undefined;\n const temporal = needsTemporal\n ? (await import(\"temporal-polyfill/full/implementation\")).Temporal\n : undefined;\n\n // Save and remove all non-whitelisted globals\n const saved: Record<string, PropertyDescriptor> = {};\n for (const key of Object.getOwnPropertyNames(g)) {\n if (!ALLOWED_GLOBALS.has(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(g, key);\n if (descriptor?.configurable) {\n saved[key] = descriptor;\n delete g[key];\n }\n }\n }\n\n // Install the base platform surface after whitelist cleanup. Per-namespace\n // mocks (workflow, tailordb, …) are installed on demand by `using xMock()`.\n installPlatformGlobals(global);\n if (needsTemporal) {\n Object.defineProperty(g, \"Temporal\", {\n value: temporal,\n writable: true,\n configurable: true,\n });\n }\n\n return {\n teardown(global: typeof globalThis) {\n cleanupPlatformGlobals(global);\n\n if (needsTemporal) {\n if (temporalDescriptor) {\n Object.defineProperty(global, \"Temporal\", temporalDescriptor);\n } else {\n Reflect.deleteProperty(global, \"Temporal\");\n }\n }\n\n // Restore removed globals\n const g = global as Record<string, unknown>;\n for (const [key, descriptor] of Object.entries(saved)) {\n Object.defineProperty(g, key, descriptor);\n }\n },\n };\n },\n};\n"],"mappings":"0GAcA,MAAM,EAAkB,IAAI,IAAI,CAC9B,GAAG,EAIH,EAGA,UACA,UACA,SACA,UACA,oBACA,oBACA,gBACF,CAAC,EAED,IAAA,EAAe,CACb,KAAM,iBACN,gBAAiB,MAEjB,MAAM,MAAM,EAA2B,CACrC,IAAM,EAAI,EAEJ,EAAqB,OAAO,yBAAyB,EAAG,UAAU,EAClE,EAAgB,EAAE,WAAa,IAAA,GAC/B,EAAW,GACZ,MAAM,OAAO,yCAAA,CAA0C,SACxD,IAAA,GAGE,EAA4C,CAAC,EACnD,IAAK,IAAM,KAAO,OAAO,oBAAoB,CAAC,EAC5C,GAAI,CAAC,EAAgB,IAAI,CAAG,EAAG,CAC7B,IAAM,EAAa,OAAO,yBAAyB,EAAG,CAAG,EACrD,GAAY,eACd,EAAM,GAAO,EACb,OAAO,EAAE,GAEb,CAcF,OATA,EAAuB,CAAM,EACzB,GACF,OAAO,eAAe,EAAG,WAAY,CACnC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC,EAGI,CACL,SAAS,EAA2B,CAClC,EAAuB,CAAM,EAEzB,IACE,EACF,OAAO,eAAe,EAAQ,WAAY,CAAkB,EAE5D,QAAQ,eAAe,EAAQ,UAAU,GAK7C,IAAM,EAAI,EACV,IAAK,GAAM,CAAC,EAAK,KAAe,OAAO,QAAQ,CAAK,EAClD,OAAO,eAAe,EAAG,EAAK,CAAU,CAE5C,CACF,CACF,CACF"}
|
package/docs/github-actions.md
CHANGED
|
@@ -26,10 +26,10 @@ lives):
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# Branch target: deploy to stg on every push to main
|
|
29
|
-
tailor setup branch --name my-app-stg
|
|
29
|
+
tailor setup ci branch --name my-app-stg
|
|
30
30
|
|
|
31
31
|
# Tag target: deploy to production when a tag is pushed, with an approval gate
|
|
32
|
-
tailor setup tag --name my-app-prod \
|
|
32
|
+
tailor setup ci tag --name my-app-prod \
|
|
33
33
|
--branch main --environment production
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -54,9 +54,9 @@ The branch target fires on pull requests and pushes to the branch you specify
|
|
|
54
54
|
omitted):
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
tailor setup branch --name my-app-stg
|
|
57
|
+
tailor setup ci branch --name my-app-stg
|
|
58
58
|
# Equivalent to:
|
|
59
|
-
tailor setup branch --name my-app-stg --target main
|
|
59
|
+
tailor setup ci branch --name my-app-stg --target main
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
What it does:
|
|
@@ -79,7 +79,7 @@ Pass `--erd-preview` on a branch target to add TailorDB ERD preview artifacts
|
|
|
79
79
|
to pull requests:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
tailor setup branch --name my-app-stg --erd-preview
|
|
82
|
+
tailor setup ci branch --name my-app-stg --erd-preview
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
The generated workflow runs `tailor tailordb erd`, which is provided by the
|
|
@@ -103,7 +103,7 @@ write PR comments.
|
|
|
103
103
|
`--erd-preview` is only available for branch targets. The namespace list is
|
|
104
104
|
recorded in `.github/tailor.lock`; the pull request workflow compares the head
|
|
105
105
|
and base lock files so newly added or removed namespaces can still produce
|
|
106
|
-
all-added or all-removed viewer artifacts. Re-run `setup branch` after adding or
|
|
106
|
+
all-added or all-removed viewer artifacts. Re-run `setup ci branch` after adding or
|
|
107
107
|
removing TailorDB namespaces. `setup check` reports drift when the recorded ERD
|
|
108
108
|
preview namespaces no longer match the current config.
|
|
109
109
|
|
|
@@ -113,7 +113,7 @@ The tag target fires when a tag matching `--tag-pattern` (default `v*`) is
|
|
|
113
113
|
pushed:
|
|
114
114
|
|
|
115
115
|
```bash
|
|
116
|
-
tailor setup tag --name my-app-prod \
|
|
116
|
+
tailor setup ci tag --name my-app-prod \
|
|
117
117
|
--tag-pattern "v*" --branch main --environment production
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -317,7 +317,7 @@ you can deploy any commit regardless of branch membership.
|
|
|
317
317
|
For a monorepo where your SDK app lives in a subdirectory, pass `--dir`:
|
|
318
318
|
|
|
319
319
|
```bash
|
|
320
|
-
tailor setup branch --name my-app --dir apps/backend
|
|
320
|
+
tailor setup ci branch --name my-app --dir apps/backend
|
|
321
321
|
```
|
|
322
322
|
|
|
323
323
|
The generated workflow adds a `paths` filter on `apps/backend/**` so the
|
|
@@ -382,10 +382,10 @@ A typical setup with staging and production:
|
|
|
382
382
|
|
|
383
383
|
```bash
|
|
384
384
|
# Staging: main → stg (deploy on every push to main)
|
|
385
|
-
tailor setup branch --name my-app-stg
|
|
385
|
+
tailor setup ci branch --name my-app-stg
|
|
386
386
|
|
|
387
387
|
# Production: tagged commits → prod, with approval gate and branch guard
|
|
388
|
-
tailor setup tag --name my-app-prod \
|
|
388
|
+
tailor setup ci tag --name my-app-prod \
|
|
389
389
|
--branch main --environment production
|
|
390
390
|
```
|
|
391
391
|
|
|
@@ -437,7 +437,7 @@ Add your own rules freely; re-running `tailor setup deps` does not overwrite
|
|
|
437
437
|
them. To remove it, delete the file.
|
|
438
438
|
|
|
439
439
|
Renovate updates the SDK dependency and action pins, but it does not regenerate
|
|
440
|
-
the workflow template. After an SDK update, `tailor setup check
|
|
440
|
+
the workflow template. After an SDK update, `tailor setup check` reports a
|
|
441
441
|
template-version warning until you re-run the relevant workflow setup
|
|
442
442
|
subcommand.
|
|
443
443
|
|
|
@@ -451,19 +451,26 @@ newer template is available, `tailor.config.ts` is no longer under the recorded
|
|
|
451
451
|
trigger. It exits non-zero when it finds drift, so you can run it in CI. Each
|
|
452
452
|
finding names a stable rule key for future suppression.
|
|
453
453
|
|
|
454
|
-
Workflows generated by `setup branch`, `setup tag`, `setup preview`, and
|
|
455
|
-
`setup coordinate` self-audit: each contains a `tailor-drift-check` step that
|
|
454
|
+
Workflows generated by `setup ci branch`, `setup ci tag`, `setup ci preview`, and
|
|
455
|
+
`setup ci coordinate` self-audit: each contains a `tailor-drift-check` step that
|
|
456
456
|
runs the check in CI. Preview workflows run it alongside each preview deploy,
|
|
457
457
|
so pull requests that deploy no preview (drafts, fork PRs, and unlabeled PRs
|
|
458
458
|
in label-triggered mode) skip the check. A single run audits every target
|
|
459
459
|
recorded in `.github/tailor.lock`, so per-app composite actions generated by
|
|
460
|
-
`setup action` are covered by their coordinator's step and do not carry one
|
|
461
|
-
their own.
|
|
460
|
+
`setup ci action` are covered by their coordinator's step and do not carry one
|
|
461
|
+
of their own.
|
|
462
462
|
|
|
463
463
|
Drift findings are advisory by default. Set the repository variable
|
|
464
464
|
`TAILOR_PLATFORM_FAIL_ON_DRIFT` to `true` to make unsuppressed findings fail
|
|
465
465
|
the job. Execution and configuration errors fail regardless of this variable.
|
|
466
466
|
|
|
467
|
+
Running `check` on your own machine also verifies that
|
|
468
|
+
`TAILOR_PLATFORM_WORKSPACE_ID` is set locally for any branch, tag, or
|
|
469
|
+
coordinate target, since those workflows read it directly. `check` detects on
|
|
470
|
+
its own when it is running in CI (no flag needed) and skips that local-only
|
|
471
|
+
verification there, since the deploy job resolves the Environment variable
|
|
472
|
+
itself at runtime.
|
|
473
|
+
|
|
467
474
|
## Updating the generated workflow
|
|
468
475
|
|
|
469
476
|
When you upgrade the SDK, re-run the relevant workflow setup subcommand with
|
package/docs/migration/v3.md
CHANGED
|
@@ -89,39 +89,6 @@ unchanged unless it documents a command to type.
|
|
|
89
89
|
|
|
90
90
|
</details>
|
|
91
91
|
|
|
92
|
-
## setup branch --branch → --target
|
|
93
|
-
|
|
94
|
-
**Migration:** Partially automatic
|
|
95
|
-
|
|
96
|
-
Rename the `--branch` option of `tailor setup branch` invocations to `--target`. `--branch` remains as a deprecated alias until it is removed in v3. The `--branch` option of `setup tag`, `setup preview`, and `setup coordinate` is unchanged.
|
|
97
|
-
|
|
98
|
-
Before:
|
|
99
|
-
|
|
100
|
-
```sh
|
|
101
|
-
tailor setup branch --name my-app-stg --branch main
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
After:
|
|
105
|
-
|
|
106
|
-
```sh
|
|
107
|
-
tailor setup branch --name my-app-stg --target main
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
<details>
|
|
111
|
-
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
112
|
-
|
|
113
|
-
```text
|
|
114
|
-
The `--branch` option of `tailor setup branch` is renamed to `--target`;
|
|
115
|
-
the old spelling is removed in v3. Replace any remaining `--branch` options of
|
|
116
|
-
`setup branch` invocations the codemod did not rewrite (e.g. wrapped across
|
|
117
|
-
lines or invoked through a package runner such as `npx @tailor-platform/sdk`)
|
|
118
|
-
with `--target`. Do not touch the `--branch` option of `setup tag`,
|
|
119
|
-
`setup preview`, or `setup coordinate`, which keeps its name, and leave prose
|
|
120
|
-
that merely mentions the option unchanged unless it documents a command to type.
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
</details>
|
|
124
|
-
|
|
125
92
|
## relation() toward.type → toward.table
|
|
126
93
|
|
|
127
94
|
**Migration:** Partially automatic
|
|
@@ -120,7 +120,7 @@ createResolver({
|
|
|
120
120
|
});
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
### Date Values
|
|
123
|
+
### Date and Time Values
|
|
124
124
|
|
|
125
125
|
`t.date()` uses `YYYY-MM-DD` strings by default. Use `t.date({ as: "date" })` to work with JavaScript `Date` values in the resolver body and input validators:
|
|
126
126
|
|
|
@@ -143,6 +143,58 @@ This option also works in nested objects and with `array: true` or `optional: tr
|
|
|
143
143
|
|
|
144
144
|
An executor subscribing to the resolver with `resolverExecutedTrigger` receives the event as JSON, so `result` holds the `YYYY-MM-DD` string rather than a `Date`.
|
|
145
145
|
|
|
146
|
+
Use `t.date({ as: "temporal" })` to work with the [`Temporal.PlainDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate) value instead:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
createResolver({
|
|
150
|
+
name: "nextDay",
|
|
151
|
+
operation: "query",
|
|
152
|
+
input: { day: t.date({ as: "temporal" }) },
|
|
153
|
+
body: ({ input }) => input.day.add({ days: 1 }),
|
|
154
|
+
output: t.date({ as: "temporal" }),
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`Temporal.PlainDate` has no time zone, so date arithmetic is unambiguous. It works the same as `as: "date"` otherwise: `array`/`optional`/nested objects are supported, input must be a valid calendar date, output must have a 4-digit year (0000-9999), and an executor receiving the event through `resolverExecutedTrigger` sees the `YYYY-MM-DD` string.
|
|
159
|
+
|
|
160
|
+
`t.datetime` and `t.time` also support both representations:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
createResolver({
|
|
164
|
+
name: "reschedule",
|
|
165
|
+
operation: "query",
|
|
166
|
+
input: {
|
|
167
|
+
at: t.datetime({ as: "temporal" }),
|
|
168
|
+
time: t.time({ as: "temporal" }),
|
|
169
|
+
},
|
|
170
|
+
body: ({ input }) => ({
|
|
171
|
+
at: input.at.add({ hours: 1 }),
|
|
172
|
+
time: input.time.add({ minutes: 30 }),
|
|
173
|
+
}),
|
|
174
|
+
output: {
|
|
175
|
+
at: t.datetime({ as: "temporal" }),
|
|
176
|
+
time: t.time({ as: "temporal" }),
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
- **Datetime**: `t.datetime({ as: "temporal" })` uses `Temporal.Instant`; `t.datetime({ as: "date" })` uses `Date`. Input must be a valid ISO datetime with seconds and a UTC offset or `Z`; leap seconds are rejected. Output uses UTC (`Z`) and must have a 4-digit UTC year (0000-9999). `Temporal.Instant` preserves nanoseconds during SDK conversion, but the Platform truncates datetimes to milliseconds. `Date` itself has only millisecond precision. Without `as`, the existing behavior is unchanged: input is a string, and output accepts `string | Date`. Explicit `as: "string"` types the value as `string`.
|
|
182
|
+
- **Time**: `t.time({ as: "temporal" })` uses `Temporal.PlainTime`; `t.time({ as: "date" })` uses a `Date` on `1970-01-01` in UTC. Input and output use `HH:mm` in the range `00:00`–`23:59`. For `Date` output, only the UTC hours and minutes are used; the date portion is ignored. Both representations truncate seconds and fractional seconds without rounding up: `12:30:59.999` becomes `12:30`. Use UTC getters/setters when changing a `Date` time. Without `as`, or with `as: "string"`, time values remain strings.
|
|
183
|
+
|
|
184
|
+
All three field types support `array`, `optional`, nested objects, and input validators with the selected representation. Both deployed resolvers and `tailor function run` convert input and output. Executors using `resolverExecutedTrigger` receive date, datetime, and time results as strings.
|
|
185
|
+
|
|
186
|
+
The SDK supplies Temporal types, so existing projects can use `as: "temporal"` without changing `compilerOptions.lib`. To construct values or name their types, import `Temporal` from the SDK:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { Temporal } from "@tailor-platform/sdk/runtime";
|
|
190
|
+
|
|
191
|
+
const day: Temporal.PlainDate = Temporal.PlainDate.from("2026-09-07");
|
|
192
|
+
const at: Temporal.Instant = Temporal.Instant.from("2026-09-07T12:30:00Z");
|
|
193
|
+
const time: Temporal.PlainTime = Temporal.PlainTime.from("12:30:59.999");
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
This import uses the runtime's Temporal implementation. Deployed resolvers and `tailor function run` use the Tailor Platform's native Temporal. The SDK's [`tailor-runtime` Vitest environment](../testing.md) installs a polyfill when Node.js does not provide Temporal; no Node.js flags or separate polyfill setup are needed. Other local runtimes must provide Temporal to construct or parse Temporal values. Importing the SDK and defining fields does not require it, so CLI configuration loading works on Node.js without Temporal. The SDK does not add ambient global Temporal types or include the polyfill in deployed functions.
|
|
197
|
+
|
|
146
198
|
### Custom Type Name (`typeName`)
|
|
147
199
|
|
|
148
200
|
Enum and nested object fields in input/output schemas generate protobuf type names automatically (e.g., `{ResolverName}{FieldName}`). Use `typeName()` to set a custom name:
|
package/docs/testing.md
CHANGED
|
@@ -475,6 +475,23 @@ export default defineConfig({
|
|
|
475
475
|
|
|
476
476
|
Inline projects inherit the root-level `tailorRuntime()` plugin by default on Vitest 5. On Vitest 4, add `extends: true` to each project; without it, `node:*` import blocking silently does not run.
|
|
477
477
|
|
|
478
|
+
### Temporal
|
|
479
|
+
|
|
480
|
+
The `tailor-runtime` environment supplies `Temporal` when Node.js does not provide it, including non-ISO calendars. An existing native implementation is preserved. No `test.execArgv` flags or separate polyfill setup are needed, and the environment restores the original global on teardown.
|
|
481
|
+
|
|
482
|
+
Use the SDK import for both values and types without changing your TypeScript `lib` settings:
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
import { Temporal } from "@tailor-platform/sdk/runtime";
|
|
486
|
+
|
|
487
|
+
test("adds one day", () => {
|
|
488
|
+
const day: Temporal.PlainDate = Temporal.PlainDate.from("2026-09-07");
|
|
489
|
+
expect(day.add({ days: 1 }).toString()).toBe("2026-09-08");
|
|
490
|
+
});
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
The polyfill is loaded by the test environment only. Deployed functions use the Platform's native Temporal.
|
|
494
|
+
|
|
478
495
|
### Known Limitations
|
|
479
496
|
|
|
480
497
|
- **`process` and `require`** are not removed or blocked. Vitest's internal runner depends on them extensively. On the real platform runtime, they do not exist.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"@inquirer/core": "12.0.3",
|
|
159
159
|
"@inquirer/prompts": "8.7.2",
|
|
160
160
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
161
|
-
"@napi-rs/keyring": "2.
|
|
161
|
+
"@napi-rs/keyring": "2.1.0",
|
|
162
162
|
"@opentelemetry/api": "1.9.1",
|
|
163
163
|
"@opentelemetry/exporter-trace-otlp-proto": "0.222.0",
|
|
164
164
|
"@opentelemetry/resources": "2.11.0",
|
|
@@ -195,10 +195,12 @@
|
|
|
195
195
|
"semver": "7.8.5",
|
|
196
196
|
"sql-highlight": "6.1.0",
|
|
197
197
|
"std-env": "4.2.0",
|
|
198
|
+
"temporal-polyfill": "1.0.5",
|
|
199
|
+
"temporal-spec": "1.0.1",
|
|
198
200
|
"ts-cron-validator": "1.1.5",
|
|
199
201
|
"type-fest": "5.9.0",
|
|
200
202
|
"xdg-basedir": "5.1.0",
|
|
201
|
-
"zod": "4.6.
|
|
203
|
+
"zod": "4.6.5"
|
|
202
204
|
},
|
|
203
205
|
"devDependencies": {
|
|
204
206
|
"@electric-sql/pglite": "0.5.8",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,t}from"./application-DEkgf2w1.mjs";export{t as defineApplication,e as generatePluginFilesIfNeeded};
|
package/dist/date-CGBZbMW5.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function formatDate(e){let t=e.getUTCFullYear();if(!Number.isFinite(t)||t<0||t>9999){let n=Number.isNaN(e.getTime())?`an invalid Date`:`year ${t}`;throw RangeError(`Expected a Date with a 4-digit year (0000-9999), but received ${n}`)}return`${String(t).padStart(4,`0`)}-${String(e.getUTCMonth()+1).padStart(2,`0`)}-${String(e.getUTCDate()).padStart(2,`0`)}`}function serialize(e,t,n){if(t==null)return t;if(e.metadata.array){if(!Array.isArray(t))return t;let r=t.map((t,r)=>serializeValue(e,t,`${n}[${r}]`));return r.every((e,n)=>e===t[n])?t:r}return serializeValue(e,t,n)}function describePathTarget(e){return e||`the top-level value`}function truncateForDescription(e){return e.length>100?`${e.slice(0,100)}...`:e}function describeReceivedValue(e){if(Array.isArray(e)){let t=e.slice(0,100),n=[...new Set(Array.from(t,e=>typeof e))];return n.length>0?`an array of ${n.join(`/`)}`:`an empty array`}if(typeof e==`string`)return`a string (${JSON.stringify(truncateForDescription(e))})`;let t=typeof e;return t===`object`?`an object`:t===`function`?`a function`:`a ${t} (${truncateForDescription(String(e))})`}function serializeValue(e,t,n){if(t==null)return t;if(e.type===`date`&&e.metadata.as===`date`){if(!(t instanceof Date))throw TypeError(`Expected a Date instance at ${describePathTarget(n)}, but received ${describeReceivedValue(t)}`);try{return formatDate(t)}catch(e){let t=e instanceof Error?e.message:String(e);throw RangeError(`Invalid date at ${describePathTarget(n)}: ${t}`,{cause:e})}}if(e.type!==`nested`||typeof t!=`object`||Array.isArray(t))return t;let r=t,i=r;for(let[t,a]of Object.entries(e.fields)){let e=serialize(a,r[t],n?`${n}.${t}`:t);e!==r[t]&&(i===r&&(i={...r}),Object.defineProperty(i,t,{value:e,enumerable:!0,configurable:!0,writable:!0}))}return i}function serializeDateFields(e,t){return serialize(e,t,``)}export{serializeDateFields as n,formatDate as t};
|
|
2
|
-
//# sourceMappingURL=date-CGBZbMW5.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"date-CGBZbMW5.mjs","names":[],"sources":["../src/runtime/date.ts"],"sourcesContent":["import type { FieldMetadata, TailorFieldType } from \"#/configure/types/field.types\";\n\n/**\n * Format a Date using its UTC calendar date.\n * @param date - Date to format\n * @returns Date string in YYYY-MM-DD format\n */\nexport function formatDate(date: Date): string {\n const year = date.getUTCFullYear();\n if (!Number.isFinite(year) || year < 0 || year > 9999) {\n const received = Number.isNaN(date.getTime()) ? \"an invalid Date\" : `year ${year}`;\n throw new RangeError(\n `Expected a Date with a 4-digit year (0000-9999), but received ${received}`,\n );\n }\n return `${String(year).padStart(4, \"0\")}-${String(date.getUTCMonth() + 1).padStart(2, \"0\")}-${String(date.getUTCDate()).padStart(2, \"0\")}`;\n}\n\ntype DateField = {\n readonly type: TailorFieldType;\n readonly metadata: FieldMetadata;\n readonly fields: Record<string, DateField>;\n};\n\nfunction serialize(field: DateField, value: unknown, path: string): unknown {\n if (value === null || value === undefined) return value;\n if (field.metadata.array) {\n if (!Array.isArray(value)) return value;\n const converted = value.map((item, index) => serializeValue(field, item, `${path}[${index}]`));\n return converted.every((item, index) => item === value[index]) ? value : converted;\n }\n return serializeValue(field, value, path);\n}\n\nfunction describePathTarget(path: string): string {\n return path || \"the top-level value\";\n}\n\nconst MAX_DESCRIBED_VALUE_LENGTH = 100;\nconst MAX_DESCRIBED_ARRAY_SAMPLE = 100;\n\nfunction truncateForDescription(text: string): string {\n return text.length > MAX_DESCRIBED_VALUE_LENGTH\n ? `${text.slice(0, MAX_DESCRIBED_VALUE_LENGTH)}...`\n : text;\n}\n\nfunction describeReceivedValue(value: unknown): string {\n if (Array.isArray(value)) {\n const sample = value.slice(0, MAX_DESCRIBED_ARRAY_SAMPLE);\n const elementTypes = [...new Set(Array.from(sample, (item) => typeof item))];\n return elementTypes.length > 0 ? `an array of ${elementTypes.join(\"/\")}` : \"an empty array\";\n }\n if (typeof value === \"string\")\n return `a string (${JSON.stringify(truncateForDescription(value))})`;\n const type = typeof value;\n if (type === \"object\") return \"an object\";\n if (type === \"function\") return \"a function\";\n return `a ${type} (${truncateForDescription(String(value))})`;\n}\n\nfunction serializeValue(field: DateField, value: unknown, path: string): unknown {\n if (value === null || value === undefined) return value;\n if (field.type === \"date\" && field.metadata.as === \"date\") {\n if (!(value instanceof Date)) {\n throw new TypeError(\n `Expected a Date instance at ${describePathTarget(path)}, but received ${describeReceivedValue(value)}`,\n );\n }\n try {\n return formatDate(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new RangeError(`Invalid date at ${describePathTarget(path)}: ${reason}`, {\n cause: error,\n });\n }\n }\n if (field.type !== \"nested\" || typeof value !== \"object\" || Array.isArray(value)) return value;\n const record = value as Record<string, unknown>;\n let result = record;\n for (const [key, child] of Object.entries(field.fields)) {\n const converted = serialize(child, record[key], path ? `${path}.${key}` : key);\n if (converted !== record[key]) {\n if (result === record) result = { ...record };\n Object.defineProperty(result, key, {\n value: converted,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n }\n return result;\n}\n\n/**\n * Convert fields using the Date representation to YYYY-MM-DD strings in UTC.\n * @param field - Date or object field defining the value's shape\n * @param value - Value to serialize\n * @returns Value with Date fields converted to strings\n * @internal\n */\nexport function serializeDateFields(field: DateField, value: unknown): unknown {\n return serialize(field, value, \"\");\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./date-CGBZbMW5.mjs";const t={uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,date:/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,time:/^(?<hour>[01]\d|2[0-3]):(?<minute>[0-5]\d)$/,datetime:/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})[Tt](?<hour>[01]\d|2[0-3]):(?<minute>[0-5]\d):(?<second>[0-5]\d|60)(\.(?<fraction>\d+))?(?<offset>[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/,decimal:/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/};function isNestedObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&!(e instanceof Date)}function validateBaseValue(e){let{field:n,value:r,pathArray:i,issues:a}=e,o=i.length>0?i:void 0,s=a.length;switch(n.type){case`string`:typeof r!=`string`&&a.push({message:`Expected a string: received ${String(r)}`,path:o});break;case`integer`:(typeof r!=`number`||!Number.isInteger(r))&&a.push({message:`Expected an integer: received ${String(r)}`,path:o});break;case`float`:(typeof r!=`number`||!Number.isFinite(r))&&a.push({message:`Expected a number: received ${String(r)}`,path:o});break;case`boolean`:typeof r!=`boolean`&&a.push({message:`Expected a boolean: received ${String(r)}`,path:o});break;case`uuid`:(typeof r!=`string`||!t.uuid.test(r))&&a.push({message:`Expected a valid UUID: received ${String(r)}`,path:o});break;case`date`:(typeof r!=`string`||!t.date.test(r))&&a.push({message:`Expected to match "yyyy-MM-dd" format: received ${String(r)}`,path:o});break;case`datetime`:(typeof r!=`string`||!t.datetime.test(r))&&a.push({message:`Expected to match ISO format: received ${String(r)}`,path:o});break;case`time`:(typeof r!=`string`||!t.time.test(r))&&a.push({message:`Expected to match "HH:mm" format: received ${String(r)}`,path:o});break;case`decimal`:(typeof r!=`string`||!t.decimal.test(r))&&a.push({message:`Expected a decimal string: received ${String(r)}`,path:o});break;case`enum`:if(n._metadata.allowedValues){let e=n._metadata.allowedValues.map(e=>e.value);(typeof r!=`string`||!e.includes(r))&&a.push({message:`Must be one of [${e.join(`, `)}]: received ${String(r)}`,path:o})}break;case`nested`:{if(!isNestedObject(r))return a.push({message:`Expected an object: received ${String(r)}`,path:o}),!1;let t=!0;for(let[a,o]of Object.entries(n.fields)){let n=r[a];validateBaseField({...e,field:o,value:n,pathArray:i.concat(a)})||(t=!1)}return t}}return a.length===s}function validateCustomValue(e,t){let{value:n,pathArray:r,issues:i}=e,a=r.length>0?r:void 0;for(let e of t){let t=e({value:n});typeof t==`string`&&i.push({message:t,path:a})}}function validateBaseField(e){let{field:t,value:n,pathArray:r,issues:i}=e,a=r.length>0?r:void 0,o=n==null;if(t._metadata.required&&o)return i.push({message:`Required field is missing`,path:a}),!1;if(!t._metadata.required&&o)return!0;let s=!0;if(t._metadata.array){if(!Array.isArray(n))return i.push({message:`Expected an array`,path:a}),!1;for(let t=0;t<n.length;t++)validateBaseValue({...e,value:n[t],pathArray:r.concat(`[${t}]`)})||(s=!1)}else s=validateBaseValue(e);return s}function validateCustomField(e){let{field:t,value:n,pathArray:r}=e;if(n==null)return;if(t.type===`nested`){let i=t._metadata.array?n:[n];for(let n=0;n<i.length;n++){let a=i[n],o=t._metadata.array?r.concat(`[${n}]`):r;for(let[n,r]of Object.entries(t.fields))validateCustomField({...e,field:r,value:a[n],pathArray:o.concat(n)})}}let i=t._metadata.validate;i?.length&&validateCustomValue(e,i)}function parseInternal(e){let{value:t}=e,n=[],r={...e,issues:n};return validateBaseField(r)&&(t=deserializeDates(r),n.length===0&&validateCustomField({...r,value:t})),n.length>0?{issues:n}:{value:t??null}}function deserializeDates(t){let{field:n,value:r,issues:i,pathArray:a}=t;if(r==null)return r;let convert=(r,a)=>{if(n.type===`date`&&n._metadata.as===`date`){let t=new Date(`${r}T00:00:00.000Z`);return(!Number.isFinite(t.getTime())||e(t)!==r)&&i.push({message:`Expected a valid calendar date: received ${r}`,path:a.length>0?a:void 0}),t}if(n.type!==`nested`)return r;let o=r,s=o;for(let[e,r]of Object.entries(n.fields)){let n=deserializeDates({...t,field:r,value:o[e],pathArray:a.concat(e)});n!==o[e]&&(s===o&&(s={...o}),Object.defineProperty(s,e,{value:n,enumerable:!0,configurable:!0,writable:!0}))}return s};if(!n._metadata.array)return convert(r,a);let o=r,s=o.map((e,t)=>convert(e,a.concat(`[${t}]`)));return s.every((e,t)=>e===o[t])?r:s}function parseInputFields(e){let{fields:t,...n}=e;return parseInternal({...n,field:{type:`nested`,fields:t,_metadata:{required:!0}},pathArray:[]})}export{parseInputFields as n,parseInternal as r,isNestedObject as t};
|
|
2
|
-
//# sourceMappingURL=field-parse-CzlKC4b7.mjs.map
|