Updates
This commit is contained in:
@@ -68,6 +68,16 @@ const DataTypes = [
|
||||
value: "0-255",
|
||||
description: "LONGTEXT is just text with max length 4,294,967,295",
|
||||
},
|
||||
{
|
||||
title: "OPTIONS",
|
||||
name: "ENUM",
|
||||
description: "String options to be selected from",
|
||||
},
|
||||
{
|
||||
title: "BOOLEAN",
|
||||
name: "BOOLEAN",
|
||||
description: "True or False. Represented in the database as 0 or 1",
|
||||
},
|
||||
{
|
||||
title: "DECIMAL",
|
||||
name: "DECIMAL",
|
||||
|
||||
@@ -8,4 +8,5 @@ export const AppNames = {
|
||||
WebsocketPathname: "dsql-websocket",
|
||||
ReverseProxyForwardURLHeaderName: "x-original-uri",
|
||||
PrivateAPIAuthHeaderName: "x-api-auth-key",
|
||||
StaticProxyForwardURLHeaderName: "x-media-path",
|
||||
} as const;
|
||||
|
||||
@@ -6,4 +6,6 @@ export const LocalStorageDict = {
|
||||
CSRF: getCsrfHeaderName(),
|
||||
CurrentQueue: "current_queue",
|
||||
DiskUsage: "disk_usage",
|
||||
MarkdownEditorDefaultSideBySide: "markdown_editor_default_side_by_side",
|
||||
MarkdownEditorDefaultPreview: "markdown_editor_default_preview",
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ export default async function handleSocialDb({
|
||||
}: HandleSocialDbFunctionParams): Promise<APIResponseObject> {
|
||||
try {
|
||||
const finalDbName = database;
|
||||
const MAX_IMAGE_STRING_LENGTH = 350;
|
||||
|
||||
const existingSocialUserQUery = `SELECT * FROM users WHERE email = ? AND social_login='1' AND social_platform = ? `;
|
||||
const existingSocialUserValues = [email, social_platform];
|
||||
@@ -127,6 +128,14 @@ export default async function handleSocialDb({
|
||||
};
|
||||
|
||||
Object.keys(payload).forEach((key) => {
|
||||
if (key.match(/image/)) {
|
||||
const imageString = payload[key] as string | undefined;
|
||||
if (
|
||||
!imageString ||
|
||||
imageString.length > MAX_IMAGE_STRING_LENGTH
|
||||
)
|
||||
return;
|
||||
}
|
||||
data[key] = payload[key];
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// @ts-check
|
||||
|
||||
import { DSQL_TableSchemaType } from "../../types";
|
||||
import decrypt from "../dsql/decrypt";
|
||||
import defaultFieldsRegexp from "../dsql/default-fields-regexp";
|
||||
|
||||
type Param = {
|
||||
unparsedResults: any[];
|
||||
tableSchema?: import("../../types").DSQL_TableSchemaType;
|
||||
tableSchema?: DSQL_TableSchemaType;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -15,23 +14,13 @@ type Param = {
|
||||
* function, decrypts encrypted fields, and returns an updated array with no encrypted
|
||||
* fields
|
||||
*/
|
||||
export default async function parseDbResults({
|
||||
export default function parseDbResults({
|
||||
unparsedResults,
|
||||
tableSchema,
|
||||
}: Param): Promise<any[] | null> {
|
||||
/**
|
||||
* Declare variables
|
||||
*
|
||||
* @description Declare "results" variable
|
||||
*/
|
||||
}: Param): any[] | null {
|
||||
let parsedResults = [];
|
||||
|
||||
try {
|
||||
/**
|
||||
* Declare variables
|
||||
*
|
||||
* @description Declare "results" variable
|
||||
*/
|
||||
for (let pr = 0; pr < unparsedResults.length; pr++) {
|
||||
let result = unparsedResults[pr];
|
||||
|
||||
@@ -39,7 +28,9 @@ export default async function parseDbResults({
|
||||
|
||||
for (let i = 0; i < resultFieldNames.length; i++) {
|
||||
const resultFieldName = resultFieldNames[i];
|
||||
let resultFieldSchema = tableSchema?.fields[i];
|
||||
let resultFieldSchema = tableSchema?.fields.find(
|
||||
(fld) => fld.fieldName == resultFieldName
|
||||
);
|
||||
|
||||
if (resultFieldName?.match(defaultFieldsRegexp)) {
|
||||
continue;
|
||||
@@ -48,7 +39,6 @@ export default async function parseDbResults({
|
||||
let value = result[resultFieldName];
|
||||
|
||||
if (typeof value !== "number" && !value) {
|
||||
// parsedResults.push(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -64,14 +54,8 @@ export default async function parseDbResults({
|
||||
parsedResults.push(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare variables
|
||||
*
|
||||
* @description Declare "results" variable
|
||||
*/
|
||||
return parsedResults;
|
||||
} catch (/** @type {any} */ error: any) {
|
||||
console.log("ERROR in parseDbResults Function =>", error.message);
|
||||
} catch (error: any) {
|
||||
return unparsedResults;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ export default async function dbGrabUserResource<
|
||||
error: result?.error,
|
||||
msg: result?.msg,
|
||||
},
|
||||
count: typeof result?.count == "number" ? result.count : undefined,
|
||||
count: typeof result?.count == "number" ? result.count : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ export default function generateColumnDescription({
|
||||
onUpdateLiteral,
|
||||
notNullValue,
|
||||
unique,
|
||||
options,
|
||||
} = columnData;
|
||||
|
||||
let fieldEntryText = "";
|
||||
@@ -41,7 +42,13 @@ export default function generateColumnDescription({
|
||||
finalDataTypeObject.decimal
|
||||
);
|
||||
|
||||
fieldEntryText += `\`${fieldName}\` ${finalDataType}`;
|
||||
if (finalDataType.match(/enum/i) && options?.[0]) {
|
||||
fieldEntryText += `\`${fieldName}\` ${finalDataType}(${options
|
||||
.map((opt) => `'${opt}'`)
|
||||
.join(",")})`;
|
||||
} else {
|
||||
fieldEntryText += `\`${fieldName}\` ${finalDataType}`;
|
||||
}
|
||||
|
||||
if (nullValue) {
|
||||
fieldEntryText += " DEFAULT NULL";
|
||||
|
||||
@@ -118,6 +118,7 @@ export type DSQL_DATASQUIREL_USER_DATABASES = {
|
||||
db_full_name?: string;
|
||||
db_image?: string;
|
||||
db_description?: string;
|
||||
db_long_description?: string;
|
||||
remote_connected?: number;
|
||||
remote_connection_type?: string;
|
||||
remote_db_full_name?: string;
|
||||
@@ -146,6 +147,7 @@ export type DSQL_DATASQUIREL_USER_DATABASE_TABLES = {
|
||||
table_name?: string;
|
||||
table_slug?: string;
|
||||
table_description?: string;
|
||||
table_long_description?: string;
|
||||
child_table?: number;
|
||||
child_table_parent_database_schema_id?: number;
|
||||
child_table_parent_table_schema_id?: number;
|
||||
|
||||
@@ -107,6 +107,7 @@ export interface DSQL_ChildrenTablesType {
|
||||
export const TextFieldTypesArray = [
|
||||
{ title: "Plain Text", value: "plain" },
|
||||
{ title: "Rich Text", value: "richText" },
|
||||
{ title: "Markdown", value: "markdown" },
|
||||
{ title: "JSON", value: "json" },
|
||||
{ title: "YAML", value: "yaml" },
|
||||
{ title: "HTML", value: "html" },
|
||||
@@ -119,6 +120,7 @@ export const TextFieldTypesArray = [
|
||||
export type DSQL_FieldSchemaType = {
|
||||
id?: number | string;
|
||||
fieldName?: string;
|
||||
fieldDescription?: string;
|
||||
originName?: string;
|
||||
updatedField?: boolean;
|
||||
dataType?: string;
|
||||
@@ -1471,6 +1473,7 @@ export type DsqlCrudParam<
|
||||
countOnly?: boolean;
|
||||
dbFullName?: string;
|
||||
dbName?: string;
|
||||
tableSchema?: DSQL_TableSchemaType;
|
||||
};
|
||||
|
||||
export type ErrorCallback = (title: string, error: Error, data?: any) => void;
|
||||
@@ -2137,6 +2140,19 @@ export type SiteConfigMain = {
|
||||
sharp_image_quality?: SiteConfigMainValue;
|
||||
max_backups?: SiteConfigMainValue;
|
||||
max_disk_usage?: SiteConfigMainValue;
|
||||
api_keys?: SiteConfigMainAPIKeysObject;
|
||||
target_ai?: AIOptionsObject;
|
||||
};
|
||||
|
||||
export type SiteConfigMainAPIKeysObject = {
|
||||
[k: string]: SiteConfigMainAPIKeysObjectInfo;
|
||||
};
|
||||
|
||||
export type SiteConfigMainAPIKeysObjectInfo = {
|
||||
key?: string;
|
||||
id?: string;
|
||||
model?: string;
|
||||
custom_model?: string;
|
||||
};
|
||||
|
||||
export type SiteConfigMainValue = {
|
||||
@@ -2629,6 +2645,7 @@ export const OpsActions = [
|
||||
"exit",
|
||||
"test",
|
||||
"restart-web-app",
|
||||
"restart-web-app-container",
|
||||
"restart-db",
|
||||
"restart-all",
|
||||
"clear",
|
||||
@@ -2637,3 +2654,70 @@ export const OpsActions = [
|
||||
export type OpsObject = {
|
||||
action: (typeof OpsActions)[number];
|
||||
};
|
||||
|
||||
export const AIOptions: AIOptionsObject[] = [
|
||||
{
|
||||
name: "openai",
|
||||
title: "Open AI",
|
||||
models: [
|
||||
"gpt-4.1",
|
||||
"gpt-4o",
|
||||
"gpt-4o-audio",
|
||||
"04-mini",
|
||||
"o3",
|
||||
"o3-pro",
|
||||
"o3-mini",
|
||||
"o1",
|
||||
"o1-mini",
|
||||
"o1-pro",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "xai",
|
||||
title: "X-AI",
|
||||
baseUrl: "https://api.x.ai/v1",
|
||||
models: [
|
||||
"grok-4-0709",
|
||||
"grok-3",
|
||||
"grok-3-mini",
|
||||
"grok-3-fast",
|
||||
"grok-3-mini-fast",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "anthropic",
|
||||
models: [
|
||||
"claude-opus-4-0",
|
||||
"claude-sonnet-4-0",
|
||||
"claude-3-7-sonnet-latest",
|
||||
"claude-3-5-sonnet-latest",
|
||||
"claude-3-5-haiku-latest",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "gemini",
|
||||
models: [
|
||||
"gemini-2.5-pro",
|
||||
"gemini-2.5-flash",
|
||||
"gemini-2.5-flash-lite",
|
||||
"gemini-2.5-flash-preview-tts",
|
||||
"gemini-2.5-pro-preview-tts",
|
||||
"gemini-2.0-flash",
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
|
||||
export type AIOptionsObject = {
|
||||
name?: string;
|
||||
title?: string;
|
||||
models?: string[];
|
||||
targetModel?: string;
|
||||
customModel?: string;
|
||||
apiKey?: string;
|
||||
baseUrl?: string;
|
||||
};
|
||||
|
||||
export type AIComponentProps = {
|
||||
targetAI: AIOptionsObject;
|
||||
context: any[];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export default function checkArrayDepth(
|
||||
arr: any[] | any[][] | any[][][] | any,
|
||||
depth: number
|
||||
): boolean {
|
||||
if (!Array.isArray(arr)) return false;
|
||||
if (depth === 1) return true;
|
||||
return arr.every((item) => checkArrayDepth(item, depth - 1));
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import sqlGenerator from "../../functions/dsql/sql/sql-generator";
|
||||
import { APIResponseObject, DsqlCrudParam } from "../../types";
|
||||
import connDbHandler, { ConnDBHandlerQueryObject } from "../db/conn-db-handler";
|
||||
import checkArrayDepth from "../check-array-depth";
|
||||
import parseDbResults from "../../functions/backend/parseDbResults";
|
||||
|
||||
export default async function <
|
||||
T extends { [key: string]: any } = { [key: string]: any }
|
||||
@@ -10,6 +12,7 @@ export default async function <
|
||||
count,
|
||||
countOnly,
|
||||
dbFullName,
|
||||
tableSchema,
|
||||
}: Omit<
|
||||
DsqlCrudParam<T>,
|
||||
"action" | "data" | "sanitize"
|
||||
@@ -55,13 +58,26 @@ export default async function <
|
||||
|
||||
const res = await connDbHandler(undefined, connQueries);
|
||||
|
||||
const parsedRes = checkArrayDepth(res, 2)
|
||||
? parseDbResults({ unparsedResults: res[0], tableSchema })
|
||||
: res[0];
|
||||
const parsedBatchRes = checkArrayDepth(res, 3)
|
||||
? res.map((_r: any[][]) => {
|
||||
return parseDbResults({ unparsedResults: _r[0], tableSchema });
|
||||
})
|
||||
: res;
|
||||
|
||||
const isSuccess = Array.isArray(res) && Array.isArray(res[0]);
|
||||
|
||||
return {
|
||||
success: isSuccess,
|
||||
payload: isSuccess ? (countOnly ? null : res[0]) : null,
|
||||
batchPayload: isSuccess ? (countOnly ? null : res) : null,
|
||||
error: isSuccess ? undefined : res?.error,
|
||||
payload: isSuccess ? (countOnly ? null : parsedRes) : null,
|
||||
batchPayload: isSuccess ? (countOnly ? null : parsedBatchRes) : null,
|
||||
error: isSuccess
|
||||
? undefined
|
||||
: typeof res == "object" && !Array.isArray(res)
|
||||
? res?.error
|
||||
: undefined,
|
||||
errors: res?.errors,
|
||||
queryObject: {
|
||||
sql: queryObject?.string,
|
||||
|
||||
@@ -26,6 +26,7 @@ export default async function dsqlCrud<
|
||||
batchData,
|
||||
deleteKeyValues,
|
||||
debug,
|
||||
tableSchema,
|
||||
} = params;
|
||||
|
||||
const finalData = (sanitize ? sanitize({ data }) : data) as T;
|
||||
@@ -47,6 +48,7 @@ export default async function dsqlCrud<
|
||||
tableName: table,
|
||||
dbFullName,
|
||||
debug,
|
||||
tableSchema,
|
||||
});
|
||||
return INSERT_RESULT;
|
||||
|
||||
@@ -60,6 +62,7 @@ export default async function dsqlCrud<
|
||||
identifierColumnName: (targetField || "id") as string,
|
||||
identifierValue: String(targetValue || targetId),
|
||||
debug,
|
||||
tableSchema,
|
||||
});
|
||||
|
||||
return UPDATE_RESULT;
|
||||
|
||||
@@ -11,6 +11,7 @@ export default function grabTextFieldType(
|
||||
if (field.css) return "css";
|
||||
if (field.javascript) return "javascript";
|
||||
if (field.shell) return "shell";
|
||||
if (field.markdown) return "markdown";
|
||||
if (nullReturn) return undefined;
|
||||
return "plain";
|
||||
}
|
||||
|
||||
@@ -122,15 +122,16 @@ export default function ({
|
||||
/**
|
||||
* Handle scenario where this table is a child of another
|
||||
*/
|
||||
if (
|
||||
currentTableSchema.childTable &&
|
||||
currentTableSchema.childTableDbId &&
|
||||
currentTableSchema.childTableDbId
|
||||
) {
|
||||
const targetParentDatabase = grabPrimaryRequiredDbSchema({
|
||||
dbId: currentTableSchema.childTableDbId,
|
||||
userId,
|
||||
});
|
||||
if (currentTableSchema.childTable && currentTableSchema.childTableDbId) {
|
||||
const isParentDbCurrentDb =
|
||||
currentTableSchema.childTableDbId == newCurrentDbSchema.id;
|
||||
|
||||
const targetParentDatabase = isParentDbCurrentDb
|
||||
? newCurrentDbSchema
|
||||
: grabPrimaryRequiredDbSchema({
|
||||
dbId: currentTableSchema.childTableDbId,
|
||||
userId,
|
||||
});
|
||||
|
||||
const targetParentDatabaseTableIndex =
|
||||
targetParentDatabase?.tables.findIndex(
|
||||
|
||||
@@ -26,6 +26,7 @@ export default function setTextFieldType(
|
||||
if (type == "yaml") return { ...newField, yaml: true };
|
||||
if (type == "javascript") return { ...newField, javascript: true };
|
||||
if (type == "code") return { ...newField, code: true };
|
||||
if (type == "markdown") return { ...newField, markdown: true };
|
||||
|
||||
return { ...newField };
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ export default function grabDockerResourceIPNumbers() {
|
||||
replica_1: 37,
|
||||
replica_2: 38,
|
||||
web_app_post_db_setup: 71,
|
||||
static: 77,
|
||||
} as const;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { AIOptions, AIOptionsObject, SiteConfig } from "../types";
|
||||
|
||||
type Params = {
|
||||
userConfig?: SiteConfig | null;
|
||||
};
|
||||
|
||||
export type GrabUserAIConfigReturn = {};
|
||||
|
||||
export default function grabUserAIInfo({
|
||||
userConfig: passedConfig,
|
||||
}: Params): AIOptionsObject | undefined {
|
||||
const userConfig: SiteConfig | undefined = passedConfig
|
||||
? passedConfig
|
||||
: undefined;
|
||||
|
||||
if (!userConfig) return undefined;
|
||||
|
||||
const targetAI = userConfig?.main.target_ai;
|
||||
|
||||
if (!targetAI?.name || !userConfig?.main.api_keys) return undefined;
|
||||
|
||||
const targetAIAPIKey = userConfig.main.api_keys[targetAI.name].key;
|
||||
|
||||
if (!targetAIAPIKey) return undefined;
|
||||
|
||||
const targetAIOption = AIOptions.find(
|
||||
(aiOpt) => aiOpt.name == targetAI.name
|
||||
);
|
||||
|
||||
targetAI.apiKey = targetAIAPIKey;
|
||||
|
||||
if (targetAIOption?.baseUrl) {
|
||||
targetAI.baseUrl = targetAIOption.baseUrl;
|
||||
}
|
||||
|
||||
return targetAI;
|
||||
}
|
||||
Reference in New Issue
Block a user