import { clone } from "es-toolkit";

//#region src/configure/types/field.ts
function mapAllowedValues(values) {
	return values.map((value) => {
		if (typeof value === "string") return {
			value,
			description: ""
		};
		return {
			...value,
			description: value.description ?? ""
		};
	});
}

//#endregion
//#region src/configure/types/type.ts
const regex = {
	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>\d{2}):(?<minute>\d{2})$/,
	datetime: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(.(?<millisec>\d{3}))?Z$/
};
var TailorField = class TailorField {
	_metadata;
	_defined = void 0;
	_output = void 0;
	get metadata() {
		return { ...this._metadata };
	}
	constructor(type, options, fields = {}, values) {
		this.type = type;
		this.fields = fields;
		this._metadata = { required: true };
		if (options) {
			if (options.optional === true) this._metadata.required = false;
			if (options.array === true) this._metadata.array = true;
		}
		if (values) this._metadata.allowedValues = mapAllowedValues(values);
	}
	static create(type, options, fields, values) {
		return new TailorField(type, options, fields, values);
	}
	description(description) {
		this._metadata.description = description;
		return this;
	}
	typeName(typeName) {
		this._metadata.typeName = typeName;
		return this;
	}
	validate(...validate) {
		this._metadata.validate = validate;
		return this;
	}
	/**
	* Parse and validate a value against this field's validation rules
	* Returns StandardSchema Result type with success or failure
	*/
	parse(args) {
		return this._parseInternal({
			value: args.value,
			data: args.data,
			user: args.user,
			pathArray: []
		});
	}
	/**
	* Validate a single value (not an array element)
	* Used internally for array element validation
	* @private
	*/
	_validateValue(args) {
		const { value, data, user, pathArray } = args;
		const issues = [];
		switch (this.type) {
			case "string":
				if (typeof value !== "string") issues.push({
					message: `Expected a string: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "integer":
				if (typeof value !== "number" || !Number.isInteger(value)) issues.push({
					message: `Expected an integer: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "float":
				if (typeof value !== "number" || !Number.isFinite(value)) issues.push({
					message: `Expected a number: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "boolean":
				if (typeof value !== "boolean") issues.push({
					message: `Expected a boolean: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "uuid":
				if (typeof value !== "string" || !regex.uuid.test(value)) issues.push({
					message: `Expected a valid UUID: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "date":
				if (typeof value !== "string" || !regex.date.test(value)) issues.push({
					message: `Expected to match "yyyy-MM-dd" format: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "datetime":
				if (typeof value !== "string" || !regex.datetime.test(value)) issues.push({
					message: `Expected to match ISO format: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "time":
				if (typeof value !== "string" || !regex.time.test(value)) issues.push({
					message: `Expected to match "HH:mm:ss" format`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				break;
			case "enum":
				if (this.metadata.allowedValues) {
					const allowedValues = this.metadata.allowedValues.map((v) => v.value);
					if (!allowedValues.includes(value)) issues.push({
						message: `Must be one of [${allowedValues.join(", ")}]: received ${String(value)}`,
						path: pathArray.length > 0 ? pathArray : void 0
					});
				}
				break;
			case "nested":
				if (typeof value !== "object" || value === null || Array.isArray(value)) issues.push({
					message: `Expected an object: received ${String(value)}`,
					path: pathArray.length > 0 ? pathArray : void 0
				});
				else if (this.fields && Object.keys(this.fields).length > 0) for (const [fieldName, field] of Object.entries(this.fields)) {
					const fieldValue = value?.[fieldName];
					const result = field._parseInternal({
						value: fieldValue,
						data,
						user,
						pathArray: pathArray.concat(fieldName)
					});
					if (result.issues) issues.push(...result.issues);
				}
				break;
		}
		const validateFns = this.metadata.validate;
		if (validateFns && validateFns.length > 0) for (const validateInput of validateFns) {
			const { fn, message } = typeof validateInput === "function" ? {
				fn: validateInput,
				message: "Validation failed"
			} : {
				fn: validateInput[0],
				message: validateInput[1]
			};
			if (!fn({
				value,
				data,
				user
			})) issues.push({
				message,
				path: pathArray.length > 0 ? pathArray : void 0
			});
		}
		return issues;
	}
	/**
	* Internal parse method that tracks field path for nested validation
	* @private
	*/
	_parseInternal(args) {
		const { value, data, user, pathArray } = args;
		const issues = [];
		const isNullOrUndefined = value === null || value === void 0;
		if (this.metadata.required && isNullOrUndefined) {
			issues.push({
				message: "Required field is missing",
				path: pathArray.length > 0 ? pathArray : void 0
			});
			return { issues };
		}
		if (!this.metadata.required && isNullOrUndefined) return { value };
		if (this.metadata.array) {
			if (!Array.isArray(value)) {
				issues.push({
					message: "Expected an array",
					path: pathArray.length > 0 ? pathArray : void 0
				});
				return { issues };
			}
			for (let i = 0; i < value.length; i++) {
				const elementValue = value[i];
				const elementPath = pathArray.concat(`[${i}]`);
				const elementIssues = this._validateValue({
					value: elementValue,
					data,
					user,
					pathArray: elementPath
				});
				if (elementIssues.length > 0) issues.push(...elementIssues);
			}
			if (issues.length > 0) return { issues };
			return { value };
		}
		const valueIssues = this._validateValue({
			value,
			data,
			user,
			pathArray
		});
		issues.push(...valueIssues);
		if (issues.length > 0) return { issues };
		return { value };
	}
};
const createField$1 = TailorField.create;
function uuid$1(options) {
	return createField$1("uuid", options);
}
function string$1(options) {
	return createField$1("string", options);
}
function bool$1(options) {
	return createField$1("boolean", options);
}
function int$1(options) {
	return createField$1("integer", options);
}
function float$1(options) {
	return createField$1("float", options);
}
function date$1(options) {
	return createField$1("date", options);
}
function datetime$1(options) {
	return createField$1("datetime", options);
}
function time$1(options) {
	return createField$1("time", options);
}
function _enum$1(values, options) {
	return createField$1("enum", options, void 0, values);
}
function object$1(fields, options) {
	return createField$1("nested", options, fields);
}
const t = {
	uuid: uuid$1,
	string: string$1,
	bool: bool$1,
	int: int$1,
	float: float$1,
	date: date$1,
	datetime: datetime$1,
	time: time$1,
	enum: _enum$1,
	object: object$1
};

//#endregion
//#region src/configure/types/user.ts
/** Represents an unauthenticated user in the Tailor platform. */
const unauthenticatedTailorUser = {
	id: "00000000-0000-0000-0000-000000000000",
	type: "",
	workspaceId: "00000000-0000-0000-0000-000000000000",
	attributes: null,
	attributeList: []
};

//#endregion
//#region src/configure/services/tailordb/permission.ts
/**
* Grants full record-level access without any conditions.
*
* Unsafe and intended only for local development, prototyping, or tests.
* Do not use this in production environments, as it effectively disables
* authorization checks.
*/
const unsafeAllowAllTypePermission = {
	create: [{
		conditions: [],
		permit: true
	}],
	read: [{
		conditions: [],
		permit: true
	}],
	update: [{
		conditions: [],
		permit: true
	}],
	delete: [{
		conditions: [],
		permit: true
	}]
};
/**
* Grants full GraphQL access (all actions) without any conditions.
*
* Unsafe and intended only for local development, prototyping, or tests.
* Do not use this in production environments, as it effectively disables
* authorization checks.
*/
const unsafeAllowAllGqlPermission = [{
	conditions: [],
	actions: "all",
	permit: true
}];

//#endregion
//#region src/configure/services/tailordb/schema.ts
function isRelationSelfConfig(config) {
	return config.toward.type === "self";
}
var TailorDBField = class TailorDBField extends TailorField {
	_ref = void 0;
	_pendingSelfRelation = void 0;
	get reference() {
		return clone(this._ref);
	}
	get metadata() {
		return { ...this._metadata };
	}
	constructor(type, options, fields, values) {
		super(type, options, fields, values);
	}
	static create(type, options, fields, values) {
		return new TailorDBField(type, options, fields, values);
	}
	description(description) {
		return super.description(description);
	}
	relation(config) {
		this._metadata.index = true;
		this._metadata.foreignKey = true;
		this._metadata.unique = ["oneToOne", "1-1"].includes(config.type);
		const key = config.toward.key ?? "id";
		const backward = config.backward ?? "";
		if (isRelationSelfConfig(config)) {
			this._pendingSelfRelation = {
				type: config.type,
				as: config.toward.as,
				key,
				backward
			};
			return this;
		}
		this._metadata.foreignKeyType = config.toward.type.name;
		this._metadata.foreignKeyField = key;
		if (config.type === "keyOnly") return this;
		const forward = config.toward.as;
		this._ref = {
			type: config.toward.type,
			nameMap: [forward, backward],
			key
		};
		this._metadata.relation = true;
		return this;
	}
	index() {
		this._metadata.index = true;
		return this;
	}
	unique() {
		this._metadata.unique = true;
		this._metadata.index = true;
		return this;
	}
	vector() {
		this._metadata.vector = true;
		return this;
	}
	hooks(hooks) {
		this._metadata.hooks = hooks;
		return this;
	}
	validate(...validate) {
		this._metadata.validate = validate;
		return this;
	}
	serial(config) {
		this._metadata.serial = config;
		return this;
	}
	/**
	* Clone the field with optional overrides for field options
	* @param options - Optional field options to override
	* @returns A new TailorDBField instance with the same configuration
	*/
	clone(options) {
		const clonedField = Object.create(Object.getPrototypeOf(this));
		Object.assign(clonedField, {
			type: this.type,
			fields: this.fields,
			_defined: this._defined,
			_output: this._output
		});
		clonedField._metadata = { ...this._metadata };
		if (options) {
			if (options.optional !== void 0) clonedField._metadata.required = !options.optional;
			if (options.array !== void 0) clonedField._metadata.array = options.array;
		}
		if (this._ref) clonedField._ref = clone(this._ref);
		if (this._pendingSelfRelation) clonedField._pendingSelfRelation = { ...this._pendingSelfRelation };
		return clonedField;
	}
};
const createField = TailorDBField.create;
function uuid(options) {
	return createField("uuid", options);
}
function string(options) {
	return createField("string", options);
}
function bool(options) {
	return createField("boolean", options);
}
function int(options) {
	return createField("integer", options);
}
function float(options) {
	return createField("float", options);
}
function date(options) {
	return createField("date", options);
}
function datetime(options) {
	return createField("datetime", options);
}
function time(options) {
	return createField("time", options);
}
function _enum(values, options) {
	return createField("enum", options, void 0, values);
}
function object(fields, options) {
	return createField("nested", options, fields);
}
var TailorDBType = class {
	_output = null;
	_description;
	_settings = {};
	_indexes = [];
	_permissions = {};
	_files = {};
	constructor(name, fields, options) {
		this.name = name;
		this.fields = fields;
		this._description = options.description;
		if (options.pluralForm) {
			if (name === options.pluralForm) throw new Error(`The name and the plural form must be different. name=${name}`);
			this._settings.pluralForm = options.pluralForm;
		}
		Object.entries(this.fields).forEach(([fieldName, field]) => {
			const f = field;
			const pending = f._pendingSelfRelation;
			if (pending) {
				f._metadata.foreignKeyType = this.name;
				f._metadata.foreignKeyField = pending.key;
				if (pending.type === "keyOnly") return this;
				const forward = pending.as ?? fieldName.replace(/(ID|Id|id)$/u, "");
				f._ref = {
					type: this,
					nameMap: [forward, pending.backward],
					key: pending.key
				};
			}
		});
	}
	get metadata() {
		const indexes = {};
		if (this._indexes && this._indexes.length > 0) this._indexes.forEach((index) => {
			const fieldNames = index.fields.map((field) => String(field));
			const key = index.name || `idx_${fieldNames.join("_")}`;
			indexes[key] = {
				fields: fieldNames,
				unique: index.unique
			};
		});
		return {
			name: this.name,
			description: this._description,
			settings: this._settings,
			permissions: this._permissions,
			files: this._files,
			...Object.keys(indexes).length > 0 && { indexes }
		};
	}
	hooks(hooks) {
		Object.entries(hooks).forEach(([fieldName, fieldHooks]) => {
			this.fields[fieldName].hooks(fieldHooks);
		});
		return this;
	}
	validate(validators) {
		Object.entries(validators).forEach(([fieldName, fieldValidators]) => {
			const field = this.fields[fieldName];
			const validators$1 = fieldValidators;
			const isValidateConfig = (v) => {
				return Array.isArray(v) && v.length === 2 && typeof v[1] === "string";
			};
			if (Array.isArray(validators$1)) if (isValidateConfig(validators$1)) field.validate(validators$1);
			else field.validate(...validators$1);
			else field.validate(validators$1);
		});
		return this;
	}
	features(features) {
		this._settings = {
			...this._settings,
			...features
		};
		return this;
	}
	indexes(...indexes) {
		this._indexes = indexes;
		return this;
	}
	files(files) {
		this._files = files;
		return this;
	}
	permission(permission) {
		const ret = this;
		ret._permissions.record = permission;
		return ret;
	}
	gqlPermission(permission) {
		const ret = this;
		ret._permissions.gql = permission;
		return ret;
	}
	description(description) {
		this._description = description;
		return this;
	}
	/**
	* Pick specific fields from the type
	* @param keys - Array of field keys to pick
	* @param options - Optional field options to apply to picked fields
	* @returns An object containing only the specified fields
	*/
	pickFields(keys, options) {
		const result = {};
		for (const key of keys) if (options) result[key] = this.fields[key].clone(options);
		else result[key] = this.fields[key];
		return result;
	}
	/**
	* Omit specific fields from the type
	* @param keys - Array of field keys to omit
	* @returns An object containing all fields except the specified ones
	*/
	omitFields(keys) {
		const keysSet = new Set(keys);
		const result = {};
		for (const key in this.fields) if (Object.hasOwn(this.fields, key) && !keysSet.has(key)) result[key] = this.fields[key];
		return result;
	}
};
const idField = uuid();
function dbType(name, fieldsOrDescription, fields) {
	const typeName = Array.isArray(name) ? name[0] : name;
	const pluralForm = Array.isArray(name) ? name[1] : void 0;
	let description;
	let fieldDef;
	if (typeof fieldsOrDescription === "string") {
		description = fieldsOrDescription;
		fieldDef = fields;
	} else fieldDef = fieldsOrDescription;
	return new TailorDBType(typeName, {
		id: idField,
		...fieldDef
	}, {
		pluralForm,
		description
	});
}
const db = {
	type: dbType,
	uuid,
	string,
	bool,
	int,
	float,
	date,
	datetime,
	time,
	enum: _enum,
	object,
	fields: { timestamps: () => ({
		createdAt: datetime().hooks({ create: () => /* @__PURE__ */ new Date() }).description("Record creation timestamp"),
		updatedAt: datetime({ optional: true }).hooks({ update: () => /* @__PURE__ */ new Date() }).description("Record last update timestamp")
	}) }
};

//#endregion
//#region src/configure/services/auth/index.ts
function defineAuth(name, config) {
	return {
		...config,
		name,
		invoker(machineUser) {
			return {
				namespace: name,
				machineUserName: machineUser
			};
		}
	};
}

//#endregion
//#region src/configure/services/workflow/job.ts
/**
* Symbol used to brand WorkflowJob objects created by createWorkflowJob.
* This enables reliable runtime detection of workflow jobs regardless of
* how they were imported or assigned (variable reassignment, destructuring, etc.)
*/
const WORKFLOW_JOB_BRAND = Symbol.for("tailor:workflow-job");
const createWorkflowJob = (config) => {
	return {
		[WORKFLOW_JOB_BRAND]: true,
		name: config.name,
		trigger: async (args) => {
			const ret = await tailor.workflow.triggerJobFunction(config.name, args);
			return ret ? JSON.parse(JSON.stringify(ret)) : ret;
		},
		body: config.body
	};
};

//#endregion
//#region src/configure/config.ts
let distPath = null;
const getDistDir = () => {
	const configured = process.env.TAILOR_SDK_OUTPUT_DIR;
	if (configured && configured !== distPath) distPath = configured;
	else if (distPath === null) distPath = configured || ".tailor-sdk";
	return distPath;
};
function defineConfig(config) {
	return config;
}
function defineGenerators(...configs) {
	return configs;
}

//#endregion
export { createWorkflowJob as a, unsafeAllowAllGqlPermission as c, TailorField as d, t as f, WORKFLOW_JOB_BRAND as i, unsafeAllowAllTypePermission as l, defineGenerators as n, defineAuth as o, getDistDir as r, db as s, defineConfig as t, unauthenticatedTailorUser as u };
//# sourceMappingURL=config-CtRi0Lgg.mjs.map