@upstart.gg/sdk
Version:
You can test the CLI without recompiling by running:
386 lines (384 loc) • 8.28 kB
JavaScript
import { StringEnum } from "../utils/string-enum.js";
import { toLLMSchema } from "../utils/llm.js";
import { Type } from "@sinclair/typebox";
//#region src/shared/datasources/types.ts
const providersSchema = StringEnum(["internal"]);
const datasourceInternalManifest = Type.Object({
id: Type.String({
title: "ID",
description: "Unique identifier of the datasource. Used to reference the datasource in the system. Use a url-safe string like a slug."
}),
label: Type.String({
title: "Label",
description: "Label of the datasource displayed in the UI"
}),
provider: Type.Literal("internal", {
title: "Internal",
description: "Internal datasource saved locally in Upstart."
}),
schema: Type.Any({
title: "Schema",
description: "JSON Schema of datasource. MUST Always an array of objects."
}),
indexes: Type.Array(Type.Object({
name: Type.String({ title: "Index name" }),
fields: Type.Array(Type.String(), { title: "Fields to index" }),
unique: Type.Optional(Type.Boolean({
title: "Unique index",
default: false
}))
}), {
title: "Indexes",
description: "IMPORTANT: Indexes to create on the datasource. use it to enforce uniqueness or improve query performance."
})
}, { examples: [{
id: "customers",
label: "Customers",
provider: "internal",
schema: {
type: "array",
items: {
type: "object",
properties: {
name: {
type: "string",
title: "Name"
},
email: {
type: "string",
title: "Email",
format: "email"
}
},
required: ["name", "email"],
title: "Customer",
examples: [
{
name: "John Doe",
email: "john.doe@example.com"
},
{
name: "Jane Smith",
email: "jane.smith@example.com"
},
{
name: "Alice Johnson",
email: "alice.johnson@example.com"
},
{
name: "Bob Brown",
email: "bob.brown@example.com"
},
{
name: "Charlie Davis",
email: "charlie.davis@example.com"
}
]
}
},
indexes: [{
name: "idx_customers_email",
fields: ["email"],
unique: true
}]
}, {
id: "blog_posts",
label: "Blog Posts",
provider: "internal",
schema: {
type: "array",
items: {
type: "object",
properties: {
title: {
type: "string",
title: "Title"
},
content: {
type: "string",
title: "Content"
},
author: {
type: "string",
title: "Author"
}
},
required: [
"title",
"content",
"author"
],
title: "Blog Post",
examples: [
{
title: "My First Blog Post",
content: "This is the content of my first blog post.",
author: "John Doe"
},
{
title: "Exploring the Cosmos",
content: "A journey through the stars and galaxies.",
author: "Jane Smith"
},
{
title: "The Art of Cooking",
content: "Delicious recipes and cooking tips.",
author: "Alice Johnson"
},
{
title: "Traveling the World",
content: "My adventures in different countries.",
author: "Bob Brown"
},
{
title: "Technology Trends",
content: "The latest trends in technology.",
author: "Charlie Davis"
}
]
}
},
indexes: [{
name: "idx_blog_posts_title",
fields: ["title"],
unique: true
}]
}] });
const datasourceManifest = datasourceInternalManifest;
const datasourceManifestLLM = toLLMSchema(datasourceManifest);
const datasourcesList = Type.Array(datasourceManifest);
const stringFilter = Type.Object({
field: Type.String(),
op: StringEnum([
"eq",
"ne",
"contains",
"notContains",
"startsWith",
"notStartsWith",
"endsWith",
"notEndsWith"
]),
value: Type.String()
});
const numberFilter = Type.Object({
field: Type.String(),
op: StringEnum([
"eq",
"ne",
"lt",
"lte",
"gt",
"gte"
]),
value: Type.Number()
});
const dateFilterAbsolute = Type.Object({
field: Type.String(),
op: StringEnum(["before", "after"]),
value: Type.String()
});
const dateFilterRelative = Type.Object({
field: Type.String(),
op: StringEnum(["beforeNow", "afterNow"]),
value: Type.Null()
});
const arrayFilter = Type.Object({
field: Type.String(),
op: StringEnum([
"contains",
"notContains",
"containsAll",
"containsAny",
"notContainsAny"
]),
value: Type.Array(Type.String())
});
const booleanFilter = Type.Object({
field: Type.String(),
op: Type.Literal("eq"),
value: Type.Boolean()
});
const queryFilter = Type.Union([
stringFilter,
numberFilter,
dateFilterAbsolute,
dateFilterRelative,
arrayFilter,
booleanFilter
]);
const filterExpression = Type.Recursive((This) => Type.Union([Type.Object({
op: Type.Literal("and"),
fields: Type.Array(Type.Union([queryFilter, This]), { title: "Indexed Fields" })
}), Type.Object({
op: Type.Literal("or"),
fields: Type.Array(Type.Union([queryFilter, This]))
})], {
default: {
op: "and",
fields: []
},
examples: [{
op: "and",
fields: [{
field: "$id",
op: "eq",
value: "123"
}, {
field: "$publicationDate",
op: "beforeNow"
}]
}]
}), {
title: "Filter Expression",
description: "Expression used to filter query results. Can be a combination of and/or conditions."
});
const querySchema = Type.Object({
id: Type.String({
title: "Query ID",
description: "Unique identifier for the query. Used to reference the query in the system. URL-safe string like a slug."
}),
label: Type.String({
title: "Label",
maxLength: 100,
description: "Label of the query displayed in the UI"
}),
datasourceId: Type.String({
title: "Database",
description: "ID of the datasource to query"
}),
limit: Type.Number({
title: "Limit",
description: "Limit the number of records to fetch from the datasource.",
minimum: 1,
default: 10
}),
sortDirection: Type.Optional(StringEnum(["asc", "desc"], {
title: "Sort",
enumNames: ["Ascending", "Descending"],
description: "Direction to sort the records by",
default: "desc"
})),
sortField: Type.Optional(Type.String({
title: "Sort Field",
description: "Field to sort by (must be an indexed field)",
default: "$publicationDate"
})),
filters: Type.Optional(filterExpression),
parameters: Type.Optional(Type.Array(Type.Object({
field: Type.String({
title: "Field",
description: "Field name to use as parameter"
}),
op: StringEnum([
"eq",
"ne",
"contains",
"notContains",
"startsWith",
"notStartsWith",
"endsWith",
"notEndsWith",
"lt",
"lte",
"gt",
"gte",
"before",
"after",
"beforeNow",
"afterNow",
"containsAll",
"containsAny",
"notContainsAny"
], {
title: "Operator",
description: "Operator to use for the parameter"
})
}), {
title: "Parameters",
description: "Field name and operator that will be used as parameters when using the query in pages. Only indexed fields can be used as parameters.",
default: [],
examples: [
[{
field: "$slug",
op: "eq"
}],
[{
field: "category",
op: "eq"
}],
[{
field: "tags",
op: "containsAny"
}],
[{
field: "author",
op: "eq"
}],
[{
field: "title",
op: "contains"
}]
]
}))
}, { examples: [
{
id: "latest-posts",
label: "Latest posts",
datasourceId: "blog_posts",
limit: 5,
sortDirection: "desc",
sortField: "$publicationDate"
},
{
id: "posts-by-category",
label: "Posts by category",
datasourceId: "blog_posts",
limit: 10,
sortDirection: "desc",
sortField: "$publicationDate",
parameters: [{
field: "category",
op: "eq"
}]
},
{
id: "posts-by-tag",
label: "Posts by tag",
datasourceId: "blog_posts",
limit: 10,
sortDirection: "desc",
sortField: "$publicationDate",
parameters: [{
field: "tags",
op: "containsAny"
}]
},
{
id: "author-posts",
label: "Author posts",
datasourceId: "blog_posts",
limit: 10,
sortDirection: "desc",
sortField: "$publicationDate",
parameters: [{
field: "author",
op: "eq"
}]
},
{
id: "search-posts",
label: "Search posts",
datasourceId: "blog_posts",
limit: 10,
sortDirection: "desc",
sortField: "$publicationDate",
parameters: [{
field: "title",
op: "contains"
}]
}
] });
//#endregion
export { datasourceManifest, datasourceManifestLLM, datasourcesList, providersSchema, queryFilter, querySchema };
//# sourceMappingURL=types.js.map