"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.maybeOverrideDbtConnection = exports.isGitProjectType = exports.DefaultSupportedDbtVersion = exports.getLatestSupportDbtVersion = exports.DbtVersionOptionLatest = exports.SupportedDbtVersions = exports.mergeWarehouseCredentials = exports.maybeOverrideWarehouseConnection = exports.getColumnTimezone = exports.SnowflakeAuthenticationType = exports.AthenaAuthenticationType = exports.DatabricksAuthenticationType = exports.sensitiveCredentialsFieldNames = exports.BigqueryAuthenticationType = exports.WarehouseTypes = exports.DbtProjectType = exports.ProjectType = void 0;
exports.isDbtVersion110OrHigher = isDbtVersion110OrHigher;
var ProjectType;
(function (ProjectType) {
    ProjectType["DEFAULT"] = "DEFAULT";
    ProjectType["PREVIEW"] = "PREVIEW";
})(ProjectType || (exports.ProjectType = ProjectType = {}));
var DbtProjectType;
(function (DbtProjectType) {
    DbtProjectType["DBT"] = "dbt";
    DbtProjectType["DBT_CLOUD_IDE"] = "dbt_cloud_ide";
    DbtProjectType["GITHUB"] = "github";
    DbtProjectType["GITLAB"] = "gitlab";
    DbtProjectType["BITBUCKET"] = "bitbucket";
    DbtProjectType["AZURE_DEVOPS"] = "azure_devops";
    DbtProjectType["NONE"] = "none";
    DbtProjectType["MANIFEST"] = "manifest";
})(DbtProjectType || (exports.DbtProjectType = DbtProjectType = {}));
var WarehouseTypes;
(function (WarehouseTypes) {
    WarehouseTypes["BIGQUERY"] = "bigquery";
    WarehouseTypes["POSTGRES"] = "postgres";
    WarehouseTypes["REDSHIFT"] = "redshift";
    WarehouseTypes["SNOWFLAKE"] = "snowflake";
    WarehouseTypes["DATABRICKS"] = "databricks";
    WarehouseTypes["TRINO"] = "trino";
    WarehouseTypes["CLICKHOUSE"] = "clickhouse";
    WarehouseTypes["ATHENA"] = "athena";
    WarehouseTypes["DUCKDB"] = "duckdb";
})(WarehouseTypes || (exports.WarehouseTypes = WarehouseTypes = {}));
var BigqueryAuthenticationType;
(function (BigqueryAuthenticationType) {
    BigqueryAuthenticationType["SSO"] = "sso";
    BigqueryAuthenticationType["PRIVATE_KEY"] = "private_key";
    BigqueryAuthenticationType["ADC"] = "adc";
})(BigqueryAuthenticationType || (exports.BigqueryAuthenticationType = BigqueryAuthenticationType = {}));
exports.sensitiveCredentialsFieldNames = [
    'user',
    'password',
    'keyfileContents',
    'personalAccessToken',
    'privateKey',
    'privateKeyPass',
    'sshTunnelPrivateKey',
    'sslcert',
    'sslkey',
    'sslrootcert',
    'token',
    'refreshToken',
    'oauthClientId',
    'oauthClientSecret',
    'accessKeyId',
    'secretAccessKey',
];
var DatabricksAuthenticationType;
(function (DatabricksAuthenticationType) {
    DatabricksAuthenticationType["PERSONAL_ACCESS_TOKEN"] = "personal_access_token";
    DatabricksAuthenticationType["OAUTH_M2M"] = "oauth_m2m";
    DatabricksAuthenticationType["OAUTH_U2M"] = "oauth_u2m";
})(DatabricksAuthenticationType || (exports.DatabricksAuthenticationType = DatabricksAuthenticationType = {}));
var AthenaAuthenticationType;
(function (AthenaAuthenticationType) {
    AthenaAuthenticationType["ACCESS_KEY"] = "access_key";
    AthenaAuthenticationType["IAM_ROLE"] = "iam_role";
})(AthenaAuthenticationType || (exports.AthenaAuthenticationType = AthenaAuthenticationType = {}));
// TODO use enum instead
var SnowflakeAuthenticationType;
(function (SnowflakeAuthenticationType) {
    SnowflakeAuthenticationType["PASSWORD"] = "password";
    SnowflakeAuthenticationType["PRIVATE_KEY"] = "private_key";
    SnowflakeAuthenticationType["SSO"] = "sso";
    SnowflakeAuthenticationType["EXTERNAL_BROWSER"] = "external_browser";
    SnowflakeAuthenticationType["NONE"] = "none";
})(SnowflakeAuthenticationType || (exports.SnowflakeAuthenticationType = SnowflakeAuthenticationType = {}));
// Returns the timezone the column data is in when the query runs.
// Snowflake's dbt translator wraps timestamps with CONVERT_TIMEZONE('UTC', col),
// so columns are UTC unless `disableTimestampConversion` opts out of that wrap.
const getColumnTimezone = (credentials) => {
    if (credentials.type === WarehouseTypes.SNOWFLAKE &&
        !credentials.disableTimestampConversion) {
        return 'UTC';
    }
    return credentials.dataTimezone ?? 'UTC';
};
exports.getColumnTimezone = getColumnTimezone;
const maybeOverrideWarehouseConnection = (connection, overrides) => {
    const isBigquery = connection.type === WarehouseTypes.BIGQUERY;
    const overridesSchema = isBigquery
        ? { dataset: overrides.schema }
        : { schema: overrides.schema };
    return {
        ...connection,
        ...(overrides.schema ? overridesSchema : undefined),
    };
};
exports.maybeOverrideWarehouseConnection = maybeOverrideWarehouseConnection;
/**
 * Merges new warehouse credentials with base credentials, preserving advanced settings
 * like requireUserCredentials from the base credentials.
 *
 * This is useful when creating preview projects where we want to use new connection details
 * (like from dbt profiles) but preserve advanced configuration from the parent project.
 */
const mergeWarehouseCredentials = (baseCredentials, newCredentials) => {
    // If types don't match, return newCredentials as-is (can't merge different warehouse types)
    if (baseCredentials.type !== newCredentials.type) {
        // eslint-disable-next-line no-console
        console.info(`Skipping merge of warehouse credentials due to differing types: ${baseCredentials.type} and ${newCredentials.type}`);
        return newCredentials;
    }
    // Edge case: if the warehouse is snowflake but with a different warehouse, return newCredentials as-is
    // This is to avoid enforcing requireUserCredentials on a different snowflake warehouse that might not have SSO enabled or different roles
    if (baseCredentials.type === WarehouseTypes.SNOWFLAKE &&
        newCredentials.type === WarehouseTypes.SNOWFLAKE &&
        baseCredentials.warehouse.toLowerCase().trim() !==
            newCredentials.warehouse.toLowerCase().trim()) {
        // eslint-disable-next-line no-console
        console.info(`Skipping merge of Snowflake credentials due to differing warehouse names: ${baseCredentials.warehouse} and ${newCredentials.warehouse}`);
        return newCredentials;
    }
    // Only add non sensitive fields from base credentials to avoid conflicts with authentication methods
    const keysToExclude = [
        ...exports.sensitiveCredentialsFieldNames,
        'authenticationType',
    ];
    const filteredBaseCredentials = Object.fromEntries(Object.entries(baseCredentials).filter(([key]) => !keysToExclude.includes(key)));
    // We will use new credentials for connection, this might contain new authentication method
    // do not include all baseCredentials here, to avoid conflicts on authentication (that will cause a mix of serviceaccounts/sso/passwords)
    const merged = {
        ...filteredBaseCredentials, // We copy most of the base config from the parent project, including advanced settings
        ...newCredentials,
        // Keep requireUserCredentials from base credentials, since this is a security setting and should not be overridden
        requireUserCredentials: baseCredentials.requireUserCredentials ||
            newCredentials.requireUserCredentials,
    };
    return merged;
};
exports.mergeWarehouseCredentials = mergeWarehouseCredentials;
var SupportedDbtVersions;
(function (SupportedDbtVersions) {
    SupportedDbtVersions["V1_4"] = "v1.4";
    SupportedDbtVersions["V1_5"] = "v1.5";
    SupportedDbtVersions["V1_6"] = "v1.6";
    SupportedDbtVersions["V1_7"] = "v1.7";
    SupportedDbtVersions["V1_8"] = "v1.8";
    SupportedDbtVersions["V1_9"] = "v1.9";
    SupportedDbtVersions["V1_10"] = "v1.10";
    SupportedDbtVersions["V1_11"] = "v1.11";
})(SupportedDbtVersions || (exports.SupportedDbtVersions = SupportedDbtVersions = {}));
// Make it an enum to avoid TSOA errors
var DbtVersionOptionLatest;
(function (DbtVersionOptionLatest) {
    DbtVersionOptionLatest["LATEST"] = "latest";
})(DbtVersionOptionLatest || (exports.DbtVersionOptionLatest = DbtVersionOptionLatest = {}));
function isDbtVersion110OrHigher(version) {
    if (!version) {
        return false;
    }
    // Get all enum values as an array in order
    const versions = Object.values(SupportedDbtVersions);
    const v110Index = versions.indexOf(SupportedDbtVersions.V1_10);
    const currentIndex = versions.indexOf(version);
    // If the current version is at or after v1.10 in the enum order
    return currentIndex >= v110Index;
}
const getLatestSupportDbtVersion = () => {
    const versions = Object.values(SupportedDbtVersions);
    return versions[versions.length - 1];
};
exports.getLatestSupportDbtVersion = getLatestSupportDbtVersion;
exports.DefaultSupportedDbtVersion = DbtVersionOptionLatest.LATEST;
const isGitProjectType = (connection) => [
    DbtProjectType.GITHUB,
    DbtProjectType.GITLAB,
    DbtProjectType.BITBUCKET,
].includes(connection.type);
exports.isGitProjectType = isGitProjectType;
const isRemoteType = (connection) => [DbtProjectType.DBT, DbtProjectType.DBT_CLOUD_IDE].includes(connection.type);
const maybeOverrideDbtConnection = (connection, overrides) => {
    // If manifest is provided, create a MANIFEST connection type
    if (overrides.manifest) {
        return {
            type: DbtProjectType.MANIFEST,
            manifest: overrides.manifest,
            hideRefreshButton: true,
        };
    }
    return {
        ...connection,
        ...((0, exports.isGitProjectType)(connection) && overrides.branch
            ? { branch: overrides.branch }
            : undefined),
        ...(!isRemoteType(connection) &&
            overrides.environment &&
            overrides.environment.length > 0
            ? { environment: overrides.environment }
            : undefined),
    };
};
exports.maybeOverrideDbtConnection = maybeOverrideDbtConnection;
//# sourceMappingURL=projects.js.map