From be7f773e791be8912dd82c41512a934589e2a357 Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 16 Oct 2025 15:58:07 +0000 Subject: [PATCH] s --- pb_data/auxiliary.db | Bin 0 -> 180224 bytes pb_data/data.db | Bin 0 -> 184320 bytes .../20251016204244_yg8t9hxz02.png | Bin 0 -> 215616 bytes .../20251016204244_yg8t9hxz02.png.attrs | 1 + .../100x100_20251016204244_yg8t9hxz02.png | Bin 0 -> 13589 bytes ...00x100_20251016204244_yg8t9hxz02.png.attrs | 1 + pb_data/types.d.ts | 23816 ++++++++++++++++ pb_migrations/1760628828_created_file.js | 77 + pb_migrations/1760628854_updated_file.js | 35 + pb_migrations/1760628872_updated_file.js | 34 + pb_migrations/1760628913_updated_file.js | 26 + pb_migrations/1760628950_created_city.js | 71 + pb_migrations/1760629025_updated_users.js | 29 + pb_migrations/1760629178_updated_city.js | 29 + pb_migrations/1760629200_updated_city.js | 24 + pb_migrations/1760629212_updated_city.js | 32 + pb_migrations/1760629707_updated_city.js | 29 + pocketbase | Bin 18 files changed, 24204 insertions(+) create mode 100644 pb_data/auxiliary.db create mode 100644 pb_data/data.db create mode 100644 pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/20251016204244_yg8t9hxz02.png create mode 100644 pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/20251016204244_yg8t9hxz02.png.attrs create mode 100644 pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png create mode 100644 pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png.attrs create mode 100644 pb_data/types.d.ts create mode 100644 pb_migrations/1760628828_created_file.js create mode 100644 pb_migrations/1760628854_updated_file.js create mode 100644 pb_migrations/1760628872_updated_file.js create mode 100644 pb_migrations/1760628913_updated_file.js create mode 100644 pb_migrations/1760628950_created_city.js create mode 100644 pb_migrations/1760629025_updated_users.js create mode 100644 pb_migrations/1760629178_updated_city.js create mode 100644 pb_migrations/1760629200_updated_city.js create mode 100644 pb_migrations/1760629212_updated_city.js create mode 100644 pb_migrations/1760629707_updated_city.js mode change 100644 => 100755 pocketbase diff --git a/pb_data/auxiliary.db b/pb_data/auxiliary.db new file mode 100644 index 0000000000000000000000000000000000000000..687f5d8a5a518762a7566a5c978328abe357005a GIT binary patch literal 180224 zcmeFa3!EHPl|Nqn?w)>u5JPxQ5<&<`dg}cc7$G2!2mwNZBqJEAyQ-_JyIx)0)h|To zB*Q~RMMOYFMMOn$1r-$)74e0;sQB0wSAV*`?1v9j*ln*8wHb4myF^#_;2Hu z;p?aBzkbuEtNp>%TUUFW+4tAwQb|-~x3)m%TTfjw>#o;Nf!A-k!WUeuvg4tEN(Dj@4U+M|1UcK6L&?$>)ZSu+7n!Hmr?cR3&WfvZ5fT0NdT(3&k z54)e;7w*|TeC1W!cWk?A@9?D;?j3&pg%@qR`m)`_XKu7NzU3{NS(WWGb8_uWTQnq7 zPitoSOl}kS3}1f5?%~U?zU;CsQ&mnr5U6zf<-0Gu_`<8EYrs%l7CJ9@8nC#|49BW`J3dglfOv* zH2K5iGs$l!zmfb(^6})O$xkOAN`5$bU-GWx9m!jh&EyS9CuvUp7*^2J&w(A0(B^Py zLLOs{v`OQFs2G-B<*FB7xO;d+wA7J|scCYiteQsYTnh|?G2#qMwy%W$VsQM7QbDzL zn`KcOBW_p+S}nJ3bltv^11@n&vRzuYWu07;GrPg)TQ|z2I8IU-o$*GKz>L>|HGo&yrpQJa)U(5E zsG25@Fe!Za%xeITnAOto<-3Oo@Gxf&1AwK^9>Uz3r86Byp12O5j@w zc9>vBDRPvgQ!GP{A6OR#{kdymWK1&*g4Y{VxuKJmTdl4#t)nw1U=wPoI6&r@+`+^>@-(yaHYbPSL}MF+#8u8&_AN1Lc6K@)8q)QSm)wD8i zh;>EmI5Eu}a8qwPA~))V0#z-rlx^CaJw57XTsvz30?|m}6hY7Ez}{&avxXnyjRvDX zaVkYI!uWxrFT6S2+%Qoe%V(>#s@}+HB_kti*?BwEm7tRvVCmefDg)JHOwWp2%(Atm zB~!PU@G5e;lV|lTo}xIMpCwuQq-PPYwt>6=yd0pd*Morjf`icK#3&`CNCAxD6TP9$ zo~;uXj7efCPe_^}ml}#tVZv^oXT^$|F^v=;Gy6>fN~Wp-?c8uQ4a|@>7`{M{zDU*N zVZ$tgO;pE_Qf(cKb0p7FiyFG1CR?6!nLy(}D4>=JGu~oAI)_Z*3^%?%?*W~&`e1zw zFXl2Fsk1qYE@f1CvU8T+BRnl|bM?p)+r4vRgT?XY=9PeMYHkPg%;x!kZfK4IdU}%r zbbS+Uwy$e$0QA)6DS)2RTm|UK%{ZVZHG_bjcoQINYJjXR0`l5CAgeNf96t`oaXSHd z%^LtY_5wf>=KvCC0EwjliEadBXc&;l8bHFw0uqXN0rez*4=A=V`TM{

4_gBQN^H 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 literal 0 HcmV?d00001 diff --git a/pb_data/data.db b/pb_data/data.db new file mode 100644 index 0000000000000000000000000000000000000000..edcfdd943717e4bdc114db84dfd9294e17a1206b GIT binary patch literal 184320 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 JPDHLkV1m{YcM$*p literal 0 HcmV?d00001 diff --git a/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/20251016204244_yg8t9hxz02.png.attrs b/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/20251016204244_yg8t9hxz02.png.attrs new file mode 100644 index 0000000..e522b27 --- /dev/null +++ b/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/20251016204244_yg8t9hxz02.png.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"20251016204244.png"},"md5":"IhQ9XkDOONHKIGDKOx8TrA=="} diff --git a/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png b/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png new file mode 100644 index 0000000000000000000000000000000000000000..6183b4e8a082dc44cf12b4e3bb08f4cffccd6782 GIT binary patch literal 13589 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 literal 0 HcmV?d00001 diff --git a/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png.attrs b/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png.attrs new file mode 100644 index 0000000..8538913 --- /dev/null +++ b/pb_data/storage/pbc_2878493088/7zus4pitiw5gvjj/thumbs_20251016204244_yg8t9hxz02.png/100x100_20251016204244_yg8t9hxz02.png.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"If5Sclu0M+wrf7ux24QwIw=="} diff --git a/pb_data/types.d.ts b/pb_data/types.d.ts new file mode 100644 index 0000000..b0d0693 --- /dev/null +++ b/pb_data/types.d.ts @@ -0,0 +1,23816 @@ +// 1757796257 +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ------------------------------------------------------------------- +// cronBinds +// ------------------------------------------------------------------- + +/** + * CronAdd registers a new cron job. + * + * If a cron job with the specified name already exist, it will be + * replaced with the new one. + * + * Example: + * + * ```js + * // prints "Hello world!" on every 30 minutes + * cronAdd("hello", "*\/30 * * * *", () => { + * console.log("Hello world!") + * }) + * ``` + * + * _Note that this method is available only in pb_hooks context._ + * + * @group PocketBase + */ +declare function cronAdd( + jobId: string, + cronExpr: string, + handler: () => void, +): void; + +/** + * CronRemove removes a single registered cron job by its name. + * + * Example: + * + * ```js + * cronRemove("hello") + * ``` + * + * _Note that this method is available only in pb_hooks context._ + * + * @group PocketBase + */ +declare function cronRemove(jobId: string): void; + +// ------------------------------------------------------------------- +// routerBinds +// ------------------------------------------------------------------- + +/** + * RouterAdd registers a new route definition. + * + * Example: + * + * ```js + * routerAdd("GET", "/hello", (e) => { + * return e.json(200, {"message": "Hello!"}) + * }, $apis.requireAuth()) + * ``` + * + * _Note that this method is available only in pb_hooks context._ + * + * @group PocketBase + */ +declare function routerAdd( + method: string, + path: string, + handler: (e: core.RequestEvent) => void, + ...middlewares: Array void)|Middleware>, +): void; + +/** + * RouterUse registers one or more global middlewares that are executed + * along the handler middlewares after a matching route is found. + * + * Example: + * + * ```js + * routerUse((e) => { + * console.log(e.request.url.path) + * return e.next() + * }) + * ``` + * + * _Note that this method is available only in pb_hooks context._ + * + * @group PocketBase + */ +declare function routerUse(...middlewares: Array void)|Middleware>): void; + +// ------------------------------------------------------------------- +// baseBinds +// ------------------------------------------------------------------- + +/** + * Global helper variable that contains the absolute path to the app pb_hooks directory. + * + * @group PocketBase + */ +declare var __hooks: string + +// Utility type to exclude the on* hook methods from a type +// (hooks are separately generated as global methods). +// +// See https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as +type excludeHooks = { + [Property in keyof Type as Exclude]: Type[Property] +}; + +// CoreApp without the on* hook methods +type CoreApp = excludeHooks + +// PocketBase without the on* hook methods +type PocketBase = excludeHooks + +/** + * `$app` is the current running PocketBase instance that is globally + * available in each .pb.js file. + * + * _Note that this variable is available only in pb_hooks context._ + * + * @namespace + * @group PocketBase + */ +declare var $app: PocketBase + +/** + * `$template` is a global helper to load and cache HTML templates on the fly. + * + * The templates uses the standard Go [html/template](https://pkg.go.dev/html/template) + * and [text/template](https://pkg.go.dev/text/template) package syntax. + * + * Example: + * + * ```js + * const html = $template.loadFiles( + * "views/layout.html", + * "views/content.html", + * ).render({"name": "John"}) + * ``` + * + * @namespace + * @group PocketBase + */ +declare var $template: template.Registry + +/** + * This method is superseded by toString. + * + * @deprecated + * @group PocketBase + */ +declare function readerToString(reader: any, maxBytes?: number): string; + +/** + * toString stringifies the specified value. + * + * Support optional second maxBytes argument to limit the max read bytes + * when the value is a io.Reader (default to 32MB). + * + * Types that don't have explicit string representation are json serialized. + * + * Example: + * + * ```js + * // io.Reader + * const ex1 = toString(e.request.body) + * + * // slice of bytes + * const ex2 = toString([104 101 108 108 111]) // "hello" + * + * // null + * const ex3 = toString(null) // "" + * ``` + * + * @group PocketBase + */ +declare function toString(val: any, maxBytes?: number): string; + +/** + * toBytes converts the specified value into a bytes slice. + * + * Support optional second maxBytes argument to limit the max read bytes + * when the value is a io.Reader (default to 32MB). + * + * Types that don't have Go slice representation (bool, objects, etc.) + * are serialized to UTF8 string and its bytes slice is returned. + * + * Example: + * + * ```js + * // io.Reader + * const ex1 = toBytes(e.request.body) + * + * // string + * const ex2 = toBytes("hello") // [104 101 108 108 111] + * + * // object (the same as the string '{"test":1}') + * const ex3 = toBytes({"test":1}) // [123 34 116 101 115 116 34 58 49 125] + * + * // null + * const ex4 = toBytes(null) // [] + * ``` + * + * @group PocketBase + */ +declare function toBytes(val: any, maxBytes?: number): Array; + +/** + * sleep pauses the current goroutine for at least the specified user duration (in ms). + * A zero or negative duration returns immediately. + * + * Example: + * + * ```js + * sleep(250) // sleeps for 250ms + * ``` + * + * @group PocketBase + */ +declare function sleep(milliseconds: number): void; + +/** + * arrayOf creates a placeholder array of the specified models. + * Usually used to populate DB result into an array of models. + * + * Example: + * + * ```js + * const records = arrayOf(new Record) + * + * $app.recordQuery("articles").limit(10).all(records) + * ``` + * + * @group PocketBase + */ +declare function arrayOf(model: T): Array; + +/** + * DynamicModel creates a new dynamic model with fields from the provided data shape. + * + * Caveats: + * - In order to use 0 as double/float initialization number you have to negate it (`-0`). + * - You need to use lowerCamelCase when accessing the model fields (e.g. `model.roles` and not `model.Roles`). + * + * Example: + * + * ```js + * const model = new DynamicModel({ + * name: "" + * age: 0, // int64 + * totalSpent: -0, // float64 + * active: false, + * Roles: [], // maps to "Roles" in the DB/JSON but the prop would be accessible via "model.roles" + * meta: {} + * }) + * ``` + * + * @group PocketBase + */ +declare class DynamicModel { + constructor(shape?: { [key:string]: any }) +} + +interface Context extends context.Context{} // merge +/** + * Context creates a new empty Go context.Context. + * + * This is usually used as part of some Go transitive bindings. + * + * Example: + * + * ```js + * const blank = new Context() + * + * // with single key-value pair + * const base = new Context(null, "a", 123) + * console.log(base.value("a")) // 123 + * + * // extend with additional key-value pair + * const sub = new Context(base, "b", 456) + * console.log(sub.value("a")) // 123 + * console.log(sub.value("b")) // 456 + * ``` + * + * @group PocketBase + */ +declare class Context implements context.Context { + constructor(parentCtx?: Context, key?: any, value?: any) +} + +/** + * Record model class. + * + * ```js + * const collection = $app.findCollectionByNameOrId("article") + * + * const record = new Record(collection, { + * title: "Lorem ipsum" + * }) + * + * // or set field values after the initialization + * record.set("description", "...") + * ``` + * + * @group PocketBase + */ +declare const Record: { + new(collection?: core.Collection, data?: { [key:string]: any }): core.Record + + // note: declare as "newable" const due to conflict with the Record TS utility type +} + +interface Collection extends core.Collection{ + type: "base" | "view" | "auth" +} // merge +/** + * Collection model class. + * + * ```js + * const collection = new Collection({ + * type: "base", + * name: "article", + * listRule: "@request.auth.id != '' || status = 'public'", + * viewRule: "@request.auth.id != '' || status = 'public'", + * deleteRule: "@request.auth.id != ''", + * fields: [ + * { + * name: "title", + * type: "text", + * required: true, + * min: 6, + * max: 100, + * }, + * { + * name: "description", + * type: "text", + * }, + * ] + * }) + * ``` + * + * @group PocketBase + */ +declare class Collection implements core.Collection { + constructor(data?: Partial) +} + +interface FieldsList extends core.FieldsList{} // merge +/** + * FieldsList model class, usually used to define the Collection.fields. + * + * @group PocketBase + */ +declare class FieldsList implements core.FieldsList { + constructor(data?: Partial) +} + +interface Field extends core.Field{} // merge +/** + * Field model class, usually used as part of the FieldsList model. + * + * @group PocketBase + */ +declare class Field implements core.Field { + constructor(data?: Partial) +} + +interface NumberField extends core.NumberField{} // merge +/** + * {@inheritDoc core.NumberField} + * + * @group PocketBase + */ +declare class NumberField implements core.NumberField { + constructor(data?: Partial) +} + +interface BoolField extends core.BoolField{} // merge +/** + * {@inheritDoc core.BoolField} + * + * @group PocketBase + */ +declare class BoolField implements core.BoolField { + constructor(data?: Partial) +} + +interface TextField extends core.TextField{} // merge +/** + * {@inheritDoc core.TextField} + * + * @group PocketBase + */ +declare class TextField implements core.TextField { + constructor(data?: Partial) +} + +interface URLField extends core.URLField{} // merge +/** + * {@inheritDoc core.URLField} + * + * @group PocketBase + */ +declare class URLField implements core.URLField { + constructor(data?: Partial) +} + +interface EmailField extends core.EmailField{} // merge +/** + * {@inheritDoc core.EmailField} + * + * @group PocketBase + */ +declare class EmailField implements core.EmailField { + constructor(data?: Partial) +} + +interface EditorField extends core.EditorField{} // merge +/** + * {@inheritDoc core.EditorField} + * + * @group PocketBase + */ +declare class EditorField implements core.EditorField { + constructor(data?: Partial) +} + +interface PasswordField extends core.PasswordField{} // merge +/** + * {@inheritDoc core.PasswordField} + * + * @group PocketBase + */ +declare class PasswordField implements core.PasswordField { + constructor(data?: Partial) +} + +interface DateField extends core.DateField{} // merge +/** + * {@inheritDoc core.DateField} + * + * @group PocketBase + */ +declare class DateField implements core.DateField { + constructor(data?: Partial) +} + +interface AutodateField extends core.AutodateField{} // merge +/** + * {@inheritDoc core.AutodateField} + * + * @group PocketBase + */ +declare class AutodateField implements core.AutodateField { + constructor(data?: Partial) +} + +interface JSONField extends core.JSONField{} // merge +/** + * {@inheritDoc core.JSONField} + * + * @group PocketBase + */ +declare class JSONField implements core.JSONField { + constructor(data?: Partial) +} + +interface RelationField extends core.RelationField{} // merge +/** + * {@inheritDoc core.RelationField} + * + * @group PocketBase + */ +declare class RelationField implements core.RelationField { + constructor(data?: Partial) +} + +interface SelectField extends core.SelectField{} // merge +/** + * {@inheritDoc core.SelectField} + * + * @group PocketBase + */ +declare class SelectField implements core.SelectField { + constructor(data?: Partial) +} + +interface FileField extends core.FileField{} // merge +/** + * {@inheritDoc core.FileField} + * + * @group PocketBase + */ +declare class FileField implements core.FileField { + constructor(data?: Partial) +} + +interface GeoPointField extends core.GeoPointField{} // merge +/** + * {@inheritDoc core.GeoPointField} + * + * @group PocketBase + */ +declare class GeoPointField implements core.GeoPointField { + constructor(data?: Partial) +} + +interface MailerMessage extends mailer.Message{} // merge +/** + * MailerMessage defines a single email message. + * + * ```js + * const message = new MailerMessage({ + * from: { + * address: $app.settings().meta.senderAddress, + * name: $app.settings().meta.senderName, + * }, + * to: [{address: "test@example.com"}], + * subject: "YOUR_SUBJECT...", + * html: "YOUR_HTML_BODY...", + * }) + * + * $app.newMailClient().send(message) + * ``` + * + * @group PocketBase + */ +declare class MailerMessage implements mailer.Message { + constructor(message?: Partial) +} + +interface Command extends cobra.Command{} // merge +/** + * Command defines a single console command. + * + * Example: + * + * ```js + * const command = new Command({ + * use: "hello", + * run: (cmd, args) => { console.log("Hello world!") }, + * }) + * + * $app.rootCmd.addCommand(command); + * ``` + * + * @group PocketBase + */ +declare class Command implements cobra.Command { + constructor(cmd?: Partial) +} + +/** + * RequestInfo defines a single core.RequestInfo instance, usually used + * as part of various filter checks. + * + * Example: + * + * ```js + * const authRecord = $app.findAuthRecordByEmail("users", "test@example.com") + * + * const info = new RequestInfo({ + * auth: authRecord, + * body: {"name": 123}, + * headers: {"x-token": "..."}, + * }) + * + * const record = $app.findFirstRecordByData("articles", "slug", "hello") + * + * const canAccess = $app.canAccessRecord(record, info, "@request.auth.id != '' && @request.body.name = 123") + * ``` + * + * @group PocketBase + */ +declare const RequestInfo: { + new(info?: Partial): core.RequestInfo + + // note: declare as "newable" const due to conflict with the RequestInfo TS node type +} + +/** + * Middleware defines a single request middleware handler. + * + * This class is usually used when you want to explicitly specify a priority to your custom route middleware. + * + * Example: + * + * ```js + * routerUse(new Middleware((e) => { + * console.log(e.request.url.path) + * return e.next() + * }, -10)) + * ``` + * + * @group PocketBase + */ +declare class Middleware { + constructor( + func: string|((e: core.RequestEvent) => void), + priority?: number, + id?: string, + ) +} + +interface Timezone extends time.Location{} // merge +/** + * Timezone returns the timezone location with the given name. + * + * The name is expected to be a location name corresponding to a file + * in the IANA Time Zone database, such as "America/New_York". + * + * If the name is "Local", LoadLocation returns Local. + * + * If the name is "", invalid or "UTC", returns UTC. + * + * The constructor is equivalent to calling the Go `time.LoadLocation(name)` method. + * + * Example: + * + * ```js + * const zone = new Timezone("America/New_York") + * $app.cron().setTimezone(zone) + * ``` + * + * @group PocketBase + */ +declare class Timezone implements time.Location { + constructor(name?: string) +} + +interface DateTime extends types.DateTime{} // merge +/** + * DateTime defines a single DateTime type instance. + * The returned date is always represented in UTC. + * + * Example: + * + * ```js + * const dt0 = new DateTime() // now + * + * // full datetime string + * const dt1 = new DateTime('2023-07-01 00:00:00.000Z') + * + * // datetime string with default "parse in" timezone location + * // + * // similar to new DateTime('2023-07-01 00:00:00 +01:00') or new DateTime('2023-07-01 00:00:00 +02:00') + * // but accounts for the daylight saving time (DST) + * const dt2 = new DateTime('2023-07-01 00:00:00', 'Europe/Amsterdam') + * ``` + * + * @group PocketBase + */ +declare class DateTime implements types.DateTime { + constructor(date?: string, defaultParseInLocation?: string) +} + +interface ValidationError extends ozzo_validation.Error{} // merge +/** + * ValidationError defines a single formatted data validation error, + * usually used as part of an error response. + * + * ```js + * new ValidationError("invalid_title", "Title is not valid") + * ``` + * + * @group PocketBase + */ +declare class ValidationError implements ozzo_validation.Error { + constructor(code?: string, message?: string) +} + +interface Cookie extends http.Cookie{} // merge +/** + * A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an + * HTTP response. + * + * Example: + * + * ```js + * routerAdd("POST", "/example", (c) => { + * c.setCookie(new Cookie({ + * name: "example_name", + * value: "example_value", + * path: "/", + * domain: "example.com", + * maxAge: 10, + * secure: true, + * httpOnly: true, + * sameSite: 3, + * })) + * + * return c.redirect(200, "/"); + * }) + * ``` + * + * @group PocketBase + */ +declare class Cookie implements http.Cookie { + constructor(options?: Partial) +} + +interface SubscriptionMessage extends subscriptions.Message{} // merge +/** + * SubscriptionMessage defines a realtime subscription payload. + * + * Example: + * + * ```js + * onRealtimeConnectRequest((e) => { + * e.client.send(new SubscriptionMessage({ + * name: "example", + * data: '{"greeting": "Hello world"}' + * })) + * }) + * ``` + * + * @group PocketBase + */ +declare class SubscriptionMessage implements subscriptions.Message { + constructor(options?: Partial) +} + +// ------------------------------------------------------------------- +// dbxBinds +// ------------------------------------------------------------------- + +/** + * `$dbx` defines common utility for working with the DB abstraction. + * For examples and guides please check the [Database guide](https://pocketbase.io/docs/js-database). + * + * @group PocketBase + */ +declare namespace $dbx { + /** + * {@inheritDoc dbx.HashExp} + */ + export function hashExp(pairs: { [key:string]: any }): dbx.Expression + + let _in: dbx._in + export { _in as in } + + export let exp: dbx.newExp + export let not: dbx.not + export let and: dbx.and + export let or: dbx.or + export let notIn: dbx.notIn + export let like: dbx.like + export let orLike: dbx.orLike + export let notLike: dbx.notLike + export let orNotLike: dbx.orNotLike + export let exists: dbx.exists + export let notExists: dbx.notExists + export let between: dbx.between + export let notBetween: dbx.notBetween +} + +// ------------------------------------------------------------------- +// mailsBinds +// ------------------------------------------------------------------- + +/** + * `$mails` defines helpers to send common + * auth records emails like verification, password reset, etc. + * + * @group PocketBase + */ +declare namespace $mails { + let sendRecordPasswordReset: mails.sendRecordPasswordReset + let sendRecordVerification: mails.sendRecordVerification + let sendRecordChangeEmail: mails.sendRecordChangeEmail + let sendRecordOTP: mails.sendRecordOTP +} + +// ------------------------------------------------------------------- +// securityBinds +// ------------------------------------------------------------------- + +/** + * `$security` defines low level helpers for creating + * and parsing JWTs, random string generation, AES encryption, etc. + * + * @group PocketBase + */ +declare namespace $security { + let randomString: security.randomString + let randomStringWithAlphabet: security.randomStringWithAlphabet + let randomStringByRegex: security.randomStringByRegex + let pseudorandomString: security.pseudorandomString + let pseudorandomStringWithAlphabet: security.pseudorandomStringWithAlphabet + let encrypt: security.encrypt + let decrypt: security.decrypt + let hs256: security.hs256 + let hs512: security.hs512 + let equal: security.equal + let md5: security.md5 + let sha256: security.sha256 + let sha512: security.sha512 + + /** + * {@inheritDoc security.newJWT} + */ + export function createJWT(payload: { [key:string]: any }, signingKey: string, secDuration: number): string + + /** + * {@inheritDoc security.parseUnverifiedJWT} + */ + export function parseUnverifiedJWT(token: string): _TygojaDict + + /** + * {@inheritDoc security.parseJWT} + */ + export function parseJWT(token: string, verificationKey: string): _TygojaDict +} + +// ------------------------------------------------------------------- +// filesystemBinds +// ------------------------------------------------------------------- + +/** + * `$filesystem` defines common helpers for working + * with the PocketBase filesystem abstraction. + * + * @group PocketBase + */ +declare namespace $filesystem { + let fileFromPath: filesystem.newFileFromPath + let fileFromBytes: filesystem.newFileFromBytes + let fileFromMultipart: filesystem.newFileFromMultipart + + /** + * fileFromURL creates a new File from the provided url by + * downloading the resource and creating a BytesReader. + * + * Example: + * + * ```js + * // with default max timeout of 120sec + * const file1 = $filesystem.fileFromURL("https://...") + * + * // with custom timeout of 15sec + * const file2 = $filesystem.fileFromURL("https://...", 15) + * ``` + */ + export function fileFromURL(url: string, secTimeout?: number): filesystem.File +} + +// ------------------------------------------------------------------- +// filepathBinds +// ------------------------------------------------------------------- + +/** + * `$filepath` defines common helpers for manipulating filename + * paths in a way compatible with the target operating system-defined file paths. + * + * @group PocketBase + */ +declare namespace $filepath { + export let base: filepath.base + export let clean: filepath.clean + export let dir: filepath.dir + export let ext: filepath.ext + export let fromSlash: filepath.fromSlash + export let glob: filepath.glob + export let isAbs: filepath.isAbs + export let join: filepath.join + export let match: filepath.match + export let rel: filepath.rel + export let split: filepath.split + export let splitList: filepath.splitList + export let toSlash: filepath.toSlash + export let walk: filepath.walk + export let walkDir: filepath.walkDir +} + +// ------------------------------------------------------------------- +// osBinds +// ------------------------------------------------------------------- + +/** + * `$os` defines common helpers for working with the OS level primitives + * (eg. deleting directories, executing shell commands, etc.). + * + * @group PocketBase + */ +declare namespace $os { + /** + * Legacy alias for $os.cmd(). + */ + export let exec: exec.command + + /** + * Prepares an external OS command. + * + * Example: + * + * ```js + * // prepare the command to execute + * const cmd = $os.cmd('ls', '-sl') + * + * // execute the command and return its standard output as string + * const output = toString(cmd.output()); + * ``` + */ + export let cmd: exec.command + + /** + * Args hold the command-line arguments, starting with the program name. + */ + export let args: Array + + export let exit: os.exit + export let getenv: os.getenv + export let dirFS: os.dirFS + export let readFile: os.readFile + export let writeFile: os.writeFile + export let stat: os.stat + export let readDir: os.readDir + export let tempDir: os.tempDir + export let truncate: os.truncate + export let getwd: os.getwd + export let mkdir: os.mkdir + export let mkdirAll: os.mkdirAll + export let rename: os.rename + export let remove: os.remove + export let removeAll: os.removeAll + export let openRoot: os.openRoot + export let openInRoot: os.openInRoot +} + +// ------------------------------------------------------------------- +// formsBinds +// ------------------------------------------------------------------- + +interface AppleClientSecretCreateForm extends forms.AppleClientSecretCreate{} // merge +/** + * @inheritDoc + * @group PocketBase + */ +declare class AppleClientSecretCreateForm implements forms.AppleClientSecretCreate { + constructor(app: CoreApp) +} + +interface RecordUpsertForm extends forms.RecordUpsert{} // merge +/** + * @inheritDoc + * @group PocketBase + */ +declare class RecordUpsertForm implements forms.RecordUpsert { + constructor(app: CoreApp, record: core.Record) +} + +interface TestEmailSendForm extends forms.TestEmailSend{} // merge +/** + * @inheritDoc + * @group PocketBase + */ +declare class TestEmailSendForm implements forms.TestEmailSend { + constructor(app: CoreApp) +} + +interface TestS3FilesystemForm extends forms.TestS3Filesystem{} // merge +/** + * @inheritDoc + * @group PocketBase + */ +declare class TestS3FilesystemForm implements forms.TestS3Filesystem { + constructor(app: CoreApp) +} + +// ------------------------------------------------------------------- +// apisBinds +// ------------------------------------------------------------------- + +interface ApiError extends router.ApiError{} // merge +/** + * @inheritDoc + * + * @group PocketBase + */ +declare class ApiError implements router.ApiError { + constructor(status?: number, message?: string, data?: any) +} + +interface NotFoundError extends router.ApiError{} // merge +/** + * NotFounderor returns 404 ApiError. + * + * @group PocketBase + */ +declare class NotFoundError implements router.ApiError { + constructor(message?: string, data?: any) +} + +interface BadRequestError extends router.ApiError{} // merge +/** + * BadRequestError returns 400 ApiError. + * + * @group PocketBase + */ +declare class BadRequestError implements router.ApiError { + constructor(message?: string, data?: any) +} + +interface ForbiddenError extends router.ApiError{} // merge +/** + * ForbiddenError returns 403 ApiError. + * + * @group PocketBase + */ +declare class ForbiddenError implements router.ApiError { + constructor(message?: string, data?: any) +} + +interface UnauthorizedError extends router.ApiError{} // merge +/** + * UnauthorizedError returns 401 ApiError. + * + * @group PocketBase + */ +declare class UnauthorizedError implements router.ApiError { + constructor(message?: string, data?: any) +} + +interface TooManyRequestsError extends router.ApiError{} // merge +/** + * TooManyRequestsError returns 429 ApiError. + * + * @group PocketBase + */ +declare class TooManyRequestsError implements router.ApiError { + constructor(message?: string, data?: any) +} + +interface InternalServerError extends router.ApiError{} // merge +/** + * InternalServerError returns 429 ApiError. + * + * @group PocketBase + */ +declare class InternalServerError implements router.ApiError { + constructor(message?: string, data?: any) +} + +/** + * `$apis` defines commonly used PocketBase api helpers and middlewares. + * + * @group PocketBase + */ +declare namespace $apis { + /** + * Route handler to serve static directory content (html, js, css, etc.). + * + * If a file resource is missing and indexFallback is set, the request + * will be forwarded to the base index.html (useful for SPA). + */ + export function static(dir: string, indexFallback: boolean): (e: core.RequestEvent) => void + + let requireGuestOnly: apis.requireGuestOnly + let requireAuth: apis.requireAuth + let requireSuperuserAuth: apis.requireSuperuserAuth + let requireSuperuserOrOwnerAuth: apis.requireSuperuserOrOwnerAuth + let skipSuccessActivityLog: apis.skipSuccessActivityLog + let gzip: apis.gzip + let bodyLimit: apis.bodyLimit + let enrichRecord: apis.enrichRecord + let enrichRecords: apis.enrichRecords + + /** + * RecordAuthResponse writes standardized json record auth response + * into the specified request event. + * + * The authMethod argument specify the name of the current authentication method (eg. password, oauth2, etc.) + * that it is used primarily as an auth identifier during MFA and for login alerts. + * + * Set authMethod to empty string if you want to ignore the MFA checks and the login alerts + * (can be also adjusted additionally via the onRecordAuthRequest hook). + */ + export function recordAuthResponse(e: core.RequestEvent, authRecord: core.Record, authMethod: string, meta?: any): void +} + +// ------------------------------------------------------------------- +// httpClientBinds +// ------------------------------------------------------------------- + +// extra FormData overload to prevent TS warnings when used with non File/Blob value. +interface FormData { + append(key:string, value:any): void + set(key:string, value:any): void +} + +/** + * `$http` defines common methods for working with HTTP requests. + * + * @group PocketBase + */ +declare namespace $http { + /** + * Sends a single HTTP request. + * + * Example: + * + * ```js + * const res = $http.send({ + * method: "POST", + * url: "https://example.com", + * body: JSON.stringify({"title": "test"}), + * headers: { 'Content-Type': 'application/json' } + * }) + * + * console.log(res.statusCode) // the response HTTP status code + * console.log(res.headers) // the response headers (eg. res.headers['X-Custom'][0]) + * console.log(res.cookies) // the response cookies (eg. res.cookies.sessionId.value) + * console.log(res.body) // the response body as raw bytes slice + * console.log(res.json) // the response body as parsed json array or map + * ``` + */ + function send(config: { + url: string, + body?: string|FormData, + method?: string, // default to "GET" + headers?: { [key:string]: string }, + timeout?: number, // default to 120 + + // @deprecated please use body instead + data?: { [key:string]: any }, + }): { + statusCode: number, + headers: { [key:string]: Array }, + cookies: { [key:string]: http.Cookie }, + json: any, + body: Array, + + // @deprecated please use toString(result.body) instead + raw: string, + }; +} + +// ------------------------------------------------------------------- +// migrate only +// ------------------------------------------------------------------- + +/** + * Migrate defines a single migration upgrade/downgrade action. + * + * _Note that this method is available only in pb_migrations context._ + * + * @group PocketBase + */ +declare function migrate( + up: (txApp: CoreApp) => void, + down?: (txApp: CoreApp) => void +): void; +/** @group PocketBase */declare function onBackupCreate(handler: (e: core.BackupEvent) => void): void +/** @group PocketBase */declare function onBackupRestore(handler: (e: core.BackupEvent) => void): void +/** @group PocketBase */declare function onBatchRequest(handler: (e: core.BatchRequestEvent) => void): void +/** @group PocketBase */declare function onBootstrap(handler: (e: core.BootstrapEvent) => void): void +/** @group PocketBase */declare function onCollectionAfterCreateError(handler: (e: core.CollectionErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionAfterCreateSuccess(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionAfterDeleteError(handler: (e: core.CollectionErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionAfterDeleteSuccess(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionAfterUpdateError(handler: (e: core.CollectionErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionAfterUpdateSuccess(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionCreate(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionCreateExecute(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionCreateRequest(handler: (e: core.CollectionRequestEvent) => void): void +/** @group PocketBase */declare function onCollectionDelete(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionDeleteExecute(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionDeleteRequest(handler: (e: core.CollectionRequestEvent) => void): void +/** @group PocketBase */declare function onCollectionUpdate(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionUpdateExecute(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionUpdateRequest(handler: (e: core.CollectionRequestEvent) => void): void +/** @group PocketBase */declare function onCollectionValidate(handler: (e: core.CollectionEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onCollectionViewRequest(handler: (e: core.CollectionRequestEvent) => void): void +/** @group PocketBase */declare function onCollectionsImportRequest(handler: (e: core.CollectionsImportRequestEvent) => void): void +/** @group PocketBase */declare function onCollectionsListRequest(handler: (e: core.CollectionsListRequestEvent) => void): void +/** @group PocketBase */declare function onFileDownloadRequest(handler: (e: core.FileDownloadRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onFileTokenRequest(handler: (e: core.FileTokenRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerRecordAuthAlertSend(handler: (e: core.MailerRecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerRecordEmailChangeSend(handler: (e: core.MailerRecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerRecordOTPSend(handler: (e: core.MailerRecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerRecordPasswordResetSend(handler: (e: core.MailerRecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerRecordVerificationSend(handler: (e: core.MailerRecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onMailerSend(handler: (e: core.MailerEvent) => void): void +/** @group PocketBase */declare function onModelAfterCreateError(handler: (e: core.ModelErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelAfterCreateSuccess(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelAfterDeleteError(handler: (e: core.ModelErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelAfterDeleteSuccess(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelAfterUpdateError(handler: (e: core.ModelErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelAfterUpdateSuccess(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelCreate(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelCreateExecute(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelDelete(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelDeleteExecute(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelUpdate(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelUpdateExecute(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onModelValidate(handler: (e: core.ModelEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRealtimeConnectRequest(handler: (e: core.RealtimeConnectRequestEvent) => void): void +/** @group PocketBase */declare function onRealtimeMessageSend(handler: (e: core.RealtimeMessageEvent) => void): void +/** @group PocketBase */declare function onRealtimeSubscribeRequest(handler: (e: core.RealtimeSubscribeRequestEvent) => void): void +/** @group PocketBase */declare function onRecordAfterCreateError(handler: (e: core.RecordErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAfterCreateSuccess(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAfterDeleteError(handler: (e: core.RecordErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAfterDeleteSuccess(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAfterUpdateError(handler: (e: core.RecordErrorEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAfterUpdateSuccess(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAuthRefreshRequest(handler: (e: core.RecordAuthRefreshRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAuthRequest(handler: (e: core.RecordAuthRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAuthWithOAuth2Request(handler: (e: core.RecordAuthWithOAuth2RequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAuthWithOTPRequest(handler: (e: core.RecordAuthWithOTPRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordAuthWithPasswordRequest(handler: (e: core.RecordAuthWithPasswordRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordConfirmEmailChangeRequest(handler: (e: core.RecordConfirmEmailChangeRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordConfirmPasswordResetRequest(handler: (e: core.RecordConfirmPasswordResetRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordConfirmVerificationRequest(handler: (e: core.RecordConfirmVerificationRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordCreate(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordCreateExecute(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordCreateRequest(handler: (e: core.RecordRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordDelete(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordDeleteExecute(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordDeleteRequest(handler: (e: core.RecordRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordEnrich(handler: (e: core.RecordEnrichEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordRequestEmailChangeRequest(handler: (e: core.RecordRequestEmailChangeRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordRequestOTPRequest(handler: (e: core.RecordCreateOTPRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordRequestPasswordResetRequest(handler: (e: core.RecordRequestPasswordResetRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordRequestVerificationRequest(handler: (e: core.RecordRequestVerificationRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordUpdate(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordUpdateExecute(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordUpdateRequest(handler: (e: core.RecordRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordValidate(handler: (e: core.RecordEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordViewRequest(handler: (e: core.RecordRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onRecordsListRequest(handler: (e: core.RecordsListRequestEvent) => void, ...tags: string[]): void +/** @group PocketBase */declare function onSettingsListRequest(handler: (e: core.SettingsListRequestEvent) => void): void +/** @group PocketBase */declare function onSettingsReload(handler: (e: core.SettingsReloadEvent) => void): void +/** @group PocketBase */declare function onSettingsUpdateRequest(handler: (e: core.SettingsUpdateRequestEvent) => void): void +/** @group PocketBase */declare function onTerminate(handler: (e: core.TerminateEvent) => void): void +type _TygojaDict = { [key:string | number | symbol]: any; } +type _TygojaAny = any + +/** + * Package os provides a platform-independent interface to operating system + * functionality. The design is Unix-like, although the error handling is + * Go-like; failing calls return values of type error rather than error numbers. + * Often, more information is available within the error. For example, + * if a call that takes a file name fails, such as [Open] or [Stat], the error + * will include the failing file name when printed and will be of type + * [*PathError], which may be unpacked for more information. + * + * The os interface is intended to be uniform across all operating systems. + * Features not generally available appear in the system-specific package syscall. + * + * Here is a simple example, opening a file and reading some of it. + * + * ``` + * file, err := os.Open("file.go") // For read access. + * if err != nil { + * log.Fatal(err) + * } + * ``` + * + * If the open fails, the error string will be self-explanatory, like + * + * ``` + * open file.go: no such file or directory + * ``` + * + * The file's data can then be read into a slice of bytes. Read and + * Write take their byte counts from the length of the argument slice. + * + * ``` + * data := make([]byte, 100) + * count, err := file.Read(data) + * if err != nil { + * log.Fatal(err) + * } + * fmt.Printf("read %d bytes: %q\n", count, data[:count]) + * ``` + * + * # Concurrency + * + * The methods of [File] correspond to file system operations. All are + * safe for concurrent use. The maximum number of concurrent + * operations on a File may be limited by the OS or the system. The + * number should be high, but exceeding it may degrade performance or + * cause other issues. + */ +namespace os { + interface readdirMode extends Number{} + interface File { + /** + * Readdir reads the contents of the directory associated with file and + * returns a slice of up to n [FileInfo] values, as would be returned + * by [Lstat], in directory order. Subsequent calls on the same file will yield + * further FileInfos. + * + * If n > 0, Readdir returns at most n FileInfo structures. In this case, if + * Readdir returns an empty slice, it will return a non-nil error + * explaining why. At the end of a directory, the error is [io.EOF]. + * + * If n <= 0, Readdir returns all the FileInfo from the directory in + * a single slice. In this case, if Readdir succeeds (reads all + * the way to the end of the directory), it returns the slice and a + * nil error. If it encounters an error before the end of the + * directory, Readdir returns the FileInfo read until that point + * and a non-nil error. + * + * Most clients are better served by the more efficient ReadDir method. + */ + readdir(n: number): Array + } + interface File { + /** + * Readdirnames reads the contents of the directory associated with file + * and returns a slice of up to n names of files in the directory, + * in directory order. Subsequent calls on the same file will yield + * further names. + * + * If n > 0, Readdirnames returns at most n names. In this case, if + * Readdirnames returns an empty slice, it will return a non-nil error + * explaining why. At the end of a directory, the error is [io.EOF]. + * + * If n <= 0, Readdirnames returns all the names from the directory in + * a single slice. In this case, if Readdirnames succeeds (reads all + * the way to the end of the directory), it returns the slice and a + * nil error. If it encounters an error before the end of the + * directory, Readdirnames returns the names read until that point and + * a non-nil error. + */ + readdirnames(n: number): Array + } + /** + * A DirEntry is an entry read from a directory + * (using the [ReadDir] function or a [File.ReadDir] method). + */ + interface DirEntry extends fs.DirEntry{} + interface File { + /** + * ReadDir reads the contents of the directory associated with the file f + * and returns a slice of [DirEntry] values in directory order. + * Subsequent calls on the same file will yield later DirEntry records in the directory. + * + * If n > 0, ReadDir returns at most n DirEntry records. + * In this case, if ReadDir returns an empty slice, it will return an error explaining why. + * At the end of a directory, the error is [io.EOF]. + * + * If n <= 0, ReadDir returns all the DirEntry records remaining in the directory. + * When it succeeds, it returns a nil error (not io.EOF). + */ + readDir(n: number): Array + } + interface readDir { + /** + * ReadDir reads the named directory, + * returning all its directory entries sorted by filename. + * If an error occurs reading the directory, + * ReadDir returns the entries it was able to read before the error, + * along with the error. + */ + (name: string): Array + } + interface copyFS { + /** + * CopyFS copies the file system fsys into the directory dir, + * creating dir if necessary. + * + * Files are created with mode 0o666 plus any execute permissions + * from the source, and directories are created with mode 0o777 + * (before umask). + * + * CopyFS will not overwrite existing files. If a file name in fsys + * already exists in the destination, CopyFS will return an error + * such that errors.Is(err, fs.ErrExist) will be true. + * + * Symbolic links in fsys are not supported. A *PathError with Err set + * to ErrInvalid is returned when copying from a symbolic link. + * + * Symbolic links in dir are followed. + * + * New files added to fsys (including if dir is a subdirectory of fsys) + * while CopyFS is running are not guaranteed to be copied. + * + * Copying stops at and returns the first error encountered. + */ + (dir: string, fsys: fs.FS): void + } + /** + * Auxiliary information if the File describes a directory + */ + interface dirInfo { + } + interface expand { + /** + * Expand replaces ${var} or $var in the string based on the mapping function. + * For example, [os.ExpandEnv](s) is equivalent to [os.Expand](s, [os.Getenv]). + */ + (s: string, mapping: (_arg0: string) => string): string + } + interface expandEnv { + /** + * ExpandEnv replaces ${var} or $var in the string according to the values + * of the current environment variables. References to undefined + * variables are replaced by the empty string. + */ + (s: string): string + } + interface getenv { + /** + * Getenv retrieves the value of the environment variable named by the key. + * It returns the value, which will be empty if the variable is not present. + * To distinguish between an empty value and an unset value, use [LookupEnv]. + */ + (key: string): string + } + interface lookupEnv { + /** + * LookupEnv retrieves the value of the environment variable named + * by the key. If the variable is present in the environment the + * value (which may be empty) is returned and the boolean is true. + * Otherwise the returned value will be empty and the boolean will + * be false. + */ + (key: string): [string, boolean] + } + interface setenv { + /** + * Setenv sets the value of the environment variable named by the key. + * It returns an error, if any. + */ + (key: string, value: string): void + } + interface unsetenv { + /** + * Unsetenv unsets a single environment variable. + */ + (key: string): void + } + interface clearenv { + /** + * Clearenv deletes all environment variables. + */ + (): void + } + interface environ { + /** + * Environ returns a copy of strings representing the environment, + * in the form "key=value". + */ + (): Array + } + interface timeout { + [key:string]: any; + timeout(): boolean + } + /** + * PathError records an error and the operation and file path that caused it. + */ + interface PathError extends fs.PathError{} + /** + * SyscallError records an error from a specific system call. + */ + interface SyscallError { + syscall: string + err: Error + } + interface SyscallError { + error(): string + } + interface SyscallError { + unwrap(): void + } + interface SyscallError { + /** + * Timeout reports whether this error represents a timeout. + */ + timeout(): boolean + } + interface newSyscallError { + /** + * NewSyscallError returns, as an error, a new [SyscallError] + * with the given system call name and error details. + * As a convenience, if err is nil, NewSyscallError returns nil. + */ + (syscall: string, err: Error): void + } + interface isExist { + /** + * IsExist returns a boolean indicating whether its argument is known to report + * that a file or directory already exists. It is satisfied by [ErrExist] as + * well as some syscall errors. + * + * This function predates [errors.Is]. It only supports errors returned by + * the os package. New code should use errors.Is(err, fs.ErrExist). + */ + (err: Error): boolean + } + interface isNotExist { + /** + * IsNotExist returns a boolean indicating whether its argument is known to + * report that a file or directory does not exist. It is satisfied by + * [ErrNotExist] as well as some syscall errors. + * + * This function predates [errors.Is]. It only supports errors returned by + * the os package. New code should use errors.Is(err, fs.ErrNotExist). + */ + (err: Error): boolean + } + interface isPermission { + /** + * IsPermission returns a boolean indicating whether its argument is known to + * report that permission is denied. It is satisfied by [ErrPermission] as well + * as some syscall errors. + * + * This function predates [errors.Is]. It only supports errors returned by + * the os package. New code should use errors.Is(err, fs.ErrPermission). + */ + (err: Error): boolean + } + interface isTimeout { + /** + * IsTimeout returns a boolean indicating whether its argument is known + * to report that a timeout occurred. + * + * This function predates [errors.Is], and the notion of whether an + * error indicates a timeout can be ambiguous. For example, the Unix + * error EWOULDBLOCK sometimes indicates a timeout and sometimes does not. + * New code should use errors.Is with a value appropriate to the call + * returning the error, such as [os.ErrDeadlineExceeded]. + */ + (err: Error): boolean + } + interface syscallErrorType extends syscall.Errno{} + interface processMode extends Number{} + interface processStatus extends Number{} + /** + * Process stores the information about a process created by [StartProcess]. + */ + interface Process { + pid: number + } + /** + * ProcAttr holds the attributes that will be applied to a new process + * started by StartProcess. + */ + interface ProcAttr { + /** + * If Dir is non-empty, the child changes into the directory before + * creating the process. + */ + dir: string + /** + * If Env is non-nil, it gives the environment variables for the + * new process in the form returned by Environ. + * If it is nil, the result of Environ will be used. + */ + env: Array + /** + * Files specifies the open files inherited by the new process. The + * first three entries correspond to standard input, standard output, and + * standard error. An implementation may support additional entries, + * depending on the underlying operating system. A nil entry corresponds + * to that file being closed when the process starts. + * On Unix systems, StartProcess will change these File values + * to blocking mode, which means that SetDeadline will stop working + * and calling Close will not interrupt a Read or Write. + */ + files: Array<(File | undefined)> + /** + * Operating system-specific process creation attributes. + * Note that setting this field means that your program + * may not execute properly or even compile on some + * operating systems. + */ + sys?: syscall.SysProcAttr + } + /** + * A Signal represents an operating system signal. + * The usual underlying implementation is operating system-dependent: + * on Unix it is syscall.Signal. + */ + interface Signal { + [key:string]: any; + string(): string + signal(): void // to distinguish from other Stringers + } + interface getpid { + /** + * Getpid returns the process id of the caller. + */ + (): number + } + interface getppid { + /** + * Getppid returns the process id of the caller's parent. + */ + (): number + } + interface findProcess { + /** + * FindProcess looks for a running process by its pid. + * + * The [Process] it returns can be used to obtain information + * about the underlying operating system process. + * + * On Unix systems, FindProcess always succeeds and returns a Process + * for the given pid, regardless of whether the process exists. To test whether + * the process actually exists, see whether p.Signal(syscall.Signal(0)) reports + * an error. + */ + (pid: number): (Process) + } + interface startProcess { + /** + * StartProcess starts a new process with the program, arguments and attributes + * specified by name, argv and attr. The argv slice will become [os.Args] in the + * new process, so it normally starts with the program name. + * + * If the calling goroutine has locked the operating system thread + * with [runtime.LockOSThread] and modified any inheritable OS-level + * thread state (for example, Linux or Plan 9 name spaces), the new + * process will inherit the caller's thread state. + * + * StartProcess is a low-level interface. The [os/exec] package provides + * higher-level interfaces. + * + * If there is an error, it will be of type [*PathError]. + */ + (name: string, argv: Array, attr: ProcAttr): (Process) + } + interface Process { + /** + * Release releases any resources associated with the [Process] p, + * rendering it unusable in the future. + * Release only needs to be called if [Process.Wait] is not. + */ + release(): void + } + interface Process { + /** + * Kill causes the [Process] to exit immediately. Kill does not wait until + * the Process has actually exited. This only kills the Process itself, + * not any other processes it may have started. + */ + kill(): void + } + interface Process { + /** + * Wait waits for the [Process] to exit, and then returns a + * ProcessState describing its status and an error, if any. + * Wait releases any resources associated with the Process. + * On most operating systems, the Process must be a child + * of the current process or an error will be returned. + */ + wait(): (ProcessState) + } + interface Process { + /** + * Signal sends a signal to the [Process]. + * Sending [Interrupt] on Windows is not implemented. + */ + signal(sig: Signal): void + } + interface ProcessState { + /** + * UserTime returns the user CPU time of the exited process and its children. + */ + userTime(): time.Duration + } + interface ProcessState { + /** + * SystemTime returns the system CPU time of the exited process and its children. + */ + systemTime(): time.Duration + } + interface ProcessState { + /** + * Exited reports whether the program has exited. + * On Unix systems this reports true if the program exited due to calling exit, + * but false if the program terminated due to a signal. + */ + exited(): boolean + } + interface ProcessState { + /** + * Success reports whether the program exited successfully, + * such as with exit status 0 on Unix. + */ + success(): boolean + } + interface ProcessState { + /** + * Sys returns system-dependent exit information about + * the process. Convert it to the appropriate underlying + * type, such as [syscall.WaitStatus] on Unix, to access its contents. + */ + sys(): any + } + interface ProcessState { + /** + * SysUsage returns system-dependent resource usage information about + * the exited process. Convert it to the appropriate underlying + * type, such as [*syscall.Rusage] on Unix, to access its contents. + * (On Unix, *syscall.Rusage matches struct rusage as defined in the + * getrusage(2) manual page.) + */ + sysUsage(): any + } + /** + * ProcessState stores information about a process, as reported by Wait. + */ + interface ProcessState { + } + interface ProcessState { + /** + * Pid returns the process id of the exited process. + */ + pid(): number + } + interface ProcessState { + string(): string + } + interface ProcessState { + /** + * ExitCode returns the exit code of the exited process, or -1 + * if the process hasn't exited or was terminated by a signal. + */ + exitCode(): number + } + interface executable { + /** + * Executable returns the path name for the executable that started + * the current process. There is no guarantee that the path is still + * pointing to the correct executable. If a symlink was used to start + * the process, depending on the operating system, the result might + * be the symlink or the path it pointed to. If a stable result is + * needed, [path/filepath.EvalSymlinks] might help. + * + * Executable returns an absolute path unless an error occurred. + * + * The main use case is finding resources located relative to an + * executable. + */ + (): string + } + interface File { + /** + * Name returns the name of the file as presented to Open. + * + * It is safe to call Name after [Close]. + */ + name(): string + } + /** + * LinkError records an error during a link or symlink or rename + * system call and the paths that caused it. + */ + interface LinkError { + op: string + old: string + new: string + err: Error + } + interface LinkError { + error(): string + } + interface LinkError { + unwrap(): void + } + interface File { + /** + * Read reads up to len(b) bytes from the File and stores them in b. + * It returns the number of bytes read and any error encountered. + * At end of file, Read returns 0, io.EOF. + */ + read(b: string|Array): number + } + interface File { + /** + * ReadAt reads len(b) bytes from the File starting at byte offset off. + * It returns the number of bytes read and the error, if any. + * ReadAt always returns a non-nil error when n < len(b). + * At end of file, that error is io.EOF. + */ + readAt(b: string|Array, off: number): number + } + interface File { + /** + * ReadFrom implements io.ReaderFrom. + */ + readFrom(r: io.Reader): number + } + /** + * noReadFrom can be embedded alongside another type to + * hide the ReadFrom method of that other type. + */ + interface noReadFrom { + } + interface noReadFrom { + /** + * ReadFrom hides another ReadFrom method. + * It should never be called. + */ + readFrom(_arg0: io.Reader): number + } + /** + * fileWithoutReadFrom implements all the methods of *File other + * than ReadFrom. This is used to permit ReadFrom to call io.Copy + * without leading to a recursive call to ReadFrom. + */ + type _sZSolJq = noReadFrom&File + interface fileWithoutReadFrom extends _sZSolJq { + } + interface File { + /** + * Write writes len(b) bytes from b to the File. + * It returns the number of bytes written and an error, if any. + * Write returns a non-nil error when n != len(b). + */ + write(b: string|Array): number + } + interface File { + /** + * WriteAt writes len(b) bytes to the File starting at byte offset off. + * It returns the number of bytes written and an error, if any. + * WriteAt returns a non-nil error when n != len(b). + * + * If file was opened with the O_APPEND flag, WriteAt returns an error. + */ + writeAt(b: string|Array, off: number): number + } + interface File { + /** + * WriteTo implements io.WriterTo. + */ + writeTo(w: io.Writer): number + } + /** + * noWriteTo can be embedded alongside another type to + * hide the WriteTo method of that other type. + */ + interface noWriteTo { + } + interface noWriteTo { + /** + * WriteTo hides another WriteTo method. + * It should never be called. + */ + writeTo(_arg0: io.Writer): number + } + /** + * fileWithoutWriteTo implements all the methods of *File other + * than WriteTo. This is used to permit WriteTo to call io.Copy + * without leading to a recursive call to WriteTo. + */ + type _sxuHDOH = noWriteTo&File + interface fileWithoutWriteTo extends _sxuHDOH { + } + interface File { + /** + * Seek sets the offset for the next Read or Write on file to offset, interpreted + * according to whence: 0 means relative to the origin of the file, 1 means + * relative to the current offset, and 2 means relative to the end. + * It returns the new offset and an error, if any. + * The behavior of Seek on a file opened with O_APPEND is not specified. + */ + seek(offset: number, whence: number): number + } + interface File { + /** + * WriteString is like Write, but writes the contents of string s rather than + * a slice of bytes. + */ + writeString(s: string): number + } + interface mkdir { + /** + * Mkdir creates a new directory with the specified name and permission + * bits (before umask). + * If there is an error, it will be of type *PathError. + */ + (name: string, perm: FileMode): void + } + interface chdir { + /** + * Chdir changes the current working directory to the named directory. + * If there is an error, it will be of type *PathError. + */ + (dir: string): void + } + interface open { + /** + * Open opens the named file for reading. If successful, methods on + * the returned file can be used for reading; the associated file + * descriptor has mode O_RDONLY. + * If there is an error, it will be of type *PathError. + */ + (name: string): (File) + } + interface create { + /** + * Create creates or truncates the named file. If the file already exists, + * it is truncated. If the file does not exist, it is created with mode 0o666 + * (before umask). If successful, methods on the returned File can + * be used for I/O; the associated file descriptor has mode O_RDWR. + * The directory containing the file must already exist. + * If there is an error, it will be of type *PathError. + */ + (name: string): (File) + } + interface openFile { + /** + * OpenFile is the generalized open call; most users will use Open + * or Create instead. It opens the named file with specified flag + * (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag + * is passed, it is created with mode perm (before umask); + * the containing directory must exist. If successful, + * methods on the returned File can be used for I/O. + * If there is an error, it will be of type *PathError. + */ + (name: string, flag: number, perm: FileMode): (File) + } + interface rename { + /** + * Rename renames (moves) oldpath to newpath. + * If newpath already exists and is not a directory, Rename replaces it. + * If newpath already exists and is a directory, Rename returns an error. + * OS-specific restrictions may apply when oldpath and newpath are in different directories. + * Even within the same directory, on non-Unix platforms Rename is not an atomic operation. + * If there is an error, it will be of type *LinkError. + */ + (oldpath: string, newpath: string): void + } + interface readlink { + /** + * Readlink returns the destination of the named symbolic link. + * If there is an error, it will be of type *PathError. + * + * If the link destination is relative, Readlink returns the relative path + * without resolving it to an absolute one. + */ + (name: string): string + } + interface tempDir { + /** + * TempDir returns the default directory to use for temporary files. + * + * On Unix systems, it returns $TMPDIR if non-empty, else /tmp. + * On Windows, it uses GetTempPath, returning the first non-empty + * value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory. + * On Plan 9, it returns /tmp. + * + * The directory is neither guaranteed to exist nor have accessible + * permissions. + */ + (): string + } + interface userCacheDir { + /** + * UserCacheDir returns the default root directory to use for user-specific + * cached data. Users should create their own application-specific subdirectory + * within this one and use that. + * + * On Unix systems, it returns $XDG_CACHE_HOME as specified by + * https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if + * non-empty, else $HOME/.cache. + * On Darwin, it returns $HOME/Library/Caches. + * On Windows, it returns %LocalAppData%. + * On Plan 9, it returns $home/lib/cache. + * + * If the location cannot be determined (for example, $HOME is not defined) or + * the path in $XDG_CACHE_HOME is relative, then it will return an error. + */ + (): string + } + interface userConfigDir { + /** + * UserConfigDir returns the default root directory to use for user-specific + * configuration data. Users should create their own application-specific + * subdirectory within this one and use that. + * + * On Unix systems, it returns $XDG_CONFIG_HOME as specified by + * https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if + * non-empty, else $HOME/.config. + * On Darwin, it returns $HOME/Library/Application Support. + * On Windows, it returns %AppData%. + * On Plan 9, it returns $home/lib. + * + * If the location cannot be determined (for example, $HOME is not defined) or + * the path in $XDG_CONFIG_HOME is relative, then it will return an error. + */ + (): string + } + interface userHomeDir { + /** + * UserHomeDir returns the current user's home directory. + * + * On Unix, including macOS, it returns the $HOME environment variable. + * On Windows, it returns %USERPROFILE%. + * On Plan 9, it returns the $home environment variable. + * + * If the expected variable is not set in the environment, UserHomeDir + * returns either a platform-specific default value or a non-nil error. + */ + (): string + } + interface chmod { + /** + * Chmod changes the mode of the named file to mode. + * If the file is a symbolic link, it changes the mode of the link's target. + * If there is an error, it will be of type *PathError. + * + * A different subset of the mode bits are used, depending on the + * operating system. + * + * On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and + * ModeSticky are used. + * + * On Windows, only the 0o200 bit (owner writable) of mode is used; it + * controls whether the file's read-only attribute is set or cleared. + * The other bits are currently unused. For compatibility with Go 1.12 + * and earlier, use a non-zero mode. Use mode 0o400 for a read-only + * file and 0o600 for a readable+writable file. + * + * On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive, + * and ModeTemporary are used. + */ + (name: string, mode: FileMode): void + } + interface File { + /** + * Chmod changes the mode of the file to mode. + * If there is an error, it will be of type *PathError. + */ + chmod(mode: FileMode): void + } + interface File { + /** + * SetDeadline sets the read and write deadlines for a File. + * It is equivalent to calling both SetReadDeadline and SetWriteDeadline. + * + * Only some kinds of files support setting a deadline. Calls to SetDeadline + * for files that do not support deadlines will return ErrNoDeadline. + * On most systems ordinary files do not support deadlines, but pipes do. + * + * A deadline is an absolute time after which I/O operations fail with an + * error instead of blocking. The deadline applies to all future and pending + * I/O, not just the immediately following call to Read or Write. + * After a deadline has been exceeded, the connection can be refreshed + * by setting a deadline in the future. + * + * If the deadline is exceeded a call to Read or Write or to other I/O + * methods will return an error that wraps ErrDeadlineExceeded. + * This can be tested using errors.Is(err, os.ErrDeadlineExceeded). + * That error implements the Timeout method, and calling the Timeout + * method will return true, but there are other possible errors for which + * the Timeout will return true even if the deadline has not been exceeded. + * + * An idle timeout can be implemented by repeatedly extending + * the deadline after successful Read or Write calls. + * + * A zero value for t means I/O operations will not time out. + */ + setDeadline(t: time.Time): void + } + interface File { + /** + * SetReadDeadline sets the deadline for future Read calls and any + * currently-blocked Read call. + * A zero value for t means Read will not time out. + * Not all files support setting deadlines; see SetDeadline. + */ + setReadDeadline(t: time.Time): void + } + interface File { + /** + * SetWriteDeadline sets the deadline for any future Write calls and any + * currently-blocked Write call. + * Even if Write times out, it may return n > 0, indicating that + * some of the data was successfully written. + * A zero value for t means Write will not time out. + * Not all files support setting deadlines; see SetDeadline. + */ + setWriteDeadline(t: time.Time): void + } + interface File { + /** + * SyscallConn returns a raw file. + * This implements the syscall.Conn interface. + */ + syscallConn(): syscall.RawConn + } + interface dirFS { + /** + * DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir. + * + * Note that DirFS("/prefix") only guarantees that the Open calls it makes to the + * operating system will begin with "/prefix": DirFS("/prefix").Open("file") is the + * same as os.Open("/prefix/file"). So if /prefix/file is a symbolic link pointing outside + * the /prefix tree, then using DirFS does not stop the access any more than using + * os.Open does. Additionally, the root of the fs.FS returned for a relative path, + * DirFS("prefix"), will be affected by later calls to Chdir. DirFS is therefore not + * a general substitute for a chroot-style security mechanism when the directory tree + * contains arbitrary content. + * + * Use [Root.FS] to obtain a fs.FS that prevents escapes from the tree via symbolic links. + * + * The directory dir must not be "". + * + * The result implements [io/fs.StatFS], [io/fs.ReadFileFS] and + * [io/fs.ReadDirFS]. + */ + (dir: string): fs.FS + } + interface dirFS extends String{} + interface dirFS { + open(name: string): fs.File + } + interface dirFS { + /** + * The ReadFile method calls the [ReadFile] function for the file + * with the given name in the directory. The function provides + * robust handling for small files and special file systems. + * Through this method, dirFS implements [io/fs.ReadFileFS]. + */ + readFile(name: string): string|Array + } + interface dirFS { + /** + * ReadDir reads the named directory, returning all its directory entries sorted + * by filename. Through this method, dirFS implements [io/fs.ReadDirFS]. + */ + readDir(name: string): Array + } + interface dirFS { + stat(name: string): fs.FileInfo + } + interface readFile { + /** + * ReadFile reads the named file and returns the contents. + * A successful call returns err == nil, not err == EOF. + * Because ReadFile reads the whole file, it does not treat an EOF from Read + * as an error to be reported. + */ + (name: string): string|Array + } + interface writeFile { + /** + * WriteFile writes data to the named file, creating it if necessary. + * If the file does not exist, WriteFile creates it with permissions perm (before umask); + * otherwise WriteFile truncates it before writing, without changing permissions. + * Since WriteFile requires multiple system calls to complete, a failure mid-operation + * can leave the file in a partially written state. + */ + (name: string, data: string|Array, perm: FileMode): void + } + interface File { + /** + * Close closes the [File], rendering it unusable for I/O. + * On files that support [File.SetDeadline], any pending I/O operations will + * be canceled and return immediately with an [ErrClosed] error. + * Close will return an error if it has already been called. + */ + close(): void + } + interface chown { + /** + * Chown changes the numeric uid and gid of the named file. + * If the file is a symbolic link, it changes the uid and gid of the link's target. + * A uid or gid of -1 means to not change that value. + * If there is an error, it will be of type [*PathError]. + * + * On Windows or Plan 9, Chown always returns the [syscall.EWINDOWS] or + * EPLAN9 error, wrapped in *PathError. + */ + (name: string, uid: number, gid: number): void + } + interface lchown { + /** + * Lchown changes the numeric uid and gid of the named file. + * If the file is a symbolic link, it changes the uid and gid of the link itself. + * If there is an error, it will be of type [*PathError]. + * + * On Windows, it always returns the [syscall.EWINDOWS] error, wrapped + * in *PathError. + */ + (name: string, uid: number, gid: number): void + } + interface File { + /** + * Chown changes the numeric uid and gid of the named file. + * If there is an error, it will be of type [*PathError]. + * + * On Windows, it always returns the [syscall.EWINDOWS] error, wrapped + * in *PathError. + */ + chown(uid: number, gid: number): void + } + interface File { + /** + * Truncate changes the size of the file. + * It does not change the I/O offset. + * If there is an error, it will be of type [*PathError]. + */ + truncate(size: number): void + } + interface File { + /** + * Sync commits the current contents of the file to stable storage. + * Typically, this means flushing the file system's in-memory copy + * of recently written data to disk. + */ + sync(): void + } + interface chtimes { + /** + * Chtimes changes the access and modification times of the named + * file, similar to the Unix utime() or utimes() functions. + * A zero [time.Time] value will leave the corresponding file time unchanged. + * + * The underlying filesystem may truncate or round the values to a + * less precise time unit. + * If there is an error, it will be of type [*PathError]. + */ + (name: string, atime: time.Time, mtime: time.Time): void + } + interface File { + /** + * Chdir changes the current working directory to the file, + * which must be a directory. + * If there is an error, it will be of type [*PathError]. + */ + chdir(): void + } + /** + * file is the real representation of *File. + * The extra level of indirection ensures that no clients of os + * can overwrite this data, which could cause the finalizer + * to close the wrong file descriptor. + */ + interface file { + } + interface File { + /** + * Fd returns the integer Unix file descriptor referencing the open file. + * If f is closed, the file descriptor becomes invalid. + * If f is garbage collected, a finalizer may close the file descriptor, + * making it invalid; see [runtime.SetFinalizer] for more information on when + * a finalizer might be run. On Unix systems this will cause the [File.SetDeadline] + * methods to stop working. + * Because file descriptors can be reused, the returned file descriptor may + * only be closed through the [File.Close] method of f, or by its finalizer during + * garbage collection. Otherwise, during garbage collection the finalizer + * may close an unrelated file descriptor with the same (reused) number. + * + * As an alternative, see the f.SyscallConn method. + */ + fd(): number + } + interface newFile { + /** + * NewFile returns a new File with the given file descriptor and + * name. The returned value will be nil if fd is not a valid file + * descriptor. On Unix systems, if the file descriptor is in + * non-blocking mode, NewFile will attempt to return a pollable File + * (one for which the SetDeadline methods work). + * + * After passing it to NewFile, fd may become invalid under the same + * conditions described in the comments of the Fd method, and the same + * constraints apply. + */ + (fd: number, name: string): (File) + } + /** + * newFileKind describes the kind of file to newFile. + */ + interface newFileKind extends Number{} + interface truncate { + /** + * Truncate changes the size of the named file. + * If the file is a symbolic link, it changes the size of the link's target. + * If there is an error, it will be of type *PathError. + */ + (name: string, size: number): void + } + interface remove { + /** + * Remove removes the named file or (empty) directory. + * If there is an error, it will be of type *PathError. + */ + (name: string): void + } + interface link { + /** + * Link creates newname as a hard link to the oldname file. + * If there is an error, it will be of type *LinkError. + */ + (oldname: string, newname: string): void + } + interface symlink { + /** + * Symlink creates newname as a symbolic link to oldname. + * On Windows, a symlink to a non-existent oldname creates a file symlink; + * if oldname is later created as a directory the symlink will not work. + * If there is an error, it will be of type *LinkError. + */ + (oldname: string, newname: string): void + } + interface unixDirent { + } + interface unixDirent { + name(): string + } + interface unixDirent { + isDir(): boolean + } + interface unixDirent { + type(): FileMode + } + interface unixDirent { + info(): FileInfo + } + interface unixDirent { + string(): string + } + interface getwd { + /** + * Getwd returns an absolute path name corresponding to the + * current directory. If the current directory can be + * reached via multiple paths (due to symbolic links), + * Getwd may return any one of them. + * + * On Unix platforms, if the environment variable PWD + * provides an absolute name, and it is a name of the + * current directory, it is returned. + */ + (): string + } + interface mkdirAll { + /** + * MkdirAll creates a directory named path, + * along with any necessary parents, and returns nil, + * or else returns an error. + * The permission bits perm (before umask) are used for all + * directories that MkdirAll creates. + * If path is already a directory, MkdirAll does nothing + * and returns nil. + */ + (path: string, perm: FileMode): void + } + interface removeAll { + /** + * RemoveAll removes path and any children it contains. + * It removes everything it can but returns the first error + * it encounters. If the path does not exist, RemoveAll + * returns nil (no error). + * If there is an error, it will be of type [*PathError]. + */ + (path: string): void + } + interface isPathSeparator { + /** + * IsPathSeparator reports whether c is a directory separator character. + */ + (c: number): boolean + } + interface pipe { + /** + * Pipe returns a connected pair of Files; reads from r return bytes written to w. + * It returns the files and an error, if any. + */ + (): [(File), (File)] + } + interface getuid { + /** + * Getuid returns the numeric user id of the caller. + * + * On Windows, it returns -1. + */ + (): number + } + interface geteuid { + /** + * Geteuid returns the numeric effective user id of the caller. + * + * On Windows, it returns -1. + */ + (): number + } + interface getgid { + /** + * Getgid returns the numeric group id of the caller. + * + * On Windows, it returns -1. + */ + (): number + } + interface getegid { + /** + * Getegid returns the numeric effective group id of the caller. + * + * On Windows, it returns -1. + */ + (): number + } + interface getgroups { + /** + * Getgroups returns a list of the numeric ids of groups that the caller belongs to. + * + * On Windows, it returns [syscall.EWINDOWS]. See the [os/user] package + * for a possible alternative. + */ + (): Array + } + interface exit { + /** + * Exit causes the current program to exit with the given status code. + * Conventionally, code zero indicates success, non-zero an error. + * The program terminates immediately; deferred functions are not run. + * + * For portability, the status code should be in the range [0, 125]. + */ + (code: number): void + } + /** + * rawConn implements syscall.RawConn. + */ + interface rawConn { + } + interface rawConn { + control(f: (_arg0: number) => void): void + } + interface rawConn { + read(f: (_arg0: number) => boolean): void + } + interface rawConn { + write(f: (_arg0: number) => boolean): void + } + interface openInRoot { + /** + * OpenInRoot opens the file name in the directory dir. + * It is equivalent to OpenRoot(dir) followed by opening the file in the root. + * + * OpenInRoot returns an error if any component of the name + * references a location outside of dir. + * + * See [Root] for details and limitations. + */ + (dir: string, name: string): (File) + } + /** + * Root may be used to only access files within a single directory tree. + * + * Methods on Root can only access files and directories beneath a root directory. + * If any component of a file name passed to a method of Root references a location + * outside the root, the method returns an error. + * File names may reference the directory itself (.). + * + * Methods on Root will follow symbolic links, but symbolic links may not + * reference a location outside the root. + * Symbolic links must not be absolute. + * + * Methods on Root do not prohibit traversal of filesystem boundaries, + * Linux bind mounts, /proc special files, or access to Unix device files. + * + * Methods on Root are safe to be used from multiple goroutines simultaneously. + * + * On most platforms, creating a Root opens a file descriptor or handle referencing + * the directory. If the directory is moved, methods on Root reference the original + * directory in its new location. + * + * Root's behavior differs on some platforms: + * + * ``` + * - When GOOS=windows, file names may not reference Windows reserved device names + * such as NUL and COM1. + * - When GOOS=js, Root is vulnerable to TOCTOU (time-of-check-time-of-use) + * attacks in symlink validation, and cannot ensure that operations will not + * escape the root. + * - When GOOS=plan9 or GOOS=js, Root does not track directories across renames. + * On these platforms, a Root references a directory name, not a file descriptor. + * ``` + */ + interface Root { + } + interface openRoot { + /** + * OpenRoot opens the named directory. + * If there is an error, it will be of type *PathError. + */ + (name: string): (Root) + } + interface Root { + /** + * Name returns the name of the directory presented to OpenRoot. + * + * It is safe to call Name after [Close]. + */ + name(): string + } + interface Root { + /** + * Close closes the Root. + * After Close is called, methods on Root return errors. + */ + close(): void + } + interface Root { + /** + * Open opens the named file in the root for reading. + * See [Open] for more details. + */ + open(name: string): (File) + } + interface Root { + /** + * Create creates or truncates the named file in the root. + * See [Create] for more details. + */ + create(name: string): (File) + } + interface Root { + /** + * OpenFile opens the named file in the root. + * See [OpenFile] for more details. + * + * If perm contains bits other than the nine least-significant bits (0o777), + * OpenFile returns an error. + */ + openFile(name: string, flag: number, perm: FileMode): (File) + } + interface Root { + /** + * OpenRoot opens the named directory in the root. + * If there is an error, it will be of type *PathError. + */ + openRoot(name: string): (Root) + } + interface Root { + /** + * Mkdir creates a new directory in the root + * with the specified name and permission bits (before umask). + * See [Mkdir] for more details. + * + * If perm contains bits other than the nine least-significant bits (0o777), + * OpenFile returns an error. + */ + mkdir(name: string, perm: FileMode): void + } + interface Root { + /** + * Remove removes the named file or (empty) directory in the root. + * See [Remove] for more details. + */ + remove(name: string): void + } + interface Root { + /** + * Stat returns a [FileInfo] describing the named file in the root. + * See [Stat] for more details. + */ + stat(name: string): FileInfo + } + interface Root { + /** + * Lstat returns a [FileInfo] describing the named file in the root. + * If the file is a symbolic link, the returned FileInfo + * describes the symbolic link. + * See [Lstat] for more details. + */ + lstat(name: string): FileInfo + } + interface Root { + /** + * FS returns a file system (an fs.FS) for the tree of files in the root. + * + * The result implements [io/fs.StatFS], [io/fs.ReadFileFS] and + * [io/fs.ReadDirFS]. + */ + fs(): fs.FS + } + interface rootFS extends Root{} + interface rootFS { + open(name: string): fs.File + } + interface rootFS { + readDir(name: string): Array + } + interface rootFS { + readFile(name: string): string|Array + } + interface rootFS { + stat(name: string): FileInfo + } + /** + * root implementation for platforms with a function to open a file + * relative to a directory. + */ + interface root { + } + interface root { + close(): void + } + interface root { + name(): string + } + /** + * errSymlink reports that a file being operated on is actually a symlink, + * and the target of that symlink. + */ + interface errSymlink extends String{} + interface errSymlink { + error(): string + } + interface sysfdType extends Number{} + interface stat { + /** + * Stat returns a [FileInfo] describing the named file. + * If there is an error, it will be of type [*PathError]. + */ + (name: string): FileInfo + } + interface lstat { + /** + * Lstat returns a [FileInfo] describing the named file. + * If the file is a symbolic link, the returned FileInfo + * describes the symbolic link. Lstat makes no attempt to follow the link. + * If there is an error, it will be of type [*PathError]. + * + * On Windows, if the file is a reparse point that is a surrogate for another + * named entity (such as a symbolic link or mounted folder), the returned + * FileInfo describes the reparse point, and makes no attempt to resolve it. + */ + (name: string): FileInfo + } + interface File { + /** + * Stat returns the [FileInfo] structure describing file. + * If there is an error, it will be of type [*PathError]. + */ + stat(): FileInfo + } + interface hostname { + /** + * Hostname returns the host name reported by the kernel. + */ + (): string + } + interface createTemp { + /** + * CreateTemp creates a new temporary file in the directory dir, + * opens the file for reading and writing, and returns the resulting file. + * The filename is generated by taking pattern and adding a random string to the end. + * If pattern includes a "*", the random string replaces the last "*". + * The file is created with mode 0o600 (before umask). + * If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by [TempDir]. + * Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file. + * The caller can use the file's Name method to find the pathname of the file. + * It is the caller's responsibility to remove the file when it is no longer needed. + */ + (dir: string, pattern: string): (File) + } + interface mkdirTemp { + /** + * MkdirTemp creates a new temporary directory in the directory dir + * and returns the pathname of the new directory. + * The new directory's name is generated by adding a random string to the end of pattern. + * If pattern includes a "*", the random string replaces the last "*" instead. + * The directory is created with mode 0o700 (before umask). + * If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir. + * Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory. + * It is the caller's responsibility to remove the directory when it is no longer needed. + */ + (dir: string, pattern: string): string + } + interface getpagesize { + /** + * Getpagesize returns the underlying system's memory page size. + */ + (): number + } + /** + * File represents an open file descriptor. + * + * The methods of File are safe for concurrent use. + */ + type _swPlPkc = file + interface File extends _swPlPkc { + } + /** + * A FileInfo describes a file and is returned by [Stat] and [Lstat]. + */ + interface FileInfo extends fs.FileInfo{} + /** + * A FileMode represents a file's mode and permission bits. + * The bits have the same definition on all systems, so that + * information about files can be moved from one system + * to another portably. Not all bits apply to all systems. + * The only required bit is [ModeDir] for directories. + */ + interface FileMode extends fs.FileMode{} + interface fileStat { + name(): string + } + interface fileStat { + isDir(): boolean + } + interface sameFile { + /** + * SameFile reports whether fi1 and fi2 describe the same file. + * For example, on Unix this means that the device and inode fields + * of the two underlying structures are identical; on other systems + * the decision may be based on the path names. + * SameFile only applies to results returned by this package's [Stat]. + * It returns false in other cases. + */ + (fi1: FileInfo, fi2: FileInfo): boolean + } + /** + * A fileStat is the implementation of FileInfo returned by Stat and Lstat. + */ + interface fileStat { + } + interface fileStat { + size(): number + } + interface fileStat { + mode(): FileMode + } + interface fileStat { + modTime(): time.Time + } + interface fileStat { + sys(): any + } +} + +/** + * Package filepath implements utility routines for manipulating filename paths + * in a way compatible with the target operating system-defined file paths. + * + * The filepath package uses either forward slashes or backslashes, + * depending on the operating system. To process paths such as URLs + * that always use forward slashes regardless of the operating + * system, see the [path] package. + */ +namespace filepath { + interface match { + /** + * Match reports whether name matches the shell file name pattern. + * The pattern syntax is: + * + * ``` + * pattern: + * { term } + * term: + * '*' matches any sequence of non-Separator characters + * '?' matches any single non-Separator character + * '[' [ '^' ] { character-range } ']' + * character class (must be non-empty) + * c matches character c (c != '*', '?', '\\', '[') + * '\\' c matches character c + * + * character-range: + * c matches character c (c != '\\', '-', ']') + * '\\' c matches character c + * lo '-' hi matches character c for lo <= c <= hi + * ``` + * + * Match requires pattern to match all of name, not just a substring. + * The only possible returned error is [ErrBadPattern], when pattern + * is malformed. + * + * On Windows, escaping is disabled. Instead, '\\' is treated as + * path separator. + */ + (pattern: string, name: string): boolean + } + interface glob { + /** + * Glob returns the names of all files matching pattern or nil + * if there is no matching file. The syntax of patterns is the same + * as in [Match]. The pattern may describe hierarchical names such as + * /usr/*\/bin/ed (assuming the [Separator] is '/'). + * + * Glob ignores file system errors such as I/O errors reading directories. + * The only possible returned error is [ErrBadPattern], when pattern + * is malformed. + */ + (pattern: string): Array + } + interface clean { + /** + * Clean returns the shortest path name equivalent to path + * by purely lexical processing. It applies the following rules + * iteratively until no further processing can be done: + * + * 1. Replace multiple [Separator] elements with a single one. + * 2. Eliminate each . path name element (the current directory). + * 3. Eliminate each inner .. path name element (the parent directory) + * ``` + * along with the non-.. element that precedes it. + * ``` + * 4. Eliminate .. elements that begin a rooted path: + * ``` + * that is, replace "/.." by "/" at the beginning of a path, + * assuming Separator is '/'. + * ``` + * + * The returned path ends in a slash only if it represents a root directory, + * such as "/" on Unix or `C:\` on Windows. + * + * Finally, any occurrences of slash are replaced by Separator. + * + * If the result of this process is an empty string, Clean + * returns the string ".". + * + * On Windows, Clean does not modify the volume name other than to replace + * occurrences of "/" with `\`. + * For example, Clean("//host/share/../x") returns `\\host\share\x`. + * + * See also Rob Pike, “Lexical File Names in Plan 9 or + * Getting Dot-Dot Right,” + * https://9p.io/sys/doc/lexnames.html + */ + (path: string): string + } + interface isLocal { + /** + * IsLocal reports whether path, using lexical analysis only, has all of these properties: + * + * ``` + * - is within the subtree rooted at the directory in which path is evaluated + * - is not an absolute path + * - is not empty + * - on Windows, is not a reserved name such as "NUL" + * ``` + * + * If IsLocal(path) returns true, then + * Join(base, path) will always produce a path contained within base and + * Clean(path) will always produce an unrooted path with no ".." path elements. + * + * IsLocal is a purely lexical operation. + * In particular, it does not account for the effect of any symbolic links + * that may exist in the filesystem. + */ + (path: string): boolean + } + interface localize { + /** + * Localize converts a slash-separated path into an operating system path. + * The input path must be a valid path as reported by [io/fs.ValidPath]. + * + * Localize returns an error if the path cannot be represented by the operating system. + * For example, the path a\b is rejected on Windows, on which \ is a separator + * character and cannot be part of a filename. + * + * The path returned by Localize will always be local, as reported by IsLocal. + */ + (path: string): string + } + interface toSlash { + /** + * ToSlash returns the result of replacing each separator character + * in path with a slash ('/') character. Multiple separators are + * replaced by multiple slashes. + */ + (path: string): string + } + interface fromSlash { + /** + * FromSlash returns the result of replacing each slash ('/') character + * in path with a separator character. Multiple slashes are replaced + * by multiple separators. + * + * See also the Localize function, which converts a slash-separated path + * as used by the io/fs package to an operating system path. + */ + (path: string): string + } + interface splitList { + /** + * SplitList splits a list of paths joined by the OS-specific [ListSeparator], + * usually found in PATH or GOPATH environment variables. + * Unlike strings.Split, SplitList returns an empty slice when passed an empty + * string. + */ + (path: string): Array + } + interface split { + /** + * Split splits path immediately following the final [Separator], + * separating it into a directory and file name component. + * If there is no Separator in path, Split returns an empty dir + * and file set to path. + * The returned values have the property that path = dir+file. + */ + (path: string): [string, string] + } + interface join { + /** + * Join joins any number of path elements into a single path, + * separating them with an OS specific [Separator]. Empty elements + * are ignored. The result is Cleaned. However, if the argument + * list is empty or all its elements are empty, Join returns + * an empty string. + * On Windows, the result will only be a UNC path if the first + * non-empty element is a UNC path. + */ + (...elem: string[]): string + } + interface ext { + /** + * Ext returns the file name extension used by path. + * The extension is the suffix beginning at the final dot + * in the final element of path; it is empty if there is + * no dot. + */ + (path: string): string + } + interface evalSymlinks { + /** + * EvalSymlinks returns the path name after the evaluation of any symbolic + * links. + * If path is relative the result will be relative to the current directory, + * unless one of the components is an absolute symbolic link. + * EvalSymlinks calls [Clean] on the result. + */ + (path: string): string + } + interface isAbs { + /** + * IsAbs reports whether the path is absolute. + */ + (path: string): boolean + } + interface abs { + /** + * Abs returns an absolute representation of path. + * If the path is not absolute it will be joined with the current + * working directory to turn it into an absolute path. The absolute + * path name for a given file is not guaranteed to be unique. + * Abs calls [Clean] on the result. + */ + (path: string): string + } + interface rel { + /** + * Rel returns a relative path that is lexically equivalent to targpath when + * joined to basepath with an intervening separator. That is, + * [Join](basepath, Rel(basepath, targpath)) is equivalent to targpath itself. + * On success, the returned path will always be relative to basepath, + * even if basepath and targpath share no elements. + * An error is returned if targpath can't be made relative to basepath or if + * knowing the current working directory would be necessary to compute it. + * Rel calls [Clean] on the result. + */ + (basepath: string, targpath: string): string + } + /** + * WalkFunc is the type of the function called by [Walk] to visit each + * file or directory. + * + * The path argument contains the argument to Walk as a prefix. + * That is, if Walk is called with root argument "dir" and finds a file + * named "a" in that directory, the walk function will be called with + * argument "dir/a". + * + * The directory and file are joined with Join, which may clean the + * directory name: if Walk is called with the root argument "x/../dir" + * and finds a file named "a" in that directory, the walk function will + * be called with argument "dir/a", not "x/../dir/a". + * + * The info argument is the fs.FileInfo for the named path. + * + * The error result returned by the function controls how Walk continues. + * If the function returns the special value [SkipDir], Walk skips the + * current directory (path if info.IsDir() is true, otherwise path's + * parent directory). If the function returns the special value [SkipAll], + * Walk skips all remaining files and directories. Otherwise, if the function + * returns a non-nil error, Walk stops entirely and returns that error. + * + * The err argument reports an error related to path, signaling that Walk + * will not walk into that directory. The function can decide how to + * handle that error; as described earlier, returning the error will + * cause Walk to stop walking the entire tree. + * + * Walk calls the function with a non-nil err argument in two cases. + * + * First, if an [os.Lstat] on the root directory or any directory or file + * in the tree fails, Walk calls the function with path set to that + * directory or file's path, info set to nil, and err set to the error + * from os.Lstat. + * + * Second, if a directory's Readdirnames method fails, Walk calls the + * function with path set to the directory's path, info, set to an + * [fs.FileInfo] describing the directory, and err set to the error from + * Readdirnames. + */ + interface WalkFunc {(path: string, info: fs.FileInfo, err: Error): void } + interface walkDir { + /** + * WalkDir walks the file tree rooted at root, calling fn for each file or + * directory in the tree, including root. + * + * All errors that arise visiting files and directories are filtered by fn: + * see the [fs.WalkDirFunc] documentation for details. + * + * The files are walked in lexical order, which makes the output deterministic + * but requires WalkDir to read an entire directory into memory before proceeding + * to walk that directory. + * + * WalkDir does not follow symbolic links. + * + * WalkDir calls fn with paths that use the separator character appropriate + * for the operating system. This is unlike [io/fs.WalkDir], which always + * uses slash separated paths. + */ + (root: string, fn: fs.WalkDirFunc): void + } + interface walk { + /** + * Walk walks the file tree rooted at root, calling fn for each file or + * directory in the tree, including root. + * + * All errors that arise visiting files and directories are filtered by fn: + * see the [WalkFunc] documentation for details. + * + * The files are walked in lexical order, which makes the output deterministic + * but requires Walk to read an entire directory into memory before proceeding + * to walk that directory. + * + * Walk does not follow symbolic links. + * + * Walk is less efficient than [WalkDir], introduced in Go 1.16, + * which avoids calling os.Lstat on every visited file or directory. + */ + (root: string, fn: WalkFunc): void + } + interface base { + /** + * Base returns the last element of path. + * Trailing path separators are removed before extracting the last element. + * If the path is empty, Base returns ".". + * If the path consists entirely of separators, Base returns a single separator. + */ + (path: string): string + } + interface dir { + /** + * Dir returns all but the last element of path, typically the path's directory. + * After dropping the final element, Dir calls [Clean] on the path and trailing + * slashes are removed. + * If the path is empty, Dir returns ".". + * If the path consists entirely of separators, Dir returns a single separator. + * The returned path does not end in a separator unless it is the root directory. + */ + (path: string): string + } + interface volumeName { + /** + * VolumeName returns leading volume name. + * Given "C:\foo\bar" it returns "C:" on Windows. + * Given "\\host\share\foo" it returns "\\host\share". + * On other platforms it returns "". + */ + (path: string): string + } + interface hasPrefix { + /** + * HasPrefix exists for historical compatibility and should not be used. + * + * Deprecated: HasPrefix does not respect path boundaries and + * does not ignore case when required. + */ + (p: string, prefix: string): boolean + } +} + +/** + * Package validation provides configurable and extensible rules for validating data of various types. + */ +namespace ozzo_validation { + /** + * Error interface represents an validation error + */ + interface Error { + [key:string]: any; + error(): string + code(): string + message(): string + setMessage(_arg0: string): Error + params(): _TygojaDict + setParams(_arg0: _TygojaDict): Error + } +} + +/** + * Package dbx provides a set of DB-agnostic and easy-to-use query building methods for relational databases. + */ +namespace dbx { + /** + * Builder supports building SQL statements in a DB-agnostic way. + * Builder mainly provides two sets of query building methods: those building SELECT statements + * and those manipulating DB data or schema (e.g. INSERT statements, CREATE TABLE statements). + */ + interface Builder { + [key:string]: any; + /** + * NewQuery creates a new Query object with the given SQL statement. + * The SQL statement may contain parameter placeholders which can be bound with actual parameter + * values before the statement is executed. + */ + newQuery(_arg0: string): (Query) + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(..._arg0: string[]): (SelectQuery) + /** + * ModelQuery returns a new ModelQuery object that can be used to perform model insertion, update, and deletion. + * The parameter to this method should be a pointer to the model struct that needs to be inserted, updated, or deleted. + */ + model(_arg0: { + }): (ModelQuery) + /** + * GeneratePlaceholder generates an anonymous parameter placeholder with the given parameter ID. + */ + generatePlaceholder(_arg0: number): string + /** + * Quote quotes a string so that it can be embedded in a SQL statement as a string value. + */ + quote(_arg0: string): string + /** + * QuoteSimpleTableName quotes a simple table name. + * A simple table name does not contain any schema prefix. + */ + quoteSimpleTableName(_arg0: string): string + /** + * QuoteSimpleColumnName quotes a simple column name. + * A simple column name does not contain any table prefix. + */ + quoteSimpleColumnName(_arg0: string): string + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + /** + * Insert creates a Query that represents an INSERT SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + insert(table: string, cols: Params): (Query) + /** + * Upsert creates a Query that represents an UPSERT SQL statement. + * Upsert inserts a row into the table if the primary key or unique index is not found. + * Otherwise it will update the row with the new values. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + upsert(table: string, cols: Params, ...constraints: string[]): (Query) + /** + * Update creates a Query that represents an UPDATE SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding new column + * values. If the "where" expression is nil, the UPDATE SQL statement will have no WHERE clause + * (be careful in this case as the SQL statement will update ALL rows in the table). + */ + update(table: string, cols: Params, where: Expression): (Query) + /** + * Delete creates a Query that represents a DELETE SQL statement. + * If the "where" expression is nil, the DELETE SQL statement will have no WHERE clause + * (be careful in this case as the SQL statement will delete ALL rows in the table). + */ + delete(table: string, where: Expression): (Query) + /** + * CreateTable creates a Query that represents a CREATE TABLE SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding column types. + * The optional "options" parameters will be appended to the generated SQL statement. + */ + createTable(table: string, cols: _TygojaDict, ...options: string[]): (Query) + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + /** + * DropTable creates a Query that can be used to drop a table. + */ + dropTable(table: string): (Query) + /** + * TruncateTable creates a Query that can be used to truncate a table. + */ + truncateTable(table: string): (Query) + /** + * AddColumn creates a Query that can be used to add a column to a table. + */ + addColumn(table: string, col: string, typ: string): (Query) + /** + * DropColumn creates a Query that can be used to drop a column from a table. + */ + dropColumn(table: string, col: string): (Query) + /** + * RenameColumn creates a Query that can be used to rename a column in a table. + */ + renameColumn(table: string, oldName: string, newName: string): (Query) + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + /** + * AddPrimaryKey creates a Query that can be used to specify primary key(s) for a table. + * The "name" parameter specifies the name of the primary key constraint. + */ + addPrimaryKey(table: string, name: string, ...cols: string[]): (Query) + /** + * DropPrimaryKey creates a Query that can be used to remove the named primary key constraint from a table. + */ + dropPrimaryKey(table: string, name: string): (Query) + /** + * AddForeignKey creates a Query that can be used to add a foreign key constraint to a table. + * The length of cols and refCols must be the same as they refer to the primary and referential columns. + * The optional "options" parameters will be appended to the SQL statement. They can be used to + * specify options such as "ON DELETE CASCADE". + */ + addForeignKey(table: string, name: string, cols: Array, refCols: Array, refTable: string, ...options: string[]): (Query) + /** + * DropForeignKey creates a Query that can be used to remove the named foreign key constraint from a table. + */ + dropForeignKey(table: string, name: string): (Query) + /** + * CreateIndex creates a Query that can be used to create an index for a table. + */ + createIndex(table: string, name: string, ...cols: string[]): (Query) + /** + * CreateUniqueIndex creates a Query that can be used to create a unique index for a table. + */ + createUniqueIndex(table: string, name: string, ...cols: string[]): (Query) + /** + * DropIndex creates a Query that can be used to remove the named index from a table. + */ + dropIndex(table: string, name: string): (Query) + } + /** + * BaseBuilder provides a basic implementation of the Builder interface. + */ + interface BaseBuilder { + } + interface newBaseBuilder { + /** + * NewBaseBuilder creates a new BaseBuilder instance. + */ + (db: DB, executor: Executor): (BaseBuilder) + } + interface BaseBuilder { + /** + * DB returns the DB instance that this builder is associated with. + */ + db(): (DB) + } + interface BaseBuilder { + /** + * Executor returns the executor object (a DB instance or a transaction) for executing SQL statements. + */ + executor(): Executor + } + interface BaseBuilder { + /** + * NewQuery creates a new Query object with the given SQL statement. + * The SQL statement may contain parameter placeholders which can be bound with actual parameter + * values before the statement is executed. + */ + newQuery(sql: string): (Query) + } + interface BaseBuilder { + /** + * GeneratePlaceholder generates an anonymous parameter placeholder with the given parameter ID. + */ + generatePlaceholder(_arg0: number): string + } + interface BaseBuilder { + /** + * Quote quotes a string so that it can be embedded in a SQL statement as a string value. + */ + quote(s: string): string + } + interface BaseBuilder { + /** + * QuoteSimpleTableName quotes a simple table name. + * A simple table name does not contain any schema prefix. + */ + quoteSimpleTableName(s: string): string + } + interface BaseBuilder { + /** + * QuoteSimpleColumnName quotes a simple column name. + * A simple column name does not contain any table prefix. + */ + quoteSimpleColumnName(s: string): string + } + interface BaseBuilder { + /** + * Insert creates a Query that represents an INSERT SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + insert(table: string, cols: Params): (Query) + } + interface BaseBuilder { + /** + * Upsert creates a Query that represents an UPSERT SQL statement. + * Upsert inserts a row into the table if the primary key or unique index is not found. + * Otherwise it will update the row with the new values. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + upsert(table: string, cols: Params, ...constraints: string[]): (Query) + } + interface BaseBuilder { + /** + * Update creates a Query that represents an UPDATE SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding new column + * values. If the "where" expression is nil, the UPDATE SQL statement will have no WHERE clause + * (be careful in this case as the SQL statement will update ALL rows in the table). + */ + update(table: string, cols: Params, where: Expression): (Query) + } + interface BaseBuilder { + /** + * Delete creates a Query that represents a DELETE SQL statement. + * If the "where" expression is nil, the DELETE SQL statement will have no WHERE clause + * (be careful in this case as the SQL statement will delete ALL rows in the table). + */ + delete(table: string, where: Expression): (Query) + } + interface BaseBuilder { + /** + * CreateTable creates a Query that represents a CREATE TABLE SQL statement. + * The keys of cols are the column names, while the values of cols are the corresponding column types. + * The optional "options" parameters will be appended to the generated SQL statement. + */ + createTable(table: string, cols: _TygojaDict, ...options: string[]): (Query) + } + interface BaseBuilder { + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + } + interface BaseBuilder { + /** + * DropTable creates a Query that can be used to drop a table. + */ + dropTable(table: string): (Query) + } + interface BaseBuilder { + /** + * TruncateTable creates a Query that can be used to truncate a table. + */ + truncateTable(table: string): (Query) + } + interface BaseBuilder { + /** + * AddColumn creates a Query that can be used to add a column to a table. + */ + addColumn(table: string, col: string, typ: string): (Query) + } + interface BaseBuilder { + /** + * DropColumn creates a Query that can be used to drop a column from a table. + */ + dropColumn(table: string, col: string): (Query) + } + interface BaseBuilder { + /** + * RenameColumn creates a Query that can be used to rename a column in a table. + */ + renameColumn(table: string, oldName: string, newName: string): (Query) + } + interface BaseBuilder { + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + } + interface BaseBuilder { + /** + * AddPrimaryKey creates a Query that can be used to specify primary key(s) for a table. + * The "name" parameter specifies the name of the primary key constraint. + */ + addPrimaryKey(table: string, name: string, ...cols: string[]): (Query) + } + interface BaseBuilder { + /** + * DropPrimaryKey creates a Query that can be used to remove the named primary key constraint from a table. + */ + dropPrimaryKey(table: string, name: string): (Query) + } + interface BaseBuilder { + /** + * AddForeignKey creates a Query that can be used to add a foreign key constraint to a table. + * The length of cols and refCols must be the same as they refer to the primary and referential columns. + * The optional "options" parameters will be appended to the SQL statement. They can be used to + * specify options such as "ON DELETE CASCADE". + */ + addForeignKey(table: string, name: string, cols: Array, refCols: Array, refTable: string, ...options: string[]): (Query) + } + interface BaseBuilder { + /** + * DropForeignKey creates a Query that can be used to remove the named foreign key constraint from a table. + */ + dropForeignKey(table: string, name: string): (Query) + } + interface BaseBuilder { + /** + * CreateIndex creates a Query that can be used to create an index for a table. + */ + createIndex(table: string, name: string, ...cols: string[]): (Query) + } + interface BaseBuilder { + /** + * CreateUniqueIndex creates a Query that can be used to create a unique index for a table. + */ + createUniqueIndex(table: string, name: string, ...cols: string[]): (Query) + } + interface BaseBuilder { + /** + * DropIndex creates a Query that can be used to remove the named index from a table. + */ + dropIndex(table: string, name: string): (Query) + } + /** + * MssqlBuilder is the builder for SQL Server databases. + */ + type _sdnlLDo = BaseBuilder + interface MssqlBuilder extends _sdnlLDo { + } + /** + * MssqlQueryBuilder is the query builder for SQL Server databases. + */ + type _sPzosIS = BaseQueryBuilder + interface MssqlQueryBuilder extends _sPzosIS { + } + interface newMssqlBuilder { + /** + * NewMssqlBuilder creates a new MssqlBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface MssqlBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface MssqlBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface MssqlBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + interface MssqlBuilder { + /** + * QuoteSimpleTableName quotes a simple table name. + * A simple table name does not contain any schema prefix. + */ + quoteSimpleTableName(s: string): string + } + interface MssqlBuilder { + /** + * QuoteSimpleColumnName quotes a simple column name. + * A simple column name does not contain any table prefix. + */ + quoteSimpleColumnName(s: string): string + } + interface MssqlBuilder { + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + } + interface MssqlBuilder { + /** + * RenameColumn creates a Query that can be used to rename a column in a table. + */ + renameColumn(table: string, oldName: string, newName: string): (Query) + } + interface MssqlBuilder { + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + } + interface MssqlQueryBuilder { + /** + * BuildOrderByAndLimit generates the ORDER BY and LIMIT clauses. + */ + buildOrderByAndLimit(sql: string, cols: Array, limit: number, offset: number): string + } + /** + * MysqlBuilder is the builder for MySQL databases. + */ + type _sLbmMhw = BaseBuilder + interface MysqlBuilder extends _sLbmMhw { + } + interface newMysqlBuilder { + /** + * NewMysqlBuilder creates a new MysqlBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface MysqlBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface MysqlBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface MysqlBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + interface MysqlBuilder { + /** + * QuoteSimpleTableName quotes a simple table name. + * A simple table name does not contain any schema prefix. + */ + quoteSimpleTableName(s: string): string + } + interface MysqlBuilder { + /** + * QuoteSimpleColumnName quotes a simple column name. + * A simple column name does not contain any table prefix. + */ + quoteSimpleColumnName(s: string): string + } + interface MysqlBuilder { + /** + * Upsert creates a Query that represents an UPSERT SQL statement. + * Upsert inserts a row into the table if the primary key or unique index is not found. + * Otherwise it will update the row with the new values. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + upsert(table: string, cols: Params, ...constraints: string[]): (Query) + } + interface MysqlBuilder { + /** + * RenameColumn creates a Query that can be used to rename a column in a table. + */ + renameColumn(table: string, oldName: string, newName: string): (Query) + } + interface MysqlBuilder { + /** + * DropPrimaryKey creates a Query that can be used to remove the named primary key constraint from a table. + */ + dropPrimaryKey(table: string, name: string): (Query) + } + interface MysqlBuilder { + /** + * DropForeignKey creates a Query that can be used to remove the named foreign key constraint from a table. + */ + dropForeignKey(table: string, name: string): (Query) + } + /** + * OciBuilder is the builder for Oracle databases. + */ + type _snlvcHZ = BaseBuilder + interface OciBuilder extends _snlvcHZ { + } + /** + * OciQueryBuilder is the query builder for Oracle databases. + */ + type _sfniBAT = BaseQueryBuilder + interface OciQueryBuilder extends _sfniBAT { + } + interface newOciBuilder { + /** + * NewOciBuilder creates a new OciBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface OciBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface OciBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + interface OciBuilder { + /** + * GeneratePlaceholder generates an anonymous parameter placeholder with the given parameter ID. + */ + generatePlaceholder(i: number): string + } + interface OciBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface OciBuilder { + /** + * DropIndex creates a Query that can be used to remove the named index from a table. + */ + dropIndex(table: string, name: string): (Query) + } + interface OciBuilder { + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + } + interface OciBuilder { + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + } + interface OciQueryBuilder { + /** + * BuildOrderByAndLimit generates the ORDER BY and LIMIT clauses. + */ + buildOrderByAndLimit(sql: string, cols: Array, limit: number, offset: number): string + } + /** + * PgsqlBuilder is the builder for PostgreSQL databases. + */ + type _slqxAtS = BaseBuilder + interface PgsqlBuilder extends _slqxAtS { + } + interface newPgsqlBuilder { + /** + * NewPgsqlBuilder creates a new PgsqlBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface PgsqlBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface PgsqlBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + interface PgsqlBuilder { + /** + * GeneratePlaceholder generates an anonymous parameter placeholder with the given parameter ID. + */ + generatePlaceholder(i: number): string + } + interface PgsqlBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface PgsqlBuilder { + /** + * Upsert creates a Query that represents an UPSERT SQL statement. + * Upsert inserts a row into the table if the primary key or unique index is not found. + * Otherwise it will update the row with the new values. + * The keys of cols are the column names, while the values of cols are the corresponding column + * values to be inserted. + */ + upsert(table: string, cols: Params, ...constraints: string[]): (Query) + } + interface PgsqlBuilder { + /** + * DropIndex creates a Query that can be used to remove the named index from a table. + */ + dropIndex(table: string, name: string): (Query) + } + interface PgsqlBuilder { + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + } + interface PgsqlBuilder { + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + } + /** + * SqliteBuilder is the builder for SQLite databases. + */ + type _sqvgcMW = BaseBuilder + interface SqliteBuilder extends _sqvgcMW { + } + interface newSqliteBuilder { + /** + * NewSqliteBuilder creates a new SqliteBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface SqliteBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface SqliteBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface SqliteBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + interface SqliteBuilder { + /** + * QuoteSimpleTableName quotes a simple table name. + * A simple table name does not contain any schema prefix. + */ + quoteSimpleTableName(s: string): string + } + interface SqliteBuilder { + /** + * QuoteSimpleColumnName quotes a simple column name. + * A simple column name does not contain any table prefix. + */ + quoteSimpleColumnName(s: string): string + } + interface SqliteBuilder { + /** + * DropIndex creates a Query that can be used to remove the named index from a table. + */ + dropIndex(table: string, name: string): (Query) + } + interface SqliteBuilder { + /** + * TruncateTable creates a Query that can be used to truncate a table. + */ + truncateTable(table: string): (Query) + } + interface SqliteBuilder { + /** + * RenameTable creates a Query that can be used to rename a table. + */ + renameTable(oldName: string, newName: string): (Query) + } + interface SqliteBuilder { + /** + * AlterColumn creates a Query that can be used to change the definition of a table column. + */ + alterColumn(table: string, col: string, typ: string): (Query) + } + interface SqliteBuilder { + /** + * AddPrimaryKey creates a Query that can be used to specify primary key(s) for a table. + * The "name" parameter specifies the name of the primary key constraint. + */ + addPrimaryKey(table: string, name: string, ...cols: string[]): (Query) + } + interface SqliteBuilder { + /** + * DropPrimaryKey creates a Query that can be used to remove the named primary key constraint from a table. + */ + dropPrimaryKey(table: string, name: string): (Query) + } + interface SqliteBuilder { + /** + * AddForeignKey creates a Query that can be used to add a foreign key constraint to a table. + * The length of cols and refCols must be the same as they refer to the primary and referential columns. + * The optional "options" parameters will be appended to the SQL statement. They can be used to + * specify options such as "ON DELETE CASCADE". + */ + addForeignKey(table: string, name: string, cols: Array, refCols: Array, refTable: string, ...options: string[]): (Query) + } + interface SqliteBuilder { + /** + * DropForeignKey creates a Query that can be used to remove the named foreign key constraint from a table. + */ + dropForeignKey(table: string, name: string): (Query) + } + /** + * StandardBuilder is the builder that is used by DB for an unknown driver. + */ + type _sdDbTYh = BaseBuilder + interface StandardBuilder extends _sdDbTYh { + } + interface newStandardBuilder { + /** + * NewStandardBuilder creates a new StandardBuilder instance. + */ + (db: DB, executor: Executor): Builder + } + interface StandardBuilder { + /** + * QueryBuilder returns the query builder supporting the current DB. + */ + queryBuilder(): QueryBuilder + } + interface StandardBuilder { + /** + * Select returns a new SelectQuery object that can be used to build a SELECT statement. + * The parameters to this method should be the list column names to be selected. + * A column name may have an optional alias name. For example, Select("id", "my_name AS name"). + */ + select(...cols: string[]): (SelectQuery) + } + interface StandardBuilder { + /** + * Model returns a new ModelQuery object that can be used to perform model-based DB operations. + * The model passed to this method should be a pointer to a model struct. + */ + model(model: { + }): (ModelQuery) + } + /** + * LogFunc logs a message for each SQL statement being executed. + * This method takes one or multiple parameters. If a single parameter + * is provided, it will be treated as the log message. If multiple parameters + * are provided, they will be passed to fmt.Sprintf() to generate the log message. + */ + interface LogFunc {(format: string, ...a: { + }[]): void } + /** + * PerfFunc is called when a query finishes execution. + * The query execution time is passed to this function so that the DB performance + * can be profiled. The "ns" parameter gives the number of nanoseconds that the + * SQL statement takes to execute, while the "execute" parameter indicates whether + * the SQL statement is executed or queried (usually SELECT statements). + */ + interface PerfFunc {(ns: number, sql: string, execute: boolean): void } + /** + * QueryLogFunc is called each time when performing a SQL query. + * The "t" parameter gives the time that the SQL statement takes to execute, + * while rows and err are the result of the query. + */ + interface QueryLogFunc {(ctx: context.Context, t: time.Duration, sql: string, rows: sql.Rows, err: Error): void } + /** + * ExecLogFunc is called each time when a SQL statement is executed. + * The "t" parameter gives the time that the SQL statement takes to execute, + * while result and err refer to the result of the execution. + */ + interface ExecLogFunc {(ctx: context.Context, t: time.Duration, sql: string, result: sql.Result, err: Error): void } + /** + * BuilderFunc creates a Builder instance using the given DB instance and Executor. + */ + interface BuilderFunc {(_arg0: DB, _arg1: Executor): Builder } + /** + * DB enhances sql.DB by providing a set of DB-agnostic query building methods. + * DB allows easier query building and population of data into Go variables. + */ + type _suJzJak = Builder + interface DB extends _suJzJak { + /** + * FieldMapper maps struct fields to DB columns. Defaults to DefaultFieldMapFunc. + */ + fieldMapper: FieldMapFunc + /** + * TableMapper maps structs to table names. Defaults to GetTableName. + */ + tableMapper: TableMapFunc + /** + * LogFunc logs the SQL statements being executed. Defaults to nil, meaning no logging. + */ + logFunc: LogFunc + /** + * PerfFunc logs the SQL execution time. Defaults to nil, meaning no performance profiling. + * Deprecated: Please use QueryLogFunc and ExecLogFunc instead. + */ + perfFunc: PerfFunc + /** + * QueryLogFunc is called each time when performing a SQL query that returns data. + */ + queryLogFunc: QueryLogFunc + /** + * ExecLogFunc is called each time when a SQL statement is executed. + */ + execLogFunc: ExecLogFunc + } + /** + * Errors represents a list of errors. + */ + interface Errors extends Array{} + interface newFromDB { + /** + * NewFromDB encapsulates an existing database connection. + */ + (sqlDB: sql.DB, driverName: string): (DB) + } + interface open { + /** + * Open opens a database specified by a driver name and data source name (DSN). + * Note that Open does not check if DSN is specified correctly. It doesn't try to establish a DB connection either. + * Please refer to sql.Open() for more information. + */ + (driverName: string, dsn: string): (DB) + } + interface mustOpen { + /** + * MustOpen opens a database and establishes a connection to it. + * Please refer to sql.Open() and sql.Ping() for more information. + */ + (driverName: string, dsn: string): (DB) + } + interface DB { + /** + * Clone makes a shallow copy of DB. + */ + clone(): (DB) + } + interface DB { + /** + * WithContext returns a new instance of DB associated with the given context. + */ + withContext(ctx: context.Context): (DB) + } + interface DB { + /** + * Context returns the context associated with the DB instance. + * It returns nil if no context is associated. + */ + context(): context.Context + } + interface DB { + /** + * DB returns the sql.DB instance encapsulated by dbx.DB. + */ + db(): (sql.DB) + } + interface DB { + /** + * Close closes the database, releasing any open resources. + * It is rare to Close a DB, as the DB handle is meant to be + * long-lived and shared between many goroutines. + */ + close(): void + } + interface DB { + /** + * Begin starts a transaction. + */ + begin(): (Tx) + } + interface DB { + /** + * BeginTx starts a transaction with the given context and transaction options. + */ + beginTx(ctx: context.Context, opts: sql.TxOptions): (Tx) + } + interface DB { + /** + * Wrap encapsulates an existing transaction. + */ + wrap(sqlTx: sql.Tx): (Tx) + } + interface DB { + /** + * Transactional starts a transaction and executes the given function. + * If the function returns an error, the transaction will be rolled back. + * Otherwise, the transaction will be committed. + */ + transactional(f: (_arg0: Tx) => void): void + } + interface DB { + /** + * TransactionalContext starts a transaction and executes the given function with the given context and transaction options. + * If the function returns an error, the transaction will be rolled back. + * Otherwise, the transaction will be committed. + */ + transactionalContext(ctx: context.Context, opts: sql.TxOptions, f: (_arg0: Tx) => void): void + } + interface DB { + /** + * DriverName returns the name of the DB driver. + */ + driverName(): string + } + interface DB { + /** + * QuoteTableName quotes the given table name appropriately. + * If the table name contains DB schema prefix, it will be handled accordingly. + * This method will do nothing if the table name is already quoted or if it contains parenthesis. + */ + quoteTableName(s: string): string + } + interface DB { + /** + * QuoteColumnName quotes the given column name appropriately. + * If the table name contains table name prefix, it will be handled accordingly. + * This method will do nothing if the column name is already quoted or if it contains parenthesis. + */ + quoteColumnName(s: string): string + } + interface Errors { + /** + * Error returns the error string of Errors. + */ + error(): string + } + /** + * Expression represents a DB expression that can be embedded in a SQL statement. + */ + interface Expression { + [key:string]: any; + /** + * Build converts an expression into a SQL fragment. + * If the expression contains binding parameters, they will be added to the given Params. + */ + build(_arg0: DB, _arg1: Params): string + } + /** + * HashExp represents a hash expression. + * + * A hash expression is a map whose keys are DB column names which need to be filtered according + * to the corresponding values. For example, HashExp{"level": 2, "dept": 10} will generate + * the SQL: "level"=2 AND "dept"=10. + * + * HashExp also handles nil values and slice values. For example, HashExp{"level": []interface{}{1, 2}, "dept": nil} + * will generate: "level" IN (1, 2) AND "dept" IS NULL. + */ + interface HashExp extends _TygojaDict{} + interface newExp { + /** + * NewExp generates an expression with the specified SQL fragment and the optional binding parameters. + */ + (e: string, ...params: Params[]): Expression + } + interface not { + /** + * Not generates a NOT expression which prefixes "NOT" to the specified expression. + */ + (e: Expression): Expression + } + interface and { + /** + * And generates an AND expression which concatenates the given expressions with "AND". + */ + (...exps: Expression[]): Expression + } + interface or { + /** + * Or generates an OR expression which concatenates the given expressions with "OR". + */ + (...exps: Expression[]): Expression + } + interface _in { + /** + * In generates an IN expression for the specified column and the list of allowed values. + * If values is empty, a SQL "0=1" will be generated which represents a false expression. + */ + (col: string, ...values: { + }[]): Expression + } + interface notIn { + /** + * NotIn generates an NOT IN expression for the specified column and the list of disallowed values. + * If values is empty, an empty string will be returned indicating a true expression. + */ + (col: string, ...values: { + }[]): Expression + } + interface like { + /** + * Like generates a LIKE expression for the specified column and the possible strings that the column should be like. + * If multiple values are present, the column should be like *all* of them. For example, Like("name", "key", "word") + * will generate a SQL expression: "name" LIKE "%key%" AND "name" LIKE "%word%". + * + * By default, each value will be surrounded by "%" to enable partial matching. If a value contains special characters + * such as "%", "\", "_", they will also be properly escaped. + * + * You may call Escape() and/or Match() to change the default behavior. For example, Like("name", "key").Match(false, true) + * generates "name" LIKE "key%". + */ + (col: string, ...values: string[]): (LikeExp) + } + interface notLike { + /** + * NotLike generates a NOT LIKE expression. + * For example, NotLike("name", "key", "word") will generate a SQL expression: + * "name" NOT LIKE "%key%" AND "name" NOT LIKE "%word%". Please see Like() for more details. + */ + (col: string, ...values: string[]): (LikeExp) + } + interface orLike { + /** + * OrLike generates an OR LIKE expression. + * This is similar to Like() except that the column should be like one of the possible values. + * For example, OrLike("name", "key", "word") will generate a SQL expression: + * "name" LIKE "%key%" OR "name" LIKE "%word%". Please see Like() for more details. + */ + (col: string, ...values: string[]): (LikeExp) + } + interface orNotLike { + /** + * OrNotLike generates an OR NOT LIKE expression. + * For example, OrNotLike("name", "key", "word") will generate a SQL expression: + * "name" NOT LIKE "%key%" OR "name" NOT LIKE "%word%". Please see Like() for more details. + */ + (col: string, ...values: string[]): (LikeExp) + } + interface exists { + /** + * Exists generates an EXISTS expression by prefixing "EXISTS" to the given expression. + */ + (exp: Expression): Expression + } + interface notExists { + /** + * NotExists generates an EXISTS expression by prefixing "NOT EXISTS" to the given expression. + */ + (exp: Expression): Expression + } + interface between { + /** + * Between generates a BETWEEN expression. + * For example, Between("age", 10, 30) generates: "age" BETWEEN 10 AND 30 + */ + (col: string, from: { + }, to: { + }): Expression + } + interface notBetween { + /** + * NotBetween generates a NOT BETWEEN expression. + * For example, NotBetween("age", 10, 30) generates: "age" NOT BETWEEN 10 AND 30 + */ + (col: string, from: { + }, to: { + }): Expression + } + /** + * Exp represents an expression with a SQL fragment and a list of optional binding parameters. + */ + interface Exp { + } + interface Exp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + interface HashExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * NotExp represents an expression that should prefix "NOT" to a specified expression. + */ + interface NotExp { + } + interface NotExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * AndOrExp represents an expression that concatenates multiple expressions using either "AND" or "OR". + */ + interface AndOrExp { + } + interface AndOrExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * InExp represents an "IN" or "NOT IN" expression. + */ + interface InExp { + } + interface InExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * LikeExp represents a variant of LIKE expressions. + */ + interface LikeExp { + /** + * Like stores the LIKE operator. It can be "LIKE", "NOT LIKE". + * It may also be customized as something like "ILIKE". + */ + like: string + } + interface LikeExp { + /** + * Escape specifies how a LIKE expression should be escaped. + * Each string at position 2i represents a special character and the string at position 2i+1 is + * the corresponding escaped version. + */ + escape(...chars: string[]): (LikeExp) + } + interface LikeExp { + /** + * Match specifies whether to do wildcard matching on the left and/or right of given strings. + */ + match(left: boolean, right: boolean): (LikeExp) + } + interface LikeExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * ExistsExp represents an EXISTS or NOT EXISTS expression. + */ + interface ExistsExp { + } + interface ExistsExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * BetweenExp represents a BETWEEN or a NOT BETWEEN expression. + */ + interface BetweenExp { + } + interface BetweenExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + interface enclose { + /** + * Enclose surrounds the provided nonempty expression with parenthesis "()". + */ + (exp: Expression): Expression + } + /** + * EncloseExp represents a parenthesis enclosed expression. + */ + interface EncloseExp { + } + interface EncloseExp { + /** + * Build converts an expression into a SQL fragment. + */ + build(db: DB, params: Params): string + } + /** + * TableModel is the interface that should be implemented by models which have unconventional table names. + */ + interface TableModel { + [key:string]: any; + tableName(): string + } + /** + * ModelQuery represents a query associated with a struct model. + */ + interface ModelQuery { + } + interface newModelQuery { + (model: { + }, fieldMapFunc: FieldMapFunc, db: DB, builder: Builder): (ModelQuery) + } + interface ModelQuery { + /** + * Context returns the context associated with the query. + */ + context(): context.Context + } + interface ModelQuery { + /** + * WithContext associates a context with the query. + */ + withContext(ctx: context.Context): (ModelQuery) + } + interface ModelQuery { + /** + * Exclude excludes the specified struct fields from being inserted/updated into the DB table. + */ + exclude(...attrs: string[]): (ModelQuery) + } + interface ModelQuery { + /** + * Insert inserts a row in the table using the struct model associated with this query. + * + * By default, it inserts *all* public fields into the table, including those nil or empty ones. + * You may pass a list of the fields to this method to indicate that only those fields should be inserted. + * You may also call Exclude to exclude some fields from being inserted. + * + * If a model has an empty primary key, it is considered auto-incremental and the corresponding struct + * field will be filled with the generated primary key value after a successful insertion. + */ + insert(...attrs: string[]): void + } + interface ModelQuery { + /** + * Update updates a row in the table using the struct model associated with this query. + * The row being updated has the same primary key as specified by the model. + * + * By default, it updates *all* public fields in the table, including those nil or empty ones. + * You may pass a list of the fields to this method to indicate that only those fields should be updated. + * You may also call Exclude to exclude some fields from being updated. + */ + update(...attrs: string[]): void + } + interface ModelQuery { + /** + * Delete deletes a row in the table using the primary key specified by the struct model associated with this query. + */ + delete(): void + } + /** + * ExecHookFunc executes before op allowing custom handling like auto fail/retry. + */ + interface ExecHookFunc {(q: Query, op: () => void): void } + /** + * OneHookFunc executes right before the query populate the row result from One() call (aka. op). + */ + interface OneHookFunc {(q: Query, a: { + }, op: (b: { + }) => void): void } + /** + * AllHookFunc executes right before the query populate the row result from All() call (aka. op). + */ + interface AllHookFunc {(q: Query, sliceA: { + }, op: (sliceB: { + }) => void): void } + /** + * Params represents a list of parameter values to be bound to a SQL statement. + * The map keys are the parameter names while the map values are the corresponding parameter values. + */ + interface Params extends _TygojaDict{} + /** + * Executor prepares, executes, or queries a SQL statement. + */ + interface Executor { + [key:string]: any; + /** + * Exec executes a SQL statement + */ + exec(query: string, ...args: { + }[]): sql.Result + /** + * ExecContext executes a SQL statement with the given context + */ + execContext(ctx: context.Context, query: string, ...args: { + }[]): sql.Result + /** + * Query queries a SQL statement + */ + query(query: string, ...args: { + }[]): (sql.Rows) + /** + * QueryContext queries a SQL statement with the given context + */ + queryContext(ctx: context.Context, query: string, ...args: { + }[]): (sql.Rows) + /** + * Prepare creates a prepared statement + */ + prepare(query: string): (sql.Stmt) + } + /** + * Query represents a SQL statement to be executed. + */ + interface Query { + /** + * FieldMapper maps struct field names to DB column names. + */ + fieldMapper: FieldMapFunc + /** + * LastError contains the last error (if any) of the query. + * LastError is cleared by Execute(), Row(), Rows(), One(), and All(). + */ + lastError: Error + /** + * LogFunc is used to log the SQL statement being executed. + */ + logFunc: LogFunc + /** + * PerfFunc is used to log the SQL execution time. It is ignored if nil. + * Deprecated: Please use QueryLogFunc and ExecLogFunc instead. + */ + perfFunc: PerfFunc + /** + * QueryLogFunc is called each time when performing a SQL query that returns data. + */ + queryLogFunc: QueryLogFunc + /** + * ExecLogFunc is called each time when a SQL statement is executed. + */ + execLogFunc: ExecLogFunc + } + interface newQuery { + /** + * NewQuery creates a new Query with the given SQL statement. + */ + (db: DB, executor: Executor, sql: string): (Query) + } + interface Query { + /** + * SQL returns the original SQL used to create the query. + * The actual SQL (RawSQL) being executed is obtained by replacing the named + * parameter placeholders with anonymous ones. + */ + sql(): string + } + interface Query { + /** + * Context returns the context associated with the query. + */ + context(): context.Context + } + interface Query { + /** + * WithContext associates a context with the query. + */ + withContext(ctx: context.Context): (Query) + } + interface Query { + /** + * WithExecHook associates the provided exec hook function with the query. + * + * It is called for every Query resolver (Execute(), One(), All(), Row(), Column()), + * allowing you to implement auto fail/retry or any other additional handling. + */ + withExecHook(fn: ExecHookFunc): (Query) + } + interface Query { + /** + * WithOneHook associates the provided hook function with the query, + * called on q.One(), allowing you to implement custom struct scan based + * on the One() argument and/or result. + */ + withOneHook(fn: OneHookFunc): (Query) + } + interface Query { + /** + * WithOneHook associates the provided hook function with the query, + * called on q.All(), allowing you to implement custom slice scan based + * on the All() argument and/or result. + */ + withAllHook(fn: AllHookFunc): (Query) + } + interface Query { + /** + * Params returns the parameters to be bound to the SQL statement represented by this query. + */ + params(): Params + } + interface Query { + /** + * Prepare creates a prepared statement for later queries or executions. + * Close() should be called after finishing all queries. + */ + prepare(): (Query) + } + interface Query { + /** + * Close closes the underlying prepared statement. + * Close does nothing if the query has not been prepared before. + */ + close(): void + } + interface Query { + /** + * Bind sets the parameters that should be bound to the SQL statement. + * The parameter placeholders in the SQL statement are in the format of "{:ParamName}". + */ + bind(params: Params): (Query) + } + interface Query { + /** + * Execute executes the SQL statement without retrieving data. + */ + execute(): sql.Result + } + interface Query { + /** + * One executes the SQL statement and populates the first row of the result into a struct or NullStringMap. + * Refer to Rows.ScanStruct() and Rows.ScanMap() for more details on how to specify + * the variable to be populated. + * Note that when the query has no rows in the result set, an sql.ErrNoRows will be returned. + */ + one(a: { + }): void + } + interface Query { + /** + * All executes the SQL statement and populates all the resulting rows into a slice of struct or NullStringMap. + * The slice must be given as a pointer. Each slice element must be either a struct or a NullStringMap. + * Refer to Rows.ScanStruct() and Rows.ScanMap() for more details on how each slice element can be. + * If the query returns no row, the slice will be an empty slice (not nil). + */ + all(slice: { + }): void + } + interface Query { + /** + * Row executes the SQL statement and populates the first row of the result into a list of variables. + * Note that the number of the variables should match to that of the columns in the query result. + * Note that when the query has no rows in the result set, an sql.ErrNoRows will be returned. + */ + row(...a: { + }[]): void + } + interface Query { + /** + * Column executes the SQL statement and populates the first column of the result into a slice. + * Note that the parameter must be a pointer to a slice. + */ + column(a: { + }): void + } + interface Query { + /** + * Rows executes the SQL statement and returns a Rows object to allow retrieving data row by row. + */ + rows(): (Rows) + } + /** + * QueryBuilder builds different clauses for a SELECT SQL statement. + */ + interface QueryBuilder { + [key:string]: any; + /** + * BuildSelect generates a SELECT clause from the given selected column names. + */ + buildSelect(cols: Array, distinct: boolean, option: string): string + /** + * BuildFrom generates a FROM clause from the given tables. + */ + buildFrom(tables: Array): string + /** + * BuildGroupBy generates a GROUP BY clause from the given group-by columns. + */ + buildGroupBy(cols: Array): string + /** + * BuildJoin generates a JOIN clause from the given join information. + */ + buildJoin(_arg0: Array, _arg1: Params): string + /** + * BuildWhere generates a WHERE clause from the given expression. + */ + buildWhere(_arg0: Expression, _arg1: Params): string + /** + * BuildHaving generates a HAVING clause from the given expression. + */ + buildHaving(_arg0: Expression, _arg1: Params): string + /** + * BuildOrderByAndLimit generates the ORDER BY and LIMIT clauses. + */ + buildOrderByAndLimit(_arg0: string, _arg1: Array, _arg2: number, _arg3: number): string + /** + * BuildUnion generates a UNION clause from the given union information. + */ + buildUnion(_arg0: Array, _arg1: Params): string + } + /** + * BaseQueryBuilder provides a basic implementation of QueryBuilder. + */ + interface BaseQueryBuilder { + } + interface newBaseQueryBuilder { + /** + * NewBaseQueryBuilder creates a new BaseQueryBuilder instance. + */ + (db: DB): (BaseQueryBuilder) + } + interface BaseQueryBuilder { + /** + * DB returns the DB instance associated with the query builder. + */ + db(): (DB) + } + interface BaseQueryBuilder { + /** + * BuildSelect generates a SELECT clause from the given selected column names. + */ + buildSelect(cols: Array, distinct: boolean, option: string): string + } + interface BaseQueryBuilder { + /** + * BuildFrom generates a FROM clause from the given tables. + */ + buildFrom(tables: Array): string + } + interface BaseQueryBuilder { + /** + * BuildJoin generates a JOIN clause from the given join information. + */ + buildJoin(joins: Array, params: Params): string + } + interface BaseQueryBuilder { + /** + * BuildWhere generates a WHERE clause from the given expression. + */ + buildWhere(e: Expression, params: Params): string + } + interface BaseQueryBuilder { + /** + * BuildHaving generates a HAVING clause from the given expression. + */ + buildHaving(e: Expression, params: Params): string + } + interface BaseQueryBuilder { + /** + * BuildGroupBy generates a GROUP BY clause from the given group-by columns. + */ + buildGroupBy(cols: Array): string + } + interface BaseQueryBuilder { + /** + * BuildOrderByAndLimit generates the ORDER BY and LIMIT clauses. + */ + buildOrderByAndLimit(sql: string, cols: Array, limit: number, offset: number): string + } + interface BaseQueryBuilder { + /** + * BuildUnion generates a UNION clause from the given union information. + */ + buildUnion(unions: Array, params: Params): string + } + interface BaseQueryBuilder { + /** + * BuildOrderBy generates the ORDER BY clause. + */ + buildOrderBy(cols: Array): string + } + interface BaseQueryBuilder { + /** + * BuildLimit generates the LIMIT clause. + */ + buildLimit(limit: number, offset: number): string + } + /** + * VarTypeError indicates a variable type error when trying to populating a variable with DB result. + */ + interface VarTypeError extends String{} + interface VarTypeError { + /** + * Error returns the error message. + */ + error(): string + } + /** + * NullStringMap is a map of sql.NullString that can be used to hold DB query result. + * The map keys correspond to the DB column names, while the map values are their corresponding column values. + */ + interface NullStringMap extends _TygojaDict{} + /** + * Rows enhances sql.Rows by providing additional data query methods. + * Rows can be obtained by calling Query.Rows(). It is mainly used to populate data row by row. + */ + type _slJPdfI = sql.Rows + interface Rows extends _slJPdfI { + } + interface Rows { + /** + * ScanMap populates the current row of data into a NullStringMap. + * Note that the NullStringMap must not be nil, or it will panic. + * The NullStringMap will be populated using column names as keys and their values as + * the corresponding element values. + */ + scanMap(a: NullStringMap): void + } + interface Rows { + /** + * ScanStruct populates the current row of data into a struct. + * The struct must be given as a pointer. + * + * ScanStruct associates struct fields with DB table columns through a field mapping function. + * It populates a struct field with the data of its associated column. + * Note that only exported struct fields will be populated. + * + * By default, DefaultFieldMapFunc() is used to map struct fields to table columns. + * This function separates each word in a field name with a underscore and turns every letter into lower case. + * For example, "LastName" is mapped to "last_name", "MyID" is mapped to "my_id", and so on. + * To change the default behavior, set DB.FieldMapper with your custom mapping function. + * You may also set Query.FieldMapper to change the behavior for particular queries. + */ + scanStruct(a: { + }): void + } + /** + * BuildHookFunc defines a callback function that is executed on Query creation. + */ + interface BuildHookFunc {(q: Query): void } + /** + * SelectQuery represents a DB-agnostic SELECT query. + * It can be built into a DB-specific query by calling the Build() method. + */ + interface SelectQuery { + /** + * FieldMapper maps struct field names to DB column names. + */ + fieldMapper: FieldMapFunc + /** + * TableMapper maps structs to DB table names. + */ + tableMapper: TableMapFunc + } + /** + * JoinInfo contains the specification for a JOIN clause. + */ + interface JoinInfo { + join: string + table: string + on: Expression + } + /** + * UnionInfo contains the specification for a UNION clause. + */ + interface UnionInfo { + all: boolean + query?: Query + } + interface newSelectQuery { + /** + * NewSelectQuery creates a new SelectQuery instance. + */ + (builder: Builder, db: DB): (SelectQuery) + } + interface SelectQuery { + /** + * WithBuildHook runs the provided hook function with the query created on Build(). + */ + withBuildHook(fn: BuildHookFunc): (SelectQuery) + } + interface SelectQuery { + /** + * Context returns the context associated with the query. + */ + context(): context.Context + } + interface SelectQuery { + /** + * WithContext associates a context with the query. + */ + withContext(ctx: context.Context): (SelectQuery) + } + interface SelectQuery { + /** + * PreFragment sets SQL fragment that should be prepended before the select query (e.g. WITH clause). + */ + preFragment(fragment: string): (SelectQuery) + } + interface SelectQuery { + /** + * PostFragment sets SQL fragment that should be appended at the end of the select query. + */ + postFragment(fragment: string): (SelectQuery) + } + interface SelectQuery { + /** + * Select specifies the columns to be selected. + * Column names will be automatically quoted. + */ + select(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * AndSelect adds additional columns to be selected. + * Column names will be automatically quoted. + */ + andSelect(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * Distinct specifies whether to select columns distinctively. + * By default, distinct is false. + */ + distinct(v: boolean): (SelectQuery) + } + interface SelectQuery { + /** + * SelectOption specifies additional option that should be append to "SELECT". + */ + selectOption(option: string): (SelectQuery) + } + interface SelectQuery { + /** + * From specifies which tables to select from. + * Table names will be automatically quoted. + */ + from(...tables: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * Where specifies the WHERE condition. + */ + where(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * AndWhere concatenates a new WHERE condition with the existing one (if any) using "AND". + */ + andWhere(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * OrWhere concatenates a new WHERE condition with the existing one (if any) using "OR". + */ + orWhere(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * Join specifies a JOIN clause. + * The "typ" parameter specifies the JOIN type (e.g. "INNER JOIN", "LEFT JOIN"). + */ + join(typ: string, table: string, on: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * InnerJoin specifies an INNER JOIN clause. + * This is a shortcut method for Join. + */ + innerJoin(table: string, on: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * LeftJoin specifies a LEFT JOIN clause. + * This is a shortcut method for Join. + */ + leftJoin(table: string, on: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * RightJoin specifies a RIGHT JOIN clause. + * This is a shortcut method for Join. + */ + rightJoin(table: string, on: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * OrderBy specifies the ORDER BY clause. + * Column names will be properly quoted. A column name can contain "ASC" or "DESC" to indicate its ordering direction. + */ + orderBy(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * AndOrderBy appends additional columns to the existing ORDER BY clause. + * Column names will be properly quoted. A column name can contain "ASC" or "DESC" to indicate its ordering direction. + */ + andOrderBy(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * GroupBy specifies the GROUP BY clause. + * Column names will be properly quoted. + */ + groupBy(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * AndGroupBy appends additional columns to the existing GROUP BY clause. + * Column names will be properly quoted. + */ + andGroupBy(...cols: string[]): (SelectQuery) + } + interface SelectQuery { + /** + * Having specifies the HAVING clause. + */ + having(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * AndHaving concatenates a new HAVING condition with the existing one (if any) using "AND". + */ + andHaving(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * OrHaving concatenates a new HAVING condition with the existing one (if any) using "OR". + */ + orHaving(e: Expression): (SelectQuery) + } + interface SelectQuery { + /** + * Union specifies a UNION clause. + */ + union(q: Query): (SelectQuery) + } + interface SelectQuery { + /** + * UnionAll specifies a UNION ALL clause. + */ + unionAll(q: Query): (SelectQuery) + } + interface SelectQuery { + /** + * Limit specifies the LIMIT clause. + * A negative limit means no limit. + */ + limit(limit: number): (SelectQuery) + } + interface SelectQuery { + /** + * Offset specifies the OFFSET clause. + * A negative offset means no offset. + */ + offset(offset: number): (SelectQuery) + } + interface SelectQuery { + /** + * Bind specifies the parameter values to be bound to the query. + */ + bind(params: Params): (SelectQuery) + } + interface SelectQuery { + /** + * AndBind appends additional parameters to be bound to the query. + */ + andBind(params: Params): (SelectQuery) + } + interface SelectQuery { + /** + * Build builds the SELECT query and returns an executable Query object. + */ + build(): (Query) + } + interface SelectQuery { + /** + * One executes the SELECT query and populates the first row of the result into the specified variable. + * + * If the query does not specify a "from" clause, the method will try to infer the name of the table + * to be selected from by calling getTableName() which will return either the variable type name + * or the TableName() method if the variable implements the TableModel interface. + * + * Note that when the query has no rows in the result set, an sql.ErrNoRows will be returned. + */ + one(a: { + }): void + } + interface SelectQuery { + /** + * Model selects the row with the specified primary key and populates the model with the row data. + * + * The model variable should be a pointer to a struct. If the query does not specify a "from" clause, + * it will use the model struct to determine which table to select data from. It will also use the model + * to infer the name of the primary key column. Only simple primary key is supported. For composite primary keys, + * please use Where() to specify the filtering condition. + */ + model(pk: { + }, model: { + }): void + } + interface SelectQuery { + /** + * All executes the SELECT query and populates all rows of the result into a slice. + * + * Note that the slice must be passed in as a pointer. + * + * If the query does not specify a "from" clause, the method will try to infer the name of the table + * to be selected from by calling getTableName() which will return either the type name of the slice elements + * or the TableName() method if the slice element implements the TableModel interface. + */ + all(slice: { + }): void + } + interface SelectQuery { + /** + * Rows builds and executes the SELECT query and returns a Rows object for data retrieval purpose. + * This is a shortcut to SelectQuery.Build().Rows() + */ + rows(): (Rows) + } + interface SelectQuery { + /** + * Row builds and executes the SELECT query and populates the first row of the result into the specified variables. + * This is a shortcut to SelectQuery.Build().Row() + */ + row(...a: { + }[]): void + } + interface SelectQuery { + /** + * Column builds and executes the SELECT statement and populates the first column of the result into a slice. + * Note that the parameter must be a pointer to a slice. + * This is a shortcut to SelectQuery.Build().Column() + */ + column(a: { + }): void + } + /** + * QueryInfo represents a debug/info struct with exported SelectQuery fields. + */ + interface QueryInfo { + preFragment: string + postFragment: string + builder: Builder + selects: Array + distinct: boolean + selectOption: string + from: Array + where: Expression + join: Array + orderBy: Array + groupBy: Array + having: Expression + union: Array + limit: number + offset: number + params: Params + context: context.Context + buildHook: BuildHookFunc + } + interface SelectQuery { + /** + * Info exports common SelectQuery fields allowing to inspect the + * current select query options. + */ + info(): (QueryInfo) + } + /** + * FieldMapFunc converts a struct field name into a DB column name. + */ + interface FieldMapFunc {(_arg0: string): string } + /** + * TableMapFunc converts a sample struct into a DB table name. + */ + interface TableMapFunc {(a: { + }): string } + interface structInfo { + } + type _sBfpoyP = structInfo + interface structValue extends _sBfpoyP { + } + interface fieldInfo { + } + interface structInfoMapKey { + } + /** + * PostScanner is an optional interface used by ScanStruct. + */ + interface PostScanner { + [key:string]: any; + /** + * PostScan executes right after the struct has been populated + * with the DB values, allowing you to further normalize or validate + * the loaded data. + */ + postScan(): void + } + interface defaultFieldMapFunc { + /** + * DefaultFieldMapFunc maps a field name to a DB column name. + * The mapping rule set by this method is that words in a field name will be separated by underscores + * and the name will be turned into lower case. For example, "FirstName" maps to "first_name", and "MyID" becomes "my_id". + * See DB.FieldMapper for more details. + */ + (f: string): string + } + interface getTableName { + /** + * GetTableName implements the default way of determining the table name corresponding to the given model struct + * or slice of structs. To get the actual table name for a model, you should use DB.TableMapFunc() instead. + * Do not call this method in a model's TableName() method because it will cause infinite loop. + */ + (a: { + }): string + } + /** + * Tx enhances sql.Tx with additional querying methods. + */ + type _shkfJoE = Builder + interface Tx extends _shkfJoE { + } + interface Tx { + /** + * Commit commits the transaction. + */ + commit(): void + } + interface Tx { + /** + * Rollback aborts the transaction. + */ + rollback(): void + } +} + +namespace security { + interface s256Challenge { + /** + * S256Challenge creates base64 encoded sha256 challenge string derived from code. + * The padding of the result base64 string is stripped per [RFC 7636]. + * + * [RFC 7636]: https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 + */ + (code: string): string + } + interface md5 { + /** + * MD5 creates md5 hash from the provided plain text. + */ + (text: string): string + } + interface sha256 { + /** + * SHA256 creates sha256 hash as defined in FIPS 180-4 from the provided text. + */ + (text: string): string + } + interface sha512 { + /** + * SHA512 creates sha512 hash as defined in FIPS 180-4 from the provided text. + */ + (text: string): string + } + interface hs256 { + /** + * HS256 creates a HMAC hash with sha256 digest algorithm. + */ + (text: string, secret: string): string + } + interface hs512 { + /** + * HS512 creates a HMAC hash with sha512 digest algorithm. + */ + (text: string, secret: string): string + } + interface equal { + /** + * Equal compares two hash strings for equality without leaking timing information. + */ + (hash1: string, hash2: string): boolean + } + // @ts-ignore + import crand = rand + interface encrypt { + /** + * Encrypt encrypts "data" with the specified "key" (must be valid 32 char AES key). + * + * This method uses AES-256-GCM block cypher mode. + */ + (data: string|Array, key: string): string + } + interface decrypt { + /** + * Decrypt decrypts encrypted text with key (must be valid 32 chars AES key). + * + * This method uses AES-256-GCM block cypher mode. + */ + (cipherText: string, key: string): string|Array + } + interface parseUnverifiedJWT { + /** + * ParseUnverifiedJWT parses JWT and returns its claims + * but DOES NOT verify the signature. + * + * It verifies only the exp, iat and nbf claims. + */ + (token: string): jwt.MapClaims + } + interface parseJWT { + /** + * ParseJWT verifies and parses JWT and returns its claims. + */ + (token: string, verificationKey: string): jwt.MapClaims + } + interface newJWT { + /** + * NewJWT generates and returns new HS256 signed JWT. + */ + (payload: jwt.MapClaims, signingKey: string, duration: time.Duration): string + } + // @ts-ignore + import cryptoRand = rand + // @ts-ignore + import mathRand = rand + interface randomString { + /** + * RandomString generates a cryptographically random string with the specified length. + * + * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. + */ + (length: number): string + } + interface randomStringWithAlphabet { + /** + * RandomStringWithAlphabet generates a cryptographically random string + * with the specified length and characters set. + * + * It panics if for some reason rand.Int returns a non-nil error. + */ + (length: number, alphabet: string): string + } + interface pseudorandomString { + /** + * PseudorandomString generates a pseudorandom string with the specified length. + * + * The generated string matches [A-Za-z0-9]+ and it's transparent to URL-encoding. + * + * For a cryptographically random string (but a little bit slower) use RandomString instead. + */ + (length: number): string + } + interface pseudorandomStringWithAlphabet { + /** + * PseudorandomStringWithAlphabet generates a pseudorandom string + * with the specified length and characters set. + * + * For a cryptographically random (but a little bit slower) use RandomStringWithAlphabet instead. + */ + (length: number, alphabet: string): string + } + interface randomStringByRegex { + /** + * RandomStringByRegex generates a random string matching the regex pattern. + * If optFlags is not set, fallbacks to [syntax.Perl]. + * + * NB! While the source of the randomness comes from [crypto/rand] this method + * is not recommended to be used on its own in critical secure contexts because + * the generated length could vary too much on the used pattern and may not be + * as secure as simply calling [security.RandomString]. + * If you still insist on using it for such purposes, consider at least + * a large enough minimum length for the generated string, e.g. `[a-z0-9]{30}`. + * + * This function is inspired by github.com/pipe01/revregexp, github.com/lucasjones/reggen and other similar packages. + */ + (pattern: string, ...optFlags: syntax.Flags[]): string + } +} + +namespace filesystem { + /** + * FileReader defines an interface for a file resource reader. + */ + interface FileReader { + [key:string]: any; + open(): io.ReadSeekCloser + } + /** + * File defines a single file [io.ReadSeekCloser] resource. + * + * The file could be from a local path, multipart/form-data header, etc. + */ + interface File { + reader: FileReader + name: string + originalName: string + size: number + } + interface File { + /** + * AsMap implements [core.mapExtractor] and returns a value suitable + * to be used in an API rule expression. + */ + asMap(): _TygojaDict + } + interface newFileFromPath { + /** + * NewFileFromPath creates a new File instance from the provided local file path. + */ + (path: string): (File) + } + interface newFileFromBytes { + /** + * NewFileFromBytes creates a new File instance from the provided byte slice. + */ + (b: string|Array, name: string): (File) + } + interface newFileFromMultipart { + /** + * NewFileFromMultipart creates a new File from the provided multipart header. + */ + (mh: multipart.FileHeader): (File) + } + interface newFileFromURL { + /** + * NewFileFromURL creates a new File from the provided url by + * downloading the resource and load it as BytesReader. + * + * Example + * + * ``` + * ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + * defer cancel() + * + * file, err := filesystem.NewFileFromURL(ctx, "https://example.com/image.png") + * ``` + */ + (ctx: context.Context, url: string): (File) + } + /** + * MultipartReader defines a FileReader from [multipart.FileHeader]. + */ + interface MultipartReader { + header?: multipart.FileHeader + } + interface MultipartReader { + /** + * Open implements the [filesystem.FileReader] interface. + */ + open(): io.ReadSeekCloser + } + /** + * PathReader defines a FileReader from a local file path. + */ + interface PathReader { + path: string + } + interface PathReader { + /** + * Open implements the [filesystem.FileReader] interface. + */ + open(): io.ReadSeekCloser + } + /** + * BytesReader defines a FileReader from bytes content. + */ + interface BytesReader { + bytes: string|Array + } + interface BytesReader { + /** + * Open implements the [filesystem.FileReader] interface. + */ + open(): io.ReadSeekCloser + } + type _sYFgTpo = bytes.Reader + interface bytesReadSeekCloser extends _sYFgTpo { + } + interface bytesReadSeekCloser { + /** + * Close implements the [io.ReadSeekCloser] interface. + */ + close(): void + } + /** + * openFuncAsReader defines a FileReader from a bare Open function. + */ + interface openFuncAsReader {(): io.ReadSeekCloser } + interface openFuncAsReader { + /** + * Open implements the [filesystem.FileReader] interface. + */ + open(): io.ReadSeekCloser + } + interface System { + } + interface newS3 { + /** + * NewS3 initializes an S3 filesystem instance. + * + * NB! Make sure to call `Close()` after you are done working with it. + */ + (bucketName: string, region: string, endpoint: string, accessKey: string, secretKey: string, s3ForcePathStyle: boolean): (System) + } + interface newLocal { + /** + * NewLocal initializes a new local filesystem instance. + * + * NB! Make sure to call `Close()` after you are done working with it. + */ + (dirPath: string): (System) + } + interface System { + /** + * SetContext assigns the specified context to the current filesystem. + */ + setContext(ctx: context.Context): void + } + interface System { + /** + * Close releases any resources used for the related filesystem. + */ + close(): void + } + interface System { + /** + * Exists checks if file with fileKey path exists or not. + */ + exists(fileKey: string): boolean + } + interface System { + /** + * Attributes returns the attributes for the file with fileKey path. + * + * If the file doesn't exist it returns ErrNotFound. + */ + attributes(fileKey: string): (blob.Attributes) + } + interface System { + /** + * GetReader returns a file content reader for the given fileKey. + * + * NB! Make sure to call Close() on the file after you are done working with it. + * + * If the file doesn't exist returns ErrNotFound. + */ + getReader(fileKey: string): (blob.Reader) + } + interface System { + /** + * Deprecated: Please use GetReader(fileKey) instead. + */ + getFile(fileKey: string): (blob.Reader) + } + interface System { + /** + * GetReuploadableFile constructs a new reuploadable File value + * from the associated fileKey blob.Reader. + * + * If preserveName is false then the returned File.Name will have + * a new randomly generated suffix, otherwise it will reuse the original one. + * + * This method could be useful in case you want to clone an existing + * Record file and assign it to a new Record (e.g. in a Record duplicate action). + * + * If you simply want to copy an existing file to a new location you + * could check the Copy(srcKey, dstKey) method. + */ + getReuploadableFile(fileKey: string, preserveName: boolean): (File) + } + interface System { + /** + * Copy copies the file stored at srcKey to dstKey. + * + * If srcKey file doesn't exist, it returns ErrNotFound. + * + * If dstKey file already exists, it is overwritten. + */ + copy(srcKey: string, dstKey: string): void + } + interface System { + /** + * List returns a flat list with info for all files under the specified prefix. + */ + list(prefix: string): Array<(blob.ListObject | undefined)> + } + interface System { + /** + * Upload writes content into the fileKey location. + */ + upload(content: string|Array, fileKey: string): void + } + interface System { + /** + * UploadFile uploads the provided File to the fileKey location. + */ + uploadFile(file: File, fileKey: string): void + } + interface System { + /** + * UploadMultipart uploads the provided multipart file to the fileKey location. + */ + uploadMultipart(fh: multipart.FileHeader, fileKey: string): void + } + interface System { + /** + * Delete deletes stored file at fileKey location. + * + * If the file doesn't exist returns ErrNotFound. + */ + delete(fileKey: string): void + } + interface System { + /** + * DeletePrefix deletes everything starting with the specified prefix. + * + * The prefix could be subpath (ex. "/a/b/") or filename prefix (ex. "/a/b/file_"). + */ + deletePrefix(prefix: string): Array + } + interface System { + /** + * Checks if the provided dir prefix doesn't have any files. + * + * A trailing slash will be appended to a non-empty dir string argument + * to ensure that the checked prefix is a "directory". + * + * Returns "false" in case the has at least one file, otherwise - "true". + */ + isEmptyDir(dir: string): boolean + } + interface System { + /** + * Serve serves the file at fileKey location to an HTTP response. + * + * If the `download` query parameter is used the file will be always served for + * download no matter of its type (aka. with "Content-Disposition: attachment"). + * + * Internally this method uses [http.ServeContent] so Range requests, + * If-Match, If-Unmodified-Since, etc. headers are handled transparently. + */ + serve(res: http.ResponseWriter, req: http.Request, fileKey: string, name: string): void + } + interface System { + /** + * CreateThumb creates a new thumb image for the file at originalKey location. + * The new thumb file is stored at thumbKey location. + * + * thumbSize is in the format: + * - 0xH (eg. 0x100) - resize to H height preserving the aspect ratio + * - Wx0 (eg. 300x0) - resize to W width preserving the aspect ratio + * - WxH (eg. 300x100) - resize and crop to WxH viewbox (from center) + * - WxHt (eg. 300x100t) - resize and crop to WxH viewbox (from top) + * - WxHb (eg. 300x100b) - resize and crop to WxH viewbox (from bottom) + * - WxHf (eg. 300x100f) - fit inside a WxH viewbox (without cropping) + */ + createThumb(originalKey: string, thumbKey: string, thumbSize: string): void + } +} + +/** + * Package exec runs external commands. It wraps os.StartProcess to make it + * easier to remap stdin and stdout, connect I/O with pipes, and do other + * adjustments. + * + * Unlike the "system" library call from C and other languages, the + * os/exec package intentionally does not invoke the system shell and + * does not expand any glob patterns or handle other expansions, + * pipelines, or redirections typically done by shells. The package + * behaves more like C's "exec" family of functions. To expand glob + * patterns, either call the shell directly, taking care to escape any + * dangerous input, or use the [path/filepath] package's Glob function. + * To expand environment variables, use package os's ExpandEnv. + * + * Note that the examples in this package assume a Unix system. + * They may not run on Windows, and they do not run in the Go Playground + * used by golang.org and godoc.org. + * + * # Executables in the current directory + * + * The functions [Command] and [LookPath] look for a program + * in the directories listed in the current path, following the + * conventions of the host operating system. + * Operating systems have for decades included the current + * directory in this search, sometimes implicitly and sometimes + * configured explicitly that way by default. + * Modern practice is that including the current directory + * is usually unexpected and often leads to security problems. + * + * To avoid those security problems, as of Go 1.19, this package will not resolve a program + * using an implicit or explicit path entry relative to the current directory. + * That is, if you run [LookPath]("go"), it will not successfully return + * ./go on Unix nor .\go.exe on Windows, no matter how the path is configured. + * Instead, if the usual path algorithms would result in that answer, + * these functions return an error err satisfying [errors.Is](err, [ErrDot]). + * + * For example, consider these two program snippets: + * + * ``` + * path, err := exec.LookPath("prog") + * if err != nil { + * log.Fatal(err) + * } + * use(path) + * ``` + * + * and + * + * ``` + * cmd := exec.Command("prog") + * if err := cmd.Run(); err != nil { + * log.Fatal(err) + * } + * ``` + * + * These will not find and run ./prog or .\prog.exe, + * no matter how the current path is configured. + * + * Code that always wants to run a program from the current directory + * can be rewritten to say "./prog" instead of "prog". + * + * Code that insists on including results from relative path entries + * can instead override the error using an errors.Is check: + * + * ``` + * path, err := exec.LookPath("prog") + * if errors.Is(err, exec.ErrDot) { + * err = nil + * } + * if err != nil { + * log.Fatal(err) + * } + * use(path) + * ``` + * + * and + * + * ``` + * cmd := exec.Command("prog") + * if errors.Is(cmd.Err, exec.ErrDot) { + * cmd.Err = nil + * } + * if err := cmd.Run(); err != nil { + * log.Fatal(err) + * } + * ``` + * + * Setting the environment variable GODEBUG=execerrdot=0 + * disables generation of ErrDot entirely, temporarily restoring the pre-Go 1.19 + * behavior for programs that are unable to apply more targeted fixes. + * A future version of Go may remove support for this variable. + * + * Before adding such overrides, make sure you understand the + * security implications of doing so. + * See https://go.dev/blog/path-security for more information. + */ +namespace exec { + interface command { + /** + * Command returns the [Cmd] struct to execute the named program with + * the given arguments. + * + * It sets only the Path and Args in the returned structure. + * + * If name contains no path separators, Command uses [LookPath] to + * resolve name to a complete path if possible. Otherwise it uses name + * directly as Path. + * + * The returned Cmd's Args field is constructed from the command name + * followed by the elements of arg, so arg should not include the + * command name itself. For example, Command("echo", "hello"). + * Args[0] is always name, not the possibly resolved Path. + * + * On Windows, processes receive the whole command line as a single string + * and do their own parsing. Command combines and quotes Args into a command + * line string with an algorithm compatible with applications using + * CommandLineToArgvW (which is the most common way). Notable exceptions are + * msiexec.exe and cmd.exe (and thus, all batch files), which have a different + * unquoting algorithm. In these or other similar cases, you can do the + * quoting yourself and provide the full command line in SysProcAttr.CmdLine, + * leaving Args empty. + */ + (name: string, ...arg: string[]): (Cmd) + } +} + +/** + * Package core is the backbone of PocketBase. + * + * It defines the main PocketBase App interface and its base implementation. + */ +namespace core { + /** + * App defines the main PocketBase app interface. + * + * Note that the interface is not intended to be implemented manually by users + * and instead they should use core.BaseApp (either directly or as embedded field in a custom struct). + * + * This interface exists to make testing easier and to allow users to + * create common and pluggable helpers and methods that doesn't rely + * on a specific wrapped app struct (hence the large interface size). + */ + interface App { + [key:string]: any; + /** + * UnsafeWithoutHooks returns a shallow copy of the current app WITHOUT any registered hooks. + * + * NB! Note that using the returned app instance may cause data integrity errors + * since the Record validations and data normalizations (including files uploads) + * rely on the app hooks to work. + */ + unsafeWithoutHooks(): App + /** + * Logger returns the default app logger. + * + * If the application is not bootstrapped yet, fallbacks to slog.Default(). + */ + logger(): (slog.Logger) + /** + * IsBootstrapped checks if the application was initialized + * (aka. whether Bootstrap() was called). + */ + isBootstrapped(): boolean + /** + * IsTransactional checks if the current app instance is part of a transaction. + */ + isTransactional(): boolean + /** + * TxInfo returns the transaction associated with the current app instance (if any). + * + * Could be used if you want to execute indirectly a function after + * the related app transaction completes using `app.TxInfo().OnAfterFunc(callback)`. + */ + txInfo(): (TxAppInfo) + /** + * Bootstrap initializes the application + * (aka. create data dir, open db connections, load settings, etc.). + * + * It will call ResetBootstrapState() if the application was already bootstrapped. + */ + bootstrap(): void + /** + * ResetBootstrapState releases the initialized core app resources + * (closing db connections, stopping cron ticker, etc.). + */ + resetBootstrapState(): void + /** + * DataDir returns the app data directory path. + */ + dataDir(): string + /** + * EncryptionEnv returns the name of the app secret env key + * (currently used primarily for optional settings encryption but this may change in the future). + */ + encryptionEnv(): string + /** + * IsDev returns whether the app is in dev mode. + * + * When enabled logs, executed sql statements, etc. are printed to the stderr. + */ + isDev(): boolean + /** + * Settings returns the loaded app settings. + */ + settings(): (Settings) + /** + * Store returns the app runtime store. + */ + store(): (store.Store) + /** + * Cron returns the app cron instance. + */ + cron(): (cron.Cron) + /** + * SubscriptionsBroker returns the app realtime subscriptions broker instance. + */ + subscriptionsBroker(): (subscriptions.Broker) + /** + * NewMailClient creates and returns a new SMTP or Sendmail client + * based on the current app settings. + */ + newMailClient(): mailer.Mailer + /** + * NewFilesystem creates a new local or S3 filesystem instance + * for managing regular app files (ex. record uploads) + * based on the current app settings. + * + * NB! Make sure to call Close() on the returned result + * after you are done working with it. + */ + newFilesystem(): (filesystem.System) + /** + * NewBackupsFilesystem creates a new local or S3 filesystem instance + * for managing app backups based on the current app settings. + * + * NB! Make sure to call Close() on the returned result + * after you are done working with it. + */ + newBackupsFilesystem(): (filesystem.System) + /** + * ReloadSettings reinitializes and reloads the stored application settings. + */ + reloadSettings(): void + /** + * CreateBackup creates a new backup of the current app pb_data directory. + * + * Backups can be stored on S3 if it is configured in app.Settings().Backups. + * + * Please refer to the godoc of the specific CoreApp implementation + * for details on the backup procedures. + */ + createBackup(ctx: context.Context, name: string): void + /** + * RestoreBackup restores the backup with the specified name and restarts + * the current running application process. + * + * The safely perform the restore it is recommended to have free disk space + * for at least 2x the size of the restored pb_data backup. + * + * Please refer to the godoc of the specific CoreApp implementation + * for details on the restore procedures. + * + * NB! This feature is experimental and currently is expected to work only on UNIX based systems. + */ + restoreBackup(ctx: context.Context, name: string): void + /** + * Restart restarts (aka. replaces) the current running application process. + * + * NB! It relies on execve which is supported only on UNIX based systems. + */ + restart(): void + /** + * RunSystemMigrations applies all new migrations registered in the [core.SystemMigrations] list. + */ + runSystemMigrations(): void + /** + * RunAppMigrations applies all new migrations registered in the [CoreAppMigrations] list. + */ + runAppMigrations(): void + /** + * RunAllMigrations applies all system and app migrations + * (aka. from both [core.SystemMigrations] and [CoreAppMigrations]). + */ + runAllMigrations(): void + /** + * DB returns the default app data.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything else + * to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly ConcurrentDB() or NonconcurrentDB(). + */ + db(): dbx.Builder + /** + * ConcurrentDB returns the concurrent app data.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + concurrentDB(): dbx.Builder + /** + * NonconcurrentDB returns the nonconcurrent app data.db builder instance. + * + * The returned db instance is limited only to a single open connection, + * meaning that it can process only 1 db operation at a time (other queries queue up). + * + * This method is used mainly internally and in the tests to execute write + * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + nonconcurrentDB(): dbx.Builder + /** + * AuxDB returns the app auxiliary.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything else + * to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly AuxConcurrentDB() or AuxNonconcurrentDB(). + */ + auxDB(): dbx.Builder + /** + * AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxConcurrentDB(): dbx.Builder + /** + * AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. + * + * The returned db instance is limited only to a single open connection, + * meaning that it can process only 1 db operation at a time (other queries queue up). + * + * This method is used mainly internally and in the tests to execute write + * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxNonconcurrentDB(): dbx.Builder + /** + * HasTable checks if a table (or view) with the provided name exists (case insensitive). + * in the data.db. + */ + hasTable(tableName: string): boolean + /** + * AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) + * in the auxiliary.db. + */ + auxHasTable(tableName: string): boolean + /** + * TableColumns returns all column names of a single table by its name. + */ + tableColumns(tableName: string): Array + /** + * TableInfo returns the "table_info" pragma result for the specified table. + */ + tableInfo(tableName: string): Array<(TableInfoRow | undefined)> + /** + * TableIndexes returns a name grouped map with all non empty index of the specified table. + * + * Note: This method doesn't return an error on nonexisting table. + */ + tableIndexes(tableName: string): _TygojaDict + /** + * DeleteTable drops the specified table. + * + * This method is a no-op if a table with the provided name doesn't exist. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "tableName" argument must come only from trusted input! + */ + deleteTable(tableName: string): void + /** + * DeleteView drops the specified view name. + * + * This method is a no-op if a view with the provided name doesn't exist. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "name" argument must come only from trusted input! + */ + deleteView(name: string): void + /** + * SaveView creates (or updates already existing) persistent SQL view. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "selectQuery" argument must come only from trusted input! + */ + saveView(name: string, selectQuery: string): void + /** + * CreateViewFields creates a new FieldsList from the provided select query. + * + * There are some caveats: + * - The select query must have an "id" column. + * - Wildcard ("*") columns are not supported to avoid accidentally leaking sensitive data. + */ + createViewFields(selectQuery: string): FieldsList + /** + * FindRecordByViewFile returns the original Record of the provided view collection file. + */ + findRecordByViewFile(viewCollectionModelOrIdentifier: any, fileFieldName: string, filename: string): (Record) + /** + * Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. + */ + vacuum(): void + /** + * AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. + */ + auxVacuum(): void + /** + * ModelQuery creates a new preconfigured select data.db query with preset + * SELECT, FROM and other common fields based on the provided model. + */ + modelQuery(model: Model): (dbx.SelectQuery) + /** + * AuxModelQuery creates a new preconfigured select auxiliary.db query with preset + * SELECT, FROM and other common fields based on the provided model. + */ + auxModelQuery(model: Model): (dbx.SelectQuery) + /** + * Delete deletes the specified model from the regular app database. + */ + delete(model: Model): void + /** + * Delete deletes the specified model from the regular app database + * (the context could be used to limit the query execution). + */ + deleteWithContext(ctx: context.Context, model: Model): void + /** + * AuxDelete deletes the specified model from the auxiliary database. + */ + auxDelete(model: Model): void + /** + * AuxDeleteWithContext deletes the specified model from the auxiliary database + * (the context could be used to limit the query execution). + */ + auxDeleteWithContext(ctx: context.Context, model: Model): void + /** + * Save validates and saves the specified model into the regular app database. + * + * If you don't want to run validations, use [App.SaveNoValidate()]. + */ + save(model: Model): void + /** + * SaveWithContext is the same as [App.Save()] but allows specifying a context to limit the db execution. + * + * If you don't want to run validations, use [App.SaveNoValidateWithContext()]. + */ + saveWithContext(ctx: context.Context, model: Model): void + /** + * SaveNoValidate saves the specified model into the regular app database without performing validations. + * + * If you want to also run validations before persisting, use [App.Save()]. + */ + saveNoValidate(model: Model): void + /** + * SaveNoValidateWithContext is the same as [App.SaveNoValidate()] + * but allows specifying a context to limit the db execution. + * + * If you want to also run validations before persisting, use [App.SaveWithContext()]. + */ + saveNoValidateWithContext(ctx: context.Context, model: Model): void + /** + * AuxSave validates and saves the specified model into the auxiliary app database. + * + * If you don't want to run validations, use [App.AuxSaveNoValidate()]. + */ + auxSave(model: Model): void + /** + * AuxSaveWithContext is the same as [App.AuxSave()] but allows specifying a context to limit the db execution. + * + * If you don't want to run validations, use [App.AuxSaveNoValidateWithContext()]. + */ + auxSaveWithContext(ctx: context.Context, model: Model): void + /** + * AuxSaveNoValidate saves the specified model into the auxiliary app database without performing validations. + * + * If you want to also run validations before persisting, use [App.AuxSave()]. + */ + auxSaveNoValidate(model: Model): void + /** + * AuxSaveNoValidateWithContext is the same as [App.AuxSaveNoValidate()] + * but allows specifying a context to limit the db execution. + * + * If you want to also run validations before persisting, use [App.AuxSaveWithContext()]. + */ + auxSaveNoValidateWithContext(ctx: context.Context, model: Model): void + /** + * Validate triggers the OnModelValidate hook for the specified model. + */ + validate(model: Model): void + /** + * ValidateWithContext is the same as Validate but allows specifying the ModelEvent context. + */ + validateWithContext(ctx: context.Context, model: Model): void + /** + * RunInTransaction wraps fn into a transaction for the regular app database. + * + * It is safe to nest RunInTransaction calls as long as you use the callback's txApp. + */ + runInTransaction(fn: (txApp: App) => void): void + /** + * AuxRunInTransaction wraps fn into a transaction for the auxiliary app database. + * + * It is safe to nest RunInTransaction calls as long as you use the callback's txApp. + */ + auxRunInTransaction(fn: (txApp: App) => void): void + /** + * LogQuery returns a new Log select query. + */ + logQuery(): (dbx.SelectQuery) + /** + * FindLogById finds a single Log entry by its id. + */ + findLogById(id: string): (Log) + /** + * LogsStatsItem returns hourly grouped logs statistics. + */ + logsStats(expr: dbx.Expression): Array<(LogsStatsItem | undefined)> + /** + * DeleteOldLogs delete all logs that are created before createdBefore. + */ + deleteOldLogs(createdBefore: time.Time): void + /** + * CollectionQuery returns a new Collection select query. + */ + collectionQuery(): (dbx.SelectQuery) + /** + * FindCollections finds all collections by the given type(s). + * + * If collectionTypes is not set, it returns all collections. + * + * Example: + * + * ``` + * app.FindAllCollections() // all collections + * app.FindAllCollections("auth", "view") // only auth and view collections + * ``` + */ + findAllCollections(...collectionTypes: string[]): Array<(Collection | undefined)> + /** + * ReloadCachedCollections fetches all collections and caches them into the app store. + */ + reloadCachedCollections(): void + /** + * FindCollectionByNameOrId finds a single collection by its name (case insensitive) or id.s + */ + findCollectionByNameOrId(nameOrId: string): (Collection) + /** + * FindCachedCollectionByNameOrId is similar to [App.FindCollectionByNameOrId] + * but retrieves the Collection from the app cache instead of making a db call. + * + * NB! This method is suitable for read-only Collection operations. + * + * Returns [sql.ErrNoRows] if no Collection is found for consistency + * with the [App.FindCollectionByNameOrId] method. + * + * If you plan making changes to the returned Collection model, + * use [App.FindCollectionByNameOrId] instead. + * + * Caveats: + * + * ``` + * - The returned Collection should be used only for read-only operations. + * Avoid directly modifying the returned cached Collection as it will affect + * the global cached value even if you don't persist the changes in the database! + * - If you are updating a Collection in a transaction and then call this method before commit, + * it'll return the cached Collection state and not the one from the uncommitted transaction. + * - The cache is automatically updated on collections db change (create/update/delete). + * To manually reload the cache you can call [App.ReloadCachedCollections] + * ``` + */ + findCachedCollectionByNameOrId(nameOrId: string): (Collection) + /** + * FindCollectionReferences returns information for all relation + * fields referencing the provided collection. + * + * If the provided collection has reference to itself then it will be + * also included in the result. To exclude it, pass the collection id + * as the excludeIds argument. + */ + findCollectionReferences(collection: Collection, ...excludeIds: string[]): _TygojaDict + /** + * FindCachedCollectionReferences is similar to [App.FindCollectionReferences] + * but retrieves the Collection from the app cache instead of making a db call. + * + * NB! This method is suitable for read-only Collection operations. + * + * If you plan making changes to the returned Collection model, + * use [App.FindCollectionReferences] instead. + * + * Caveats: + * + * ``` + * - The returned Collection should be used only for read-only operations. + * Avoid directly modifying the returned cached Collection as it will affect + * the global cached value even if you don't persist the changes in the database! + * - If you are updating a Collection in a transaction and then call this method before commit, + * it'll return the cached Collection state and not the one from the uncommitted transaction. + * - The cache is automatically updated on collections db change (create/update/delete). + * To manually reload the cache you can call [App.ReloadCachedCollections]. + * ``` + */ + findCachedCollectionReferences(collection: Collection, ...excludeIds: string[]): _TygojaDict + /** + * IsCollectionNameUnique checks that there is no existing collection + * with the provided name (case insensitive!). + * + * Note: case insensitive check because the name is used also as + * table name for the records. + */ + isCollectionNameUnique(name: string, ...excludeIds: string[]): boolean + /** + * TruncateCollection deletes all records associated with the provided collection. + * + * The truncate operation is executed in a single transaction, + * aka. either everything is deleted or none. + * + * Note that this method will also trigger the records related + * cascade and file delete actions. + */ + truncateCollection(collection: Collection): void + /** + * ImportCollections imports the provided collections data in a single transaction. + * + * For existing matching collections, the imported data is unmarshaled on top of the existing model. + * + * NB! If deleteMissing is true, ALL NON-SYSTEM COLLECTIONS AND SCHEMA FIELDS, + * that are not present in the imported configuration, WILL BE DELETED + * (this includes their related records data). + */ + importCollections(toImport: Array<_TygojaDict>, deleteMissing: boolean): void + /** + * ImportCollectionsByMarshaledJSON is the same as [ImportCollections] + * but accept marshaled json array as import data (usually used for the autogenerated snapshots). + */ + importCollectionsByMarshaledJSON(rawSliceOfMaps: string|Array, deleteMissing: boolean): void + /** + * SyncRecordTableSchema compares the two provided collections + * and applies the necessary related record table changes. + * + * If oldCollection is null, then only newCollection is used to create the record table. + * + * This method is automatically invoked as part of a collection create/update/delete operation. + */ + syncRecordTableSchema(newCollection: Collection, oldCollection: Collection): void + /** + * FindAllExternalAuthsByRecord returns all ExternalAuth models + * linked to the provided auth record. + */ + findAllExternalAuthsByRecord(authRecord: Record): Array<(ExternalAuth | undefined)> + /** + * FindAllExternalAuthsByCollection returns all ExternalAuth models + * linked to the provided auth collection. + */ + findAllExternalAuthsByCollection(collection: Collection): Array<(ExternalAuth | undefined)> + /** + * FindFirstExternalAuthByExpr returns the first available (the most recent created) + * ExternalAuth model that satisfies the non-nil expression. + */ + findFirstExternalAuthByExpr(expr: dbx.Expression): (ExternalAuth) + /** + * FindAllMFAsByRecord returns all MFA models linked to the provided auth record. + */ + findAllMFAsByRecord(authRecord: Record): Array<(MFA | undefined)> + /** + * FindAllMFAsByCollection returns all MFA models linked to the provided collection. + */ + findAllMFAsByCollection(collection: Collection): Array<(MFA | undefined)> + /** + * FindMFAById returns a single MFA model by its id. + */ + findMFAById(id: string): (MFA) + /** + * DeleteAllMFAsByRecord deletes all MFA models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllMFAsByRecord(authRecord: Record): void + /** + * DeleteExpiredMFAs deletes the expired MFAs for all auth collections. + */ + deleteExpiredMFAs(): void + /** + * FindAllOTPsByRecord returns all OTP models linked to the provided auth record. + */ + findAllOTPsByRecord(authRecord: Record): Array<(OTP | undefined)> + /** + * FindAllOTPsByCollection returns all OTP models linked to the provided collection. + */ + findAllOTPsByCollection(collection: Collection): Array<(OTP | undefined)> + /** + * FindOTPById returns a single OTP model by its id. + */ + findOTPById(id: string): (OTP) + /** + * DeleteAllOTPsByRecord deletes all OTP models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllOTPsByRecord(authRecord: Record): void + /** + * DeleteExpiredOTPs deletes the expired OTPs for all auth collections. + */ + deleteExpiredOTPs(): void + /** + * FindAllAuthOriginsByRecord returns all AuthOrigin models linked to the provided auth record (in DESC order). + */ + findAllAuthOriginsByRecord(authRecord: Record): Array<(AuthOrigin | undefined)> + /** + * FindAllAuthOriginsByCollection returns all AuthOrigin models linked to the provided collection (in DESC order). + */ + findAllAuthOriginsByCollection(collection: Collection): Array<(AuthOrigin | undefined)> + /** + * FindAuthOriginById returns a single AuthOrigin model by its id. + */ + findAuthOriginById(id: string): (AuthOrigin) + /** + * FindAuthOriginByRecordAndFingerprint returns a single AuthOrigin model + * by its authRecord relation and fingerprint. + */ + findAuthOriginByRecordAndFingerprint(authRecord: Record, fingerprint: string): (AuthOrigin) + /** + * DeleteAllAuthOriginsByRecord deletes all AuthOrigin models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllAuthOriginsByRecord(authRecord: Record): void + /** + * RecordQuery returns a new Record select query from a collection model, id or name. + * + * In case a collection id or name is provided and that collection doesn't + * actually exists, the generated query will be created with a cancelled context + * and will fail once an executor (Row(), One(), All(), etc.) is called. + */ + recordQuery(collectionModelOrIdentifier: any): (dbx.SelectQuery) + /** + * FindRecordById finds the Record model by its id. + */ + findRecordById(collectionModelOrIdentifier: any, recordId: string, ...optFilters: ((q: dbx.SelectQuery) => void)[]): (Record) + /** + * FindRecordsByIds finds all records by the specified ids. + * If no records are found, returns an empty slice. + */ + findRecordsByIds(collectionModelOrIdentifier: any, recordIds: Array, ...optFilters: ((q: dbx.SelectQuery) => void)[]): Array<(Record | undefined)> + /** + * FindAllRecords finds all records matching specified db expressions. + * + * Returns all collection records if no expression is provided. + * + * Returns an empty slice if no records are found. + * + * Example: + * + * ``` + * // no extra expressions + * app.FindAllRecords("example") + * + * // with extra expressions + * expr1 := dbx.HashExp{"email": "test@example.com"} + * expr2 := dbx.NewExp("LOWER(username) = {:username}", dbx.Params{"username": "test"}) + * app.FindAllRecords("example", expr1, expr2) + * ``` + */ + findAllRecords(collectionModelOrIdentifier: any, ...exprs: dbx.Expression[]): Array<(Record | undefined)> + /** + * FindFirstRecordByData returns the first found record matching + * the provided key-value pair. + */ + findFirstRecordByData(collectionModelOrIdentifier: any, key: string, value: any): (Record) + /** + * FindRecordsByFilter returns limit number of records matching the + * provided string filter. + * + * NB! Use the last "params" argument to bind untrusted user variables! + * + * The filter argument is optional and can be empty string to target + * all available records. + * + * The sort argument is optional and can be empty string OR the same format + * used in the web APIs, ex. "-created,title". + * + * If the limit argument is <= 0, no limit is applied to the query and + * all matching records are returned. + * + * Returns an empty slice if no records are found. + * + * Example: + * + * ``` + * app.FindRecordsByFilter( + * "posts", + * "title ~ {:title} && visible = {:visible}", + * "-created", + * 10, + * 0, + * dbx.Params{"title": "lorem ipsum", "visible": true} + * ) + * ``` + */ + findRecordsByFilter(collectionModelOrIdentifier: any, filter: string, sort: string, limit: number, offset: number, ...params: dbx.Params[]): Array<(Record | undefined)> + /** + * FindFirstRecordByFilter returns the first available record matching the provided filter (if any). + * + * NB! Use the last params argument to bind untrusted user variables! + * + * Returns sql.ErrNoRows if no record is found. + * + * Example: + * + * ``` + * app.FindFirstRecordByFilter("posts", "") + * app.FindFirstRecordByFilter("posts", "slug={:slug} && status='public'", dbx.Params{"slug": "test"}) + * ``` + */ + findFirstRecordByFilter(collectionModelOrIdentifier: any, filter: string, ...params: dbx.Params[]): (Record) + /** + * CountRecords returns the total number of records in a collection. + */ + countRecords(collectionModelOrIdentifier: any, ...exprs: dbx.Expression[]): number + /** + * FindAuthRecordByToken finds the auth record associated with the provided JWT + * (auth, file, verifyEmail, changeEmail, passwordReset types). + * + * Optionally specify a list of validTypes to check tokens only from those types. + * + * Returns an error if the JWT is invalid, expired or not associated to an auth collection record. + */ + findAuthRecordByToken(token: string, ...validTypes: string[]): (Record) + /** + * FindAuthRecordByEmail finds the auth record associated with the provided email. + * + * Returns an error if it is not an auth collection or the record is not found. + */ + findAuthRecordByEmail(collectionModelOrIdentifier: any, email: string): (Record) + /** + * CanAccessRecord checks if a record is allowed to be accessed by the + * specified requestInfo and accessRule. + * + * Rule and db checks are ignored in case requestInfo.Auth is a superuser. + * + * The returned error indicate that something unexpected happened during + * the check (eg. invalid rule or db query error). + * + * The method always return false on invalid rule or db query error. + * + * Example: + * + * ``` + * requestInfo, _ := e.RequestInfo() + * record, _ := app.FindRecordById("example", "RECORD_ID") + * rule := types.Pointer("@request.auth.id != '' || status = 'public'") + * // ... or use one of the record collection's rule, eg. record.Collection().ViewRule + * + * if ok, _ := app.CanAccessRecord(record, requestInfo, rule); ok { ... } + * ``` + */ + canAccessRecord(record: Record, requestInfo: RequestInfo, accessRule: string): boolean + /** + * ExpandRecord expands the relations of a single Record model. + * + * If optFetchFunc is not set, then a default function will be used + * that returns all relation records. + * + * Returns a map with the failed expand parameters and their errors. + */ + expandRecord(record: Record, expands: Array, optFetchFunc: ExpandFetchFunc): _TygojaDict + /** + * ExpandRecords expands the relations of the provided Record models list. + * + * If optFetchFunc is not set, then a default function will be used + * that returns all relation records. + * + * Returns a map with the failed expand parameters and their errors. + */ + expandRecords(records: Array<(Record | undefined)>, expands: Array, optFetchFunc: ExpandFetchFunc): _TygojaDict + /** + * OnBootstrap hook is triggered when initializing the main application + * resources (db, app settings, etc). + */ + onBootstrap(): (hook.Hook) + /** + * OnServe hook is triggered when the app web server is started + * (after starting the TCP listener but before initializing the blocking serve task), + * allowing you to adjust its options and attach new routes or middlewares. + */ + onServe(): (hook.Hook) + /** + * OnTerminate hook is triggered when the app is in the process + * of being terminated (ex. on SIGTERM signal). + * + * Note that the app could be terminated abruptly without awaiting the hook completion. + */ + onTerminate(): (hook.Hook) + /** + * OnBackupCreate hook is triggered on each [App.CreateBackup] call. + */ + onBackupCreate(): (hook.Hook) + /** + * OnBackupRestore hook is triggered before app backup restore (aka. [App.RestoreBackup] call). + * + * Note that by default on success the application is restarted and the after state of the hook is ignored. + */ + onBackupRestore(): (hook.Hook) + /** + * OnModelValidate is triggered every time when a model is being validated + * (e.g. triggered by App.Validate() or App.Save()). + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelValidate(...tags: string[]): (hook.TaggedHook) + /** + * OnModelCreate is triggered every time when a new model is being created + * (e.g. triggered by App.Save()). + * + * Operations BEFORE the e.Next() execute before the model validation + * and the INSERT DB statement. + * + * Operations AFTER the e.Next() execute after the model validation + * and the INSERT DB statement. + * + * Note that successful execution doesn't guarantee that the model + * is persisted in the database since its wrapping transaction may + * not have been committed yet. + * If you want to listen to only the actual persisted events, you can + * bind to [OnModelAfterCreateSuccess] or [OnModelAfterCreateError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelCreate(...tags: string[]): (hook.TaggedHook) + /** + * OnModelCreateExecute is triggered after successful Model validation + * and right before the model INSERT DB statement execution. + * + * Usually it is triggered as part of the App.Save() in the following firing order: + * OnModelCreate { + * ``` + * -> OnModelValidate (skipped with App.SaveNoValidate()) + * -> OnModelCreateExecute + * ``` + * } + * + * Note that successful execution doesn't guarantee that the model + * is persisted in the database since its wrapping transaction may have been + * committed yet. + * If you want to listen to only the actual persisted events, + * you can bind to [OnModelAfterCreateSuccess] or [OnModelAfterCreateError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelCreateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterCreateSuccess is triggered after each successful + * Model DB create persistence. + * + * Note that when a Model is persisted as part of a transaction, + * this hook is delayed and executed only AFTER the transaction has been committed. + * This hook is NOT triggered in case the transaction rollbacks + * (aka. when the model wasn't persisted). + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterCreateError is triggered after each failed + * Model DB create persistence. + * + * Note that the execution of this hook is either immediate or delayed + * depending on the error: + * ``` + * - "immediate" on App.Save() failure + * - "delayed" on transaction rollback + * ``` + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterCreateError(...tags: string[]): (hook.TaggedHook) + /** + * OnModelUpdate is triggered every time when a new model is being updated + * (e.g. triggered by App.Save()). + * + * Operations BEFORE the e.Next() execute before the model validation + * and the UPDATE DB statement. + * + * Operations AFTER the e.Next() execute after the model validation + * and the UPDATE DB statement. + * + * Note that successful execution doesn't guarantee that the model + * is persisted in the database since its wrapping transaction may + * not have been committed yet. + * If you want to listen to only the actual persisted events, you can + * bind to [OnModelAfterUpdateSuccess] or [OnModelAfterUpdateError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelUpdate(...tags: string[]): (hook.TaggedHook) + /** + * OnModelUpdateExecute is triggered after successful Model validation + * and right before the model UPDATE DB statement execution. + * + * Usually it is triggered as part of the App.Save() in the following firing order: + * OnModelUpdate { + * ``` + * -> OnModelValidate (skipped with App.SaveNoValidate()) + * -> OnModelUpdateExecute + * ``` + * } + * + * Note that successful execution doesn't guarantee that the model + * is persisted in the database since its wrapping transaction may have been + * committed yet. + * If you want to listen to only the actual persisted events, + * you can bind to [OnModelAfterUpdateSuccess] or [OnModelAfterUpdateError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelUpdateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterUpdateSuccess is triggered after each successful + * Model DB update persistence. + * + * Note that when a Model is persisted as part of a transaction, + * this hook is delayed and executed only AFTER the transaction has been committed. + * This hook is NOT triggered in case the transaction rollbacks + * (aka. when the model changes weren't persisted). + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterUpdateError is triggered after each failed + * Model DB update persistence. + * + * Note that the execution of this hook is either immediate or delayed + * depending on the error: + * ``` + * - "immediate" on App.Save() failure + * - "delayed" on transaction rollback + * ``` + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterUpdateError(...tags: string[]): (hook.TaggedHook) + /** + * OnModelDelete is triggered every time when a new model is being deleted + * (e.g. triggered by App.Delete()). + * + * Note that successful execution doesn't guarantee that the model + * is deleted from the database since its wrapping transaction may + * not have been committed yet. + * If you want to listen to only the actual persisted deleted events, you can + * bind to [OnModelAfterDeleteSuccess] or [OnModelAfterDeleteError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelDelete(...tags: string[]): (hook.TaggedHook) + /** + * OnModelUpdateExecute is triggered right before the model + * DELETE DB statement execution. + * + * Usually it is triggered as part of the App.Delete() in the following firing order: + * OnModelDelete { + * ``` + * -> (internal delete checks) + * -> OnModelDeleteExecute + * ``` + * } + * + * Note that successful execution doesn't guarantee that the model + * is deleted from the database since its wrapping transaction may + * not have been committed yet. + * If you want to listen to only the actual persisted deleted events, you can + * bind to [OnModelAfterDeleteSuccess] or [OnModelAfterDeleteError] hooks. + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelDeleteExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterDeleteSuccess is triggered after each successful + * Model DB delete persistence. + * + * Note that when a Model is deleted as part of a transaction, + * this hook is delayed and executed only AFTER the transaction has been committed. + * This hook is NOT triggered in case the transaction rollbacks + * (aka. when the model delete wasn't persisted). + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnModelAfterDeleteError is triggered after each failed + * Model DB delete persistence. + * + * Note that the execution of this hook is either immediate or delayed + * depending on the error: + * ``` + * - "immediate" on App.Delete() failure + * - "delayed" on transaction rollback + * ``` + * + * For convenience, if you want to listen to only the Record models + * events without doing manual type assertion, you can attach to the OnRecord* proxy hooks. + * + * If the optional "tags" list (Collection id/name, Model table name, etc.) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onModelAfterDeleteError(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordEnrich is triggered every time when a record is enriched + * (as part of the builtin Record responses, during realtime message seriazation, or when [apis.EnrichRecord] is invoked). + * + * It could be used for example to redact/hide or add computed temporary + * Record model props only for the specific request info. For example: + * + * app.OnRecordEnrich("posts").BindFunc(func(e core.*RecordEnrichEvent) { + * ``` + * // hide one or more fields + * e.Record.Hide("role") + * + * // add new custom field for registered users + * if e.RequestInfo.Auth != nil && e.RequestInfo.Auth.Collection().Name == "users" { + * e.Record.WithCustomData(true) // for security requires explicitly allowing it + * e.Record.Set("computedScore", e.Record.GetInt("score") * e.RequestInfo.Auth.GetInt("baseScore")) + * } + * + * return e.Next() + * ``` + * }) + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordEnrich(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordValidate is a Record proxy model hook of [OnModelValidate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordValidate(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordCreate is a Record proxy model hook of [OnModelCreate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordCreate(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordCreateExecute is a Record proxy model hook of [OnModelCreateExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordCreateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterCreateSuccess is a Record proxy model hook of [OnModelAfterCreateSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterCreateError is a Record proxy model hook of [OnModelAfterCreateError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterCreateError(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordUpdate is a Record proxy model hook of [OnModelUpdate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordUpdate(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordUpdateExecute is a Record proxy model hook of [OnModelUpdateExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordUpdateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterUpdateSuccess is a Record proxy model hook of [OnModelAfterUpdateSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterUpdateError is a Record proxy model hook of [OnModelAfterUpdateError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterUpdateError(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordDelete is a Record proxy model hook of [OnModelDelete]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordDelete(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordDeleteExecute is a Record proxy model hook of [OnModelDeleteExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordDeleteExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterDeleteSuccess is a Record proxy model hook of [OnModelAfterDeleteSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAfterDeleteError is a Record proxy model hook of [OnModelAfterDeleteError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAfterDeleteError(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionValidate is a Collection proxy model hook of [OnModelValidate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionValidate(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionCreate is a Collection proxy model hook of [OnModelCreate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionCreate(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionCreateExecute is a Collection proxy model hook of [OnModelCreateExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionCreateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterCreateSuccess is a Collection proxy model hook of [OnModelAfterCreateSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterCreateError is a Collection proxy model hook of [OnModelAfterCreateError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterCreateError(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionUpdate is a Collection proxy model hook of [OnModelUpdate]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionUpdate(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionUpdateExecute is a Collection proxy model hook of [OnModelUpdateExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionUpdateExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterUpdateSuccess is a Collection proxy model hook of [OnModelAfterUpdateSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterUpdateError is a Collection proxy model hook of [OnModelAfterUpdateError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterUpdateError(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionDelete is a Collection proxy model hook of [OnModelDelete]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionDelete(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionDeleteExecute is a Collection proxy model hook of [OnModelDeleteExecute]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionDeleteExecute(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterDeleteSuccess is a Collection proxy model hook of [OnModelAfterDeleteSuccess]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionAfterDeleteError is a Collection proxy model hook of [OnModelAfterDeleteError]. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onCollectionAfterDeleteError(...tags: string[]): (hook.TaggedHook) + /** + * OnMailerSend hook is triggered every time when a new email is + * being send using the [App.NewMailClient()] instance. + * + * It allows intercepting the email message or to use a custom mailer client. + */ + onMailerSend(): (hook.Hook) + /** + * OnMailerRecordAuthAlertSend hook is triggered when + * sending a new device login auth alert email, allowing you to + * intercept and customize the email message that is being sent. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onMailerRecordAuthAlertSend(...tags: string[]): (hook.TaggedHook) + /** + * OnMailerBeforeRecordResetPasswordSend hook is triggered when + * sending a password reset email to an auth record, allowing + * you to intercept and customize the email message that is being sent. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onMailerRecordPasswordResetSend(...tags: string[]): (hook.TaggedHook) + /** + * OnMailerBeforeRecordVerificationSend hook is triggered when + * sending a verification email to an auth record, allowing + * you to intercept and customize the email message that is being sent. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onMailerRecordVerificationSend(...tags: string[]): (hook.TaggedHook) + /** + * OnMailerRecordEmailChangeSend hook is triggered when sending a + * confirmation new address email to an auth record, allowing + * you to intercept and customize the email message that is being sent. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onMailerRecordEmailChangeSend(...tags: string[]): (hook.TaggedHook) + /** + * OnMailerRecordOTPSend hook is triggered when sending an OTP email + * to an auth record, allowing you to intercept and customize the + * email message that is being sent. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onMailerRecordOTPSend(...tags: string[]): (hook.TaggedHook) + /** + * OnRealtimeConnectRequest hook is triggered when establishing the SSE client connection. + * + * Any execution after e.Next() of a hook handler happens after the client disconnects. + */ + onRealtimeConnectRequest(): (hook.Hook) + /** + * OnRealtimeMessageSend hook is triggered when sending an SSE message to a client. + */ + onRealtimeMessageSend(): (hook.Hook) + /** + * OnRealtimeSubscribeRequest hook is triggered when updating the + * client subscriptions, allowing you to further validate and + * modify the submitted change. + */ + onRealtimeSubscribeRequest(): (hook.Hook) + /** + * OnSettingsListRequest hook is triggered on each API Settings list request. + * + * Could be used to validate or modify the response before returning it to the client. + */ + onSettingsListRequest(): (hook.Hook) + /** + * OnSettingsUpdateRequest hook is triggered on each API Settings update request. + * + * Could be used to additionally validate the request data or + * implement completely different persistence behavior. + */ + onSettingsUpdateRequest(): (hook.Hook) + /** + * OnSettingsReload hook is triggered every time when the App.Settings() + * is being replaced with a new state. + * + * Calling App.Settings() after e.Next() returns the new state. + */ + onSettingsReload(): (hook.Hook) + /** + * OnFileDownloadRequest hook is triggered before each API File download request. + * + * Could be used to validate or modify the file response before + * returning it to the client. + */ + onFileDownloadRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnFileBeforeTokenRequest hook is triggered on each auth file token API request. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onFileTokenRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAuthRequest hook is triggered on each successful API + * record authentication request (sign-in, token refresh, etc.). + * + * Could be used to additionally validate or modify the authenticated + * record data and token. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAuthRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAuthWithPasswordRequest hook is triggered on each + * Record auth with password API request. + * + * [RecordAuthWithPasswordRequestEvent.Record] could be nil if no matching identity is found, allowing + * you to manually locate a different Record model (by reassigning [RecordAuthWithPasswordRequestEvent.Record]). + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAuthWithPasswordRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAuthWithOAuth2Request hook is triggered on each Record + * OAuth2 sign-in/sign-up API request (after token exchange and before external provider linking). + * + * If [RecordAuthWithOAuth2RequestEvent.Record] is not set, then the OAuth2 + * request will try to create a new auth Record. + * + * To assign or link a different existing record model you can + * change the [RecordAuthWithOAuth2RequestEvent.Record] field. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAuthWithOAuth2Request(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAuthRefreshRequest hook is triggered on each Record + * auth refresh API request (right before generating a new auth token). + * + * Could be used to additionally validate the request data or implement + * completely different auth refresh behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAuthRefreshRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordRequestPasswordResetRequest hook is triggered on + * each Record request password reset API request. + * + * Could be used to additionally validate the request data or implement + * completely different password reset behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordRequestPasswordResetRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordConfirmPasswordResetRequest hook is triggered on + * each Record confirm password reset API request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordConfirmPasswordResetRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordRequestVerificationRequest hook is triggered on + * each Record request verification API request. + * + * Could be used to additionally validate the loaded request data or implement + * completely different verification behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordRequestVerificationRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordConfirmVerificationRequest hook is triggered on each + * Record confirm verification API request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordConfirmVerificationRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordRequestEmailChangeRequest hook is triggered on each + * Record request email change API request. + * + * Could be used to additionally validate the request data or implement + * completely different request email change behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordRequestEmailChangeRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordConfirmEmailChangeRequest hook is triggered on each + * Record confirm email change API request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordConfirmEmailChangeRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordRequestOTPRequest hook is triggered on each Record + * request OTP API request. + * + * [RecordCreateOTPRequestEvent.Record] could be nil if no matching identity is found, allowing + * you to manually create or locate a different Record model (by reassigning [RecordCreateOTPRequestEvent.Record]). + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordRequestOTPRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordAuthWithOTPRequest hook is triggered on each Record + * auth with OTP API request. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordAuthWithOTPRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordsListRequest hook is triggered on each API Records list request. + * + * Could be used to validate or modify the response before returning it to the client. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordsListRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordViewRequest hook is triggered on each API Record view request. + * + * Could be used to validate or modify the response before returning it to the client. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordViewRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordCreateRequest hook is triggered on each API Record create request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordCreateRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordUpdateRequest hook is triggered on each API Record update request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordUpdateRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnRecordDeleteRequest hook is triggered on each API Record delete request. + * + * Could be used to additionally validate the request data or implement + * completely different delete behavior. + * + * If the optional "tags" list (Collection ids or names) is specified, + * then all event handlers registered via the created hook will be + * triggered and called only if their event data origin matches the tags. + */ + onRecordDeleteRequest(...tags: string[]): (hook.TaggedHook) + /** + * OnCollectionsListRequest hook is triggered on each API Collections list request. + * + * Could be used to validate or modify the response before returning it to the client. + */ + onCollectionsListRequest(): (hook.Hook) + /** + * OnCollectionViewRequest hook is triggered on each API Collection view request. + * + * Could be used to validate or modify the response before returning it to the client. + */ + onCollectionViewRequest(): (hook.Hook) + /** + * OnCollectionCreateRequest hook is triggered on each API Collection create request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + */ + onCollectionCreateRequest(): (hook.Hook) + /** + * OnCollectionUpdateRequest hook is triggered on each API Collection update request. + * + * Could be used to additionally validate the request data or implement + * completely different persistence behavior. + */ + onCollectionUpdateRequest(): (hook.Hook) + /** + * OnCollectionDeleteRequest hook is triggered on each API Collection delete request. + * + * Could be used to additionally validate the request data or implement + * completely different delete behavior. + */ + onCollectionDeleteRequest(): (hook.Hook) + /** + * OnCollectionsBeforeImportRequest hook is triggered on each API + * collections import request. + * + * Could be used to additionally validate the imported collections or + * to implement completely different import behavior. + */ + onCollectionsImportRequest(): (hook.Hook) + /** + * OnBatchRequest hook is triggered on each API batch request. + * + * Could be used to additionally validate or modify the submitted batch requests. + */ + onBatchRequest(): (hook.Hook) + } + // @ts-ignore + import validation = ozzo_validation + /** + * AuthOrigin defines a Record proxy for working with the authOrigins collection. + */ + type _sTFKJuk = Record + interface AuthOrigin extends _sTFKJuk { + } + interface newAuthOrigin { + /** + * NewAuthOrigin instantiates and returns a new blank *AuthOrigin model. + * + * Example usage: + * + * ``` + * origin := core.NewOrigin(app) + * origin.SetRecordRef(user.Id) + * origin.SetCollectionRef(user.Collection().Id) + * origin.SetFingerprint("...") + * app.Save(origin) + * ``` + */ + (app: App): (AuthOrigin) + } + interface AuthOrigin { + /** + * PreValidate implements the [PreValidator] interface and checks + * whether the proxy is properly loaded. + */ + preValidate(ctx: context.Context, app: App): void + } + interface AuthOrigin { + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + } + interface AuthOrigin { + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + interface AuthOrigin { + /** + * CollectionRef returns the "collectionRef" field value. + */ + collectionRef(): string + } + interface AuthOrigin { + /** + * SetCollectionRef updates the "collectionRef" record field value. + */ + setCollectionRef(collectionId: string): void + } + interface AuthOrigin { + /** + * RecordRef returns the "recordRef" record field value. + */ + recordRef(): string + } + interface AuthOrigin { + /** + * SetRecordRef updates the "recordRef" record field value. + */ + setRecordRef(recordId: string): void + } + interface AuthOrigin { + /** + * Fingerprint returns the "fingerprint" record field value. + */ + fingerprint(): string + } + interface AuthOrigin { + /** + * SetFingerprint updates the "fingerprint" record field value. + */ + setFingerprint(fingerprint: string): void + } + interface AuthOrigin { + /** + * Created returns the "created" record field value. + */ + created(): types.DateTime + } + interface AuthOrigin { + /** + * Updated returns the "updated" record field value. + */ + updated(): types.DateTime + } + interface BaseApp { + /** + * FindAllAuthOriginsByRecord returns all AuthOrigin models linked to the provided auth record (in DESC order). + */ + findAllAuthOriginsByRecord(authRecord: Record): Array<(AuthOrigin | undefined)> + } + interface BaseApp { + /** + * FindAllAuthOriginsByCollection returns all AuthOrigin models linked to the provided collection (in DESC order). + */ + findAllAuthOriginsByCollection(collection: Collection): Array<(AuthOrigin | undefined)> + } + interface BaseApp { + /** + * FindAuthOriginById returns a single AuthOrigin model by its id. + */ + findAuthOriginById(id: string): (AuthOrigin) + } + interface BaseApp { + /** + * FindAuthOriginByRecordAndFingerprint returns a single AuthOrigin model + * by its authRecord relation and fingerprint. + */ + findAuthOriginByRecordAndFingerprint(authRecord: Record, fingerprint: string): (AuthOrigin) + } + interface BaseApp { + /** + * DeleteAllAuthOriginsByRecord deletes all AuthOrigin models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllAuthOriginsByRecord(authRecord: Record): void + } + /** + * FilesManager defines an interface with common methods that files manager models should implement. + */ + interface FilesManager { + [key:string]: any; + /** + * BaseFilesPath returns the storage dir path used by the interface instance. + */ + baseFilesPath(): string + } + /** + * DBConnectFunc defines a database connection initialization function. + */ + interface DBConnectFunc {(dbPath: string): (dbx.DB) } + /** + * BaseAppConfig defines a BaseApp configuration option + */ + interface BaseAppConfig { + dbConnect: DBConnectFunc + dataDir: string + encryptionEnv: string + queryTimeout: time.Duration + dataMaxOpenConns: number + dataMaxIdleConns: number + auxMaxOpenConns: number + auxMaxIdleConns: number + isDev: boolean + } + /** + * BaseApp implements CoreApp and defines the base PocketBase app structure. + */ + interface BaseApp { + } + interface newBaseApp { + /** + * NewBaseApp creates and returns a new BaseApp instance + * configured with the provided arguments. + * + * To initialize the app, you need to call `app.Bootstrap()`. + */ + (config: BaseAppConfig): (BaseApp) + } + interface BaseApp { + /** + * UnsafeWithoutHooks returns a shallow copy of the current app WITHOUT any registered hooks. + * + * NB! Note that using the returned app instance may cause data integrity errors + * since the Record validations and data normalizations (including files uploads) + * rely on the app hooks to work. + */ + unsafeWithoutHooks(): App + } + interface BaseApp { + /** + * Logger returns the default app logger. + * + * If the application is not bootstrapped yet, fallbacks to slog.Default(). + */ + logger(): (slog.Logger) + } + interface BaseApp { + /** + * TxInfo returns the transaction associated with the current app instance (if any). + * + * Could be used if you want to execute indirectly a function after + * the related app transaction completes using `app.TxInfo().OnAfterFunc(callback)`. + */ + txInfo(): (TxAppInfo) + } + interface BaseApp { + /** + * IsTransactional checks if the current app instance is part of a transaction. + */ + isTransactional(): boolean + } + interface BaseApp { + /** + * IsBootstrapped checks if the application was initialized + * (aka. whether Bootstrap() was called). + */ + isBootstrapped(): boolean + } + interface BaseApp { + /** + * Bootstrap initializes the application + * (aka. create data dir, open db connections, load settings, etc.). + * + * It will call ResetBootstrapState() if the application was already bootstrapped. + */ + bootstrap(): void + } + interface closer { + [key:string]: any; + close(): void + } + interface BaseApp { + /** + * ResetBootstrapState releases the initialized core app resources + * (closing db connections, stopping cron ticker, etc.). + */ + resetBootstrapState(): void + } + interface BaseApp { + /** + * DB returns the default app data.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything + * else to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly ConcurrentDB() or NonconcurrentDB(). + */ + db(): dbx.Builder + } + interface BaseApp { + /** + * ConcurrentDB returns the concurrent app data.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + concurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * NonconcurrentDB returns the nonconcurrent app data.db builder instance. + * + * The returned db instance is limited only to a single open connection, + * meaning that it can process only 1 db operation at a time (other queries queue up). + * + * This method is used mainly internally and in the tests to execute write + * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. + * + * Most users should use simply DB() as it will automatically + * route the query execution to ConcurrentDB() or NonconcurrentDB(). + * + * In a transaction the ConcurrentDB() and NonconcurrentDB() refer to the same *dbx.TX instance. + */ + nonconcurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * AuxDB returns the app auxiliary.db builder instance. + * + * To minimize SQLITE_BUSY errors, it automatically routes the + * SELECT queries to the underlying concurrent db pool and everything + * else to the nonconcurrent one. + * + * For more finer control over the used connections pools you can + * call directly AuxConcurrentDB() or AuxNonconcurrentDB(). + */ + auxDB(): dbx.Builder + } + interface BaseApp { + /** + * AuxConcurrentDB returns the concurrent app auxiliary.db builder instance. + * + * This method is used mainly internally for executing db read + * operations in a concurrent/non-blocking manner. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxConcurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * AuxNonconcurrentDB returns the nonconcurrent app auxiliary.db builder instance. + * + * The returned db instance is limited only to a single open connection, + * meaning that it can process only 1 db operation at a time (other queries queue up). + * + * This method is used mainly internally and in the tests to execute write + * (save/delete) db operations as it helps with minimizing the SQLITE_BUSY errors. + * + * Most users should use simply AuxDB() as it will automatically + * route the query execution to AuxConcurrentDB() or AuxNonconcurrentDB(). + * + * In a transaction the AuxConcurrentDB() and AuxNonconcurrentDB() refer to the same *dbx.TX instance. + */ + auxNonconcurrentDB(): dbx.Builder + } + interface BaseApp { + /** + * DataDir returns the app data directory path. + */ + dataDir(): string + } + interface BaseApp { + /** + * EncryptionEnv returns the name of the app secret env key + * (currently used primarily for optional settings encryption but this may change in the future). + */ + encryptionEnv(): string + } + interface BaseApp { + /** + * IsDev returns whether the app is in dev mode. + * + * When enabled logs, executed sql statements, etc. are printed to the stderr. + */ + isDev(): boolean + } + interface BaseApp { + /** + * Settings returns the loaded app settings. + */ + settings(): (Settings) + } + interface BaseApp { + /** + * Store returns the app runtime store. + */ + store(): (store.Store) + } + interface BaseApp { + /** + * Cron returns the app cron instance. + */ + cron(): (cron.Cron) + } + interface BaseApp { + /** + * SubscriptionsBroker returns the app realtime subscriptions broker instance. + */ + subscriptionsBroker(): (subscriptions.Broker) + } + interface BaseApp { + /** + * NewMailClient creates and returns a new SMTP or Sendmail client + * based on the current app settings. + */ + newMailClient(): mailer.Mailer + } + interface BaseApp { + /** + * NewFilesystem creates a new local or S3 filesystem instance + * for managing regular app files (ex. record uploads) + * based on the current app settings. + * + * NB! Make sure to call Close() on the returned result + * after you are done working with it. + */ + newFilesystem(): (filesystem.System) + } + interface BaseApp { + /** + * NewBackupsFilesystem creates a new local or S3 filesystem instance + * for managing app backups based on the current app settings. + * + * NB! Make sure to call Close() on the returned result + * after you are done working with it. + */ + newBackupsFilesystem(): (filesystem.System) + } + interface BaseApp { + /** + * Restart restarts (aka. replaces) the current running application process. + * + * NB! It relies on execve which is supported only on UNIX based systems. + */ + restart(): void + } + interface BaseApp { + /** + * RunSystemMigrations applies all new migrations registered in the [core.SystemMigrations] list. + */ + runSystemMigrations(): void + } + interface BaseApp { + /** + * RunAppMigrations applies all new migrations registered in the [CoreAppMigrations] list. + */ + runAppMigrations(): void + } + interface BaseApp { + /** + * RunAllMigrations applies all system and app migrations + * (aka. from both [core.SystemMigrations] and [CoreAppMigrations]). + */ + runAllMigrations(): void + } + interface BaseApp { + onBootstrap(): (hook.Hook) + } + interface BaseApp { + onServe(): (hook.Hook) + } + interface BaseApp { + onTerminate(): (hook.Hook) + } + interface BaseApp { + onBackupCreate(): (hook.Hook) + } + interface BaseApp { + onBackupRestore(): (hook.Hook) + } + interface BaseApp { + onModelCreate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelCreateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterCreateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelUpdate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelUpdateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterUpdateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelValidate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelDelete(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelDeleteExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onModelAfterDeleteError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordEnrich(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordValidate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordCreate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordCreateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterCreateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordUpdate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordUpdateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterUpdateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordDelete(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordDeleteExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAfterDeleteError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionValidate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionCreate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionCreateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterCreateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterCreateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionUpdate(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionUpdateExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterUpdateSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterUpdateError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionDelete(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionDeleteExecute(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterDeleteSuccess(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionAfterDeleteError(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onMailerSend(): (hook.Hook) + } + interface BaseApp { + onMailerRecordPasswordResetSend(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onMailerRecordVerificationSend(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onMailerRecordEmailChangeSend(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onMailerRecordOTPSend(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onMailerRecordAuthAlertSend(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRealtimeConnectRequest(): (hook.Hook) + } + interface BaseApp { + onRealtimeMessageSend(): (hook.Hook) + } + interface BaseApp { + onRealtimeSubscribeRequest(): (hook.Hook) + } + interface BaseApp { + onSettingsListRequest(): (hook.Hook) + } + interface BaseApp { + onSettingsUpdateRequest(): (hook.Hook) + } + interface BaseApp { + onSettingsReload(): (hook.Hook) + } + interface BaseApp { + onFileDownloadRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onFileTokenRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAuthRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAuthWithPasswordRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAuthWithOAuth2Request(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAuthRefreshRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordRequestPasswordResetRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordConfirmPasswordResetRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordRequestVerificationRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordConfirmVerificationRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordRequestEmailChangeRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordConfirmEmailChangeRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordRequestOTPRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordAuthWithOTPRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordsListRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordViewRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordCreateRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordUpdateRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onRecordDeleteRequest(...tags: string[]): (hook.TaggedHook) + } + interface BaseApp { + onCollectionsListRequest(): (hook.Hook) + } + interface BaseApp { + onCollectionViewRequest(): (hook.Hook) + } + interface BaseApp { + onCollectionCreateRequest(): (hook.Hook) + } + interface BaseApp { + onCollectionUpdateRequest(): (hook.Hook) + } + interface BaseApp { + onCollectionDeleteRequest(): (hook.Hook) + } + interface BaseApp { + onCollectionsImportRequest(): (hook.Hook) + } + interface BaseApp { + onBatchRequest(): (hook.Hook) + } + interface BaseApp { + /** + * CreateBackup creates a new backup of the current app pb_data directory. + * + * If name is empty, it will be autogenerated. + * If backup with the same name exists, the new backup file will replace it. + * + * The backup is executed within a transaction, meaning that new writes + * will be temporary "blocked" until the backup file is generated. + * + * To safely perform the backup, it is recommended to have free disk space + * for at least 2x the size of the pb_data directory. + * + * By default backups are stored in pb_data/backups + * (the backups directory itself is excluded from the generated backup). + * + * When using S3 storage for the uploaded collection files, you have to + * take care manually to backup those since they are not part of the pb_data. + * + * Backups can be stored on S3 if it is configured in app.Settings().Backups. + */ + createBackup(ctx: context.Context, name: string): void + } + interface BaseApp { + /** + * RestoreBackup restores the backup with the specified name and restarts + * the current running application process. + * + * NB! This feature is experimental and currently is expected to work only on UNIX based systems. + * + * To safely perform the restore it is recommended to have free disk space + * for at least 2x the size of the restored pb_data backup. + * + * The performed steps are: + * + * 1. Download the backup with the specified name in a temp location + * ``` + * (this is in case of S3; otherwise it creates a temp copy of the zip) + * ``` + * + * 2. Extract the backup in a temp directory inside the app "pb_data" + * ``` + * (eg. "pb_data/.pb_temp_to_delete/pb_restore"). + * ``` + * + * 3. Move the current app "pb_data" content (excluding the local backups and the special temp dir) + * ``` + * under another temp sub dir that will be deleted on the next app start up + * (eg. "pb_data/.pb_temp_to_delete/old_pb_data"). + * This is because on some environments it may not be allowed + * to delete the currently open "pb_data" files. + * ``` + * + * 4. Move the extracted dir content to the app "pb_data". + * + * 5. Restart the app (on successful app bootstap it will also remove the old pb_data). + * + * If a failure occure during the restore process the dir changes are reverted. + * If for whatever reason the revert is not possible, it panics. + * + * Note that if your pb_data has custom network mounts as subdirectories, then + * it is possible the restore to fail during the `os.Rename` operations + * (see https://github.com/pocketbase/pocketbase/issues/4647). + */ + restoreBackup(ctx: context.Context, name: string): void + } + interface BaseApp { + /** + * ImportCollectionsByMarshaledJSON is the same as [ImportCollections] + * but accept marshaled json array as import data (usually used for the autogenerated snapshots). + */ + importCollectionsByMarshaledJSON(rawSliceOfMaps: string|Array, deleteMissing: boolean): void + } + interface BaseApp { + /** + * ImportCollections imports the provided collections data in a single transaction. + * + * For existing matching collections, the imported data is unmarshaled on top of the existing model. + * + * NB! If deleteMissing is true, ALL NON-SYSTEM COLLECTIONS AND SCHEMA FIELDS, + * that are not present in the imported configuration, WILL BE DELETED + * (this includes their related records data). + */ + importCollections(toImport: Array<_TygojaDict>, deleteMissing: boolean): void + } + /** + * @todo experiment eventually replacing the rules *string with a struct? + */ + type _sGvYwdg = BaseModel + interface baseCollection extends _sGvYwdg { + listRule?: string + viewRule?: string + createRule?: string + updateRule?: string + deleteRule?: string + /** + * RawOptions represents the raw serialized collection option loaded from the DB. + * NB! This field shouldn't be modified manually. It is automatically updated + * with the collection type specific option before save. + */ + rawOptions: types.JSONRaw + name: string + type: string + fields: FieldsList + indexes: types.JSONArray + created: types.DateTime + updated: types.DateTime + /** + * System prevents the collection rename, deletion and rules change. + * It is used primarily for internal purposes for collections like "_superusers", "_externalAuths", etc. + */ + system: boolean + } + /** + * Collection defines the table, fields and various options related to a set of records. + */ + type _sARVXJw = baseCollection&collectionAuthOptions&collectionViewOptions + interface Collection extends _sARVXJw { + } + interface newCollection { + /** + * NewCollection initializes and returns a new Collection model with the specified type and name. + * + * It also loads the minimal default configuration for the collection + * (eg. system fields, indexes, type specific options, etc.). + */ + (typ: string, name: string, ...optId: string[]): (Collection) + } + interface newBaseCollection { + /** + * NewBaseCollection initializes and returns a new "base" Collection model. + * + * It also loads the minimal default configuration for the collection + * (eg. system fields, indexes, type specific options, etc.). + */ + (name: string, ...optId: string[]): (Collection) + } + interface newViewCollection { + /** + * NewViewCollection initializes and returns a new "view" Collection model. + * + * It also loads the minimal default configuration for the collection + * (eg. system fields, indexes, type specific options, etc.). + */ + (name: string, ...optId: string[]): (Collection) + } + interface newAuthCollection { + /** + * NewAuthCollection initializes and returns a new "auth" Collection model. + * + * It also loads the minimal default configuration for the collection + * (eg. system fields, indexes, type specific options, etc.). + */ + (name: string, ...optId: string[]): (Collection) + } + interface Collection { + /** + * TableName returns the Collection model SQL table name. + */ + tableName(): string + } + interface Collection { + /** + * BaseFilesPath returns the storage dir path used by the collection. + */ + baseFilesPath(): string + } + interface Collection { + /** + * IsBase checks if the current collection has "base" type. + */ + isBase(): boolean + } + interface Collection { + /** + * IsAuth checks if the current collection has "auth" type. + */ + isAuth(): boolean + } + interface Collection { + /** + * IsView checks if the current collection has "view" type. + */ + isView(): boolean + } + interface Collection { + /** + * IntegrityChecks toggles the current collection integrity checks (ex. checking references on delete). + */ + integrityChecks(enable: boolean): void + } + interface Collection { + /** + * PostScan implements the [dbx.PostScanner] interface to auto unmarshal + * the raw serialized options into the concrete type specific fields. + */ + postScan(): void + } + interface Collection { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + * + * For new/"blank" Collection models it replaces the model with a factory + * instance and then unmarshal the provided data one on top of it. + */ + unmarshalJSON(b: string|Array): void + } + interface Collection { + /** + * MarshalJSON implements the [json.Marshaler] interface. + * + * Note that non-type related fields are ignored from the serialization + * (ex. for "view" colections the "auth" fields are skipped). + */ + marshalJSON(): string|Array + } + interface Collection { + /** + * String returns a string representation of the current collection. + */ + string(): string + } + interface Collection { + /** + * DBExport prepares and exports the current collection data for db persistence. + */ + dbExport(app: App): _TygojaDict + } + interface Collection { + /** + * GetIndex returns s single Collection index expression by its name. + */ + getIndex(name: string): string + } + interface Collection { + /** + * AddIndex adds a new index into the current collection. + * + * If the collection has an existing index matching the new name it will be replaced with the new one. + */ + addIndex(name: string, unique: boolean, columnsExpr: string, optWhereExpr: string): void + } + interface Collection { + /** + * RemoveIndex removes a single index with the specified name from the current collection. + */ + removeIndex(name: string): void + } + /** + * collectionAuthOptions defines the options for the "auth" type collection. + */ + interface collectionAuthOptions { + /** + * AuthRule could be used to specify additional record constraints + * applied after record authentication and right before returning the + * auth token response to the client. + * + * For example, to allow only verified users you could set it to + * "verified = true". + * + * Set it to empty string to allow any Auth collection record to authenticate. + * + * Set it to nil to disallow authentication altogether for the collection + * (that includes password, OAuth2, etc.). + */ + authRule?: string + /** + * ManageRule gives admin-like permissions to allow fully managing + * the auth record(s), eg. changing the password without requiring + * to enter the old one, directly updating the verified state and email, etc. + * + * This rule is executed in addition to the Create and Update API rules. + */ + manageRule?: string + /** + * AuthAlert defines options related to the auth alerts on new device login. + */ + authAlert: AuthAlertConfig + /** + * OAuth2 specifies whether OAuth2 auth is enabled for the collection + * and which OAuth2 providers are allowed. + */ + oauth2: OAuth2Config + /** + * PasswordAuth defines options related to the collection password authentication. + */ + passwordAuth: PasswordAuthConfig + /** + * MFA defines options related to the Multi-factor authentication (MFA). + */ + mfa: MFAConfig + /** + * OTP defines options related to the One-time password authentication (OTP). + */ + otp: OTPConfig + /** + * Various token configurations + * --- + */ + authToken: TokenConfig + passwordResetToken: TokenConfig + emailChangeToken: TokenConfig + verificationToken: TokenConfig + fileToken: TokenConfig + /** + * Default email templates + * --- + */ + verificationTemplate: EmailTemplate + resetPasswordTemplate: EmailTemplate + confirmEmailChangeTemplate: EmailTemplate + } + interface EmailTemplate { + subject: string + body: string + } + interface EmailTemplate { + /** + * Validate makes EmailTemplate validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface EmailTemplate { + /** + * Resolve replaces the placeholder parameters in the current email + * template and returns its components as ready-to-use strings. + */ + resolve(placeholders: _TygojaDict): [string, string] + } + interface AuthAlertConfig { + enabled: boolean + emailTemplate: EmailTemplate + } + interface AuthAlertConfig { + /** + * Validate makes AuthAlertConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface TokenConfig { + secret: string + /** + * Duration specifies how long an issued token to be valid (in seconds) + */ + duration: number + } + interface TokenConfig { + /** + * Validate makes TokenConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface TokenConfig { + /** + * DurationTime returns the current Duration as [time.Duration]. + */ + durationTime(): time.Duration + } + interface OTPConfig { + enabled: boolean + /** + * Duration specifies how long the OTP to be valid (in seconds) + */ + duration: number + /** + * Length specifies the auto generated password length. + */ + length: number + /** + * EmailTemplate is the default OTP email template that will be send to the auth record. + * + * In addition to the system placeholders you can also make use of + * [core.EmailPlaceholderOTPId] and [core.EmailPlaceholderOTP]. + */ + emailTemplate: EmailTemplate + } + interface OTPConfig { + /** + * Validate makes OTPConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface OTPConfig { + /** + * DurationTime returns the current Duration as [time.Duration]. + */ + durationTime(): time.Duration + } + interface MFAConfig { + enabled: boolean + /** + * Duration specifies how long an issued MFA to be valid (in seconds) + */ + duration: number + /** + * Rule is an optional field to restrict MFA only for the records that satisfy the rule. + * + * Leave it empty to enable MFA for everyone. + */ + rule: string + } + interface MFAConfig { + /** + * Validate makes MFAConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface MFAConfig { + /** + * DurationTime returns the current Duration as [time.Duration]. + */ + durationTime(): time.Duration + } + interface PasswordAuthConfig { + enabled: boolean + /** + * IdentityFields is a list of field names that could be used as + * identity during password authentication. + * + * Usually only fields that has single column UNIQUE index are accepted as values. + */ + identityFields: Array + } + interface PasswordAuthConfig { + /** + * Validate makes PasswordAuthConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface OAuth2KnownFields { + id: string + name: string + username: string + avatarURL: string + } + interface OAuth2Config { + providers: Array + mappedFields: OAuth2KnownFields + enabled: boolean + } + interface OAuth2Config { + /** + * GetProviderConfig returns the first OAuth2ProviderConfig that matches the specified name. + * + * Returns false and zero config if no such provider is available in c.Providers. + */ + getProviderConfig(name: string): [OAuth2ProviderConfig, boolean] + } + interface OAuth2Config { + /** + * Validate makes OAuth2Config validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface OAuth2ProviderConfig { + /** + * PKCE overwrites the default provider PKCE config option. + * + * This usually shouldn't be needed but some OAuth2 vendors, like the LinkedIn OIDC, + * may require manual adjustment due to returning error if extra parameters are added to the request + * (https://github.com/pocketbase/pocketbase/discussions/3799#discussioncomment-7640312) + */ + pkce?: boolean + name: string + clientId: string + clientSecret: string + authURL: string + tokenURL: string + userInfoURL: string + displayName: string + extra: _TygojaDict + } + interface OAuth2ProviderConfig { + /** + * Validate makes OAuth2ProviderConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface OAuth2ProviderConfig { + /** + * InitProvider returns a new auth.Provider instance loaded with the current OAuth2ProviderConfig options. + */ + initProvider(): auth.Provider + } + /** + * collectionBaseOptions defines the options for the "base" type collection. + */ + interface collectionBaseOptions { + } + /** + * collectionViewOptions defines the options for the "view" type collection. + */ + interface collectionViewOptions { + viewQuery: string + } + interface BaseApp { + /** + * CollectionQuery returns a new Collection select query. + */ + collectionQuery(): (dbx.SelectQuery) + } + interface BaseApp { + /** + * FindCollections finds all collections by the given type(s). + * + * If collectionTypes is not set, it returns all collections. + * + * Example: + * + * ``` + * app.FindAllCollections() // all collections + * app.FindAllCollections("auth", "view") // only auth and view collections + * ``` + */ + findAllCollections(...collectionTypes: string[]): Array<(Collection | undefined)> + } + interface BaseApp { + /** + * ReloadCachedCollections fetches all collections and caches them into the app store. + */ + reloadCachedCollections(): void + } + interface BaseApp { + /** + * FindCollectionByNameOrId finds a single collection by its name (case insensitive) or id. + */ + findCollectionByNameOrId(nameOrId: string): (Collection) + } + interface BaseApp { + /** + * FindCachedCollectionByNameOrId is similar to [BaseApp.FindCollectionByNameOrId] + * but retrieves the Collection from the app cache instead of making a db call. + * + * NB! This method is suitable for read-only Collection operations. + * + * Returns [sql.ErrNoRows] if no Collection is found for consistency + * with the [BaseApp.FindCollectionByNameOrId] method. + * + * If you plan making changes to the returned Collection model, + * use [BaseApp.FindCollectionByNameOrId] instead. + * + * Caveats: + * + * ``` + * - The returned Collection should be used only for read-only operations. + * Avoid directly modifying the returned cached Collection as it will affect + * the global cached value even if you don't persist the changes in the database! + * - If you are updating a Collection in a transaction and then call this method before commit, + * it'll return the cached Collection state and not the one from the uncommitted transaction. + * - The cache is automatically updated on collections db change (create/update/delete). + * To manually reload the cache you can call [BaseApp.ReloadCachedCollections]. + * ``` + */ + findCachedCollectionByNameOrId(nameOrId: string): (Collection) + } + interface BaseApp { + /** + * FindCollectionReferences returns information for all relation fields + * referencing the provided collection. + * + * If the provided collection has reference to itself then it will be + * also included in the result. To exclude it, pass the collection id + * as the excludeIds argument. + */ + findCollectionReferences(collection: Collection, ...excludeIds: string[]): _TygojaDict + } + interface BaseApp { + /** + * FindCachedCollectionReferences is similar to [BaseApp.FindCollectionReferences] + * but retrieves the Collection from the app cache instead of making a db call. + * + * NB! This method is suitable for read-only Collection operations. + * + * If you plan making changes to the returned Collection model, + * use [BaseApp.FindCollectionReferences] instead. + * + * Caveats: + * + * ``` + * - The returned Collection should be used only for read-only operations. + * Avoid directly modifying the returned cached Collection as it will affect + * the global cached value even if you don't persist the changes in the database! + * - If you are updating a Collection in a transaction and then call this method before commit, + * it'll return the cached Collection state and not the one from the uncommitted transaction. + * - The cache is automatically updated on collections db change (create/update/delete). + * To manually reload the cache you can call [BaseApp.ReloadCachedCollections]. + * ``` + */ + findCachedCollectionReferences(collection: Collection, ...excludeIds: string[]): _TygojaDict + } + interface BaseApp { + /** + * IsCollectionNameUnique checks that there is no existing collection + * with the provided name (case insensitive!). + * + * Note: case insensitive check because the name is used also as + * table name for the records. + */ + isCollectionNameUnique(name: string, ...excludeIds: string[]): boolean + } + interface BaseApp { + /** + * TruncateCollection deletes all records associated with the provided collection. + * + * The truncate operation is executed in a single transaction, + * aka. either everything is deleted or none. + * + * Note that this method will also trigger the records related + * cascade and file delete actions. + */ + truncateCollection(collection: Collection): void + } + interface BaseApp { + /** + * SyncRecordTableSchema compares the two provided collections + * and applies the necessary related record table changes. + * + * If oldCollection is null, then only newCollection is used to create the record table. + * + * This method is automatically invoked as part of a collection create/update/delete operation. + */ + syncRecordTableSchema(newCollection: Collection, oldCollection: Collection): void + } + interface collectionValidator { + } + interface optionsValidator { + [key:string]: any; + } + /** + * DBExporter defines an interface for custom DB data export. + * Usually used as part of [App.Save]. + */ + interface DBExporter { + [key:string]: any; + /** + * DBExport returns a key-value map with the data to be used when saving the struct in the database. + */ + dbExport(app: App): _TygojaDict + } + /** + * PreValidator defines an optional model interface for registering a + * function that will run BEFORE firing the validation hooks (see [App.ValidateWithContext]). + */ + interface PreValidator { + [key:string]: any; + /** + * PreValidate defines a function that runs BEFORE the validation hooks. + */ + preValidate(ctx: context.Context, app: App): void + } + /** + * PostValidator defines an optional model interface for registering a + * function that will run AFTER executing the validation hooks (see [App.ValidateWithContext]). + */ + interface PostValidator { + [key:string]: any; + /** + * PostValidate defines a function that runs AFTER the successful + * execution of the validation hooks. + */ + postValidate(ctx: context.Context, app: App): void + } + interface generateDefaultRandomId { + /** + * GenerateDefaultRandomId generates a default random id string + * (note: the generated random string is not intended for security purposes). + */ + (): string + } + interface BaseApp { + /** + * ModelQuery creates a new preconfigured select data.db query with preset + * SELECT, FROM and other common fields based on the provided model. + */ + modelQuery(m: Model): (dbx.SelectQuery) + } + interface BaseApp { + /** + * AuxModelQuery creates a new preconfigured select auxiliary.db query with preset + * SELECT, FROM and other common fields based on the provided model. + */ + auxModelQuery(m: Model): (dbx.SelectQuery) + } + interface BaseApp { + /** + * Delete deletes the specified model from the regular app database. + */ + delete(model: Model): void + } + interface BaseApp { + /** + * Delete deletes the specified model from the regular app database + * (the context could be used to limit the query execution). + */ + deleteWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * AuxDelete deletes the specified model from the auxiliary database. + */ + auxDelete(model: Model): void + } + interface BaseApp { + /** + * AuxDeleteWithContext deletes the specified model from the auxiliary database + * (the context could be used to limit the query execution). + */ + auxDeleteWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * Save validates and saves the specified model into the regular app database. + * + * If you don't want to run validations, use [App.SaveNoValidate()]. + */ + save(model: Model): void + } + interface BaseApp { + /** + * SaveWithContext is the same as [App.Save()] but allows specifying a context to limit the db execution. + * + * If you don't want to run validations, use [App.SaveNoValidateWithContext()]. + */ + saveWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * SaveNoValidate saves the specified model into the regular app database without performing validations. + * + * If you want to also run validations before persisting, use [App.Save()]. + */ + saveNoValidate(model: Model): void + } + interface BaseApp { + /** + * SaveNoValidateWithContext is the same as [App.SaveNoValidate()] + * but allows specifying a context to limit the db execution. + * + * If you want to also run validations before persisting, use [App.SaveWithContext()]. + */ + saveNoValidateWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * AuxSave validates and saves the specified model into the auxiliary app database. + * + * If you don't want to run validations, use [App.AuxSaveNoValidate()]. + */ + auxSave(model: Model): void + } + interface BaseApp { + /** + * AuxSaveWithContext is the same as [App.AuxSave()] but allows specifying a context to limit the db execution. + * + * If you don't want to run validations, use [App.AuxSaveNoValidateWithContext()]. + */ + auxSaveWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * AuxSaveNoValidate saves the specified model into the auxiliary app database without performing validations. + * + * If you want to also run validations before persisting, use [App.AuxSave()]. + */ + auxSaveNoValidate(model: Model): void + } + interface BaseApp { + /** + * AuxSaveNoValidateWithContext is the same as [App.AuxSaveNoValidate()] + * but allows specifying a context to limit the db execution. + * + * If you want to also run validations before persisting, use [App.AuxSaveWithContext()]. + */ + auxSaveNoValidateWithContext(ctx: context.Context, model: Model): void + } + interface BaseApp { + /** + * Validate triggers the OnModelValidate hook for the specified model. + */ + validate(model: Model): void + } + interface BaseApp { + /** + * ValidateWithContext is the same as Validate but allows specifying the ModelEvent context. + */ + validateWithContext(ctx: context.Context, model: Model): void + } + /** + * note: expects both builder to use the same driver + */ + interface dualDBBuilder { + } + interface dualDBBuilder { + /** + * Select implements the [dbx.Builder.Select] interface method. + */ + select(...cols: string[]): (dbx.SelectQuery) + } + interface dualDBBuilder { + /** + * Model implements the [dbx.Builder.Model] interface method. + */ + model(data: { + }): (dbx.ModelQuery) + } + interface dualDBBuilder { + /** + * GeneratePlaceholder implements the [dbx.Builder.GeneratePlaceholder] interface method. + */ + generatePlaceholder(i: number): string + } + interface dualDBBuilder { + /** + * Quote implements the [dbx.Builder.Quote] interface method. + */ + quote(str: string): string + } + interface dualDBBuilder { + /** + * QuoteSimpleTableName implements the [dbx.Builder.QuoteSimpleTableName] interface method. + */ + quoteSimpleTableName(table: string): string + } + interface dualDBBuilder { + /** + * QuoteSimpleColumnName implements the [dbx.Builder.QuoteSimpleColumnName] interface method. + */ + quoteSimpleColumnName(col: string): string + } + interface dualDBBuilder { + /** + * QueryBuilder implements the [dbx.Builder.QueryBuilder] interface method. + */ + queryBuilder(): dbx.QueryBuilder + } + interface dualDBBuilder { + /** + * Insert implements the [dbx.Builder.Insert] interface method. + */ + insert(table: string, cols: dbx.Params): (dbx.Query) + } + interface dualDBBuilder { + /** + * Upsert implements the [dbx.Builder.Upsert] interface method. + */ + upsert(table: string, cols: dbx.Params, ...constraints: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * Update implements the [dbx.Builder.Update] interface method. + */ + update(table: string, cols: dbx.Params, where: dbx.Expression): (dbx.Query) + } + interface dualDBBuilder { + /** + * Delete implements the [dbx.Builder.Delete] interface method. + */ + delete(table: string, where: dbx.Expression): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateTable implements the [dbx.Builder.CreateTable] interface method. + */ + createTable(table: string, cols: _TygojaDict, ...options: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * RenameTable implements the [dbx.Builder.RenameTable] interface method. + */ + renameTable(oldName: string, newName: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropTable implements the [dbx.Builder.DropTable] interface method. + */ + dropTable(table: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * TruncateTable implements the [dbx.Builder.TruncateTable] interface method. + */ + truncateTable(table: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddColumn implements the [dbx.Builder.AddColumn] interface method. + */ + addColumn(table: string, col: string, typ: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropColumn implements the [dbx.Builder.DropColumn] interface method. + */ + dropColumn(table: string, col: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * RenameColumn implements the [dbx.Builder.RenameColumn] interface method. + */ + renameColumn(table: string, oldName: string, newName: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AlterColumn implements the [dbx.Builder.AlterColumn] interface method. + */ + alterColumn(table: string, col: string, typ: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddPrimaryKey implements the [dbx.Builder.AddPrimaryKey] interface method. + */ + addPrimaryKey(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropPrimaryKey implements the [dbx.Builder.DropPrimaryKey] interface method. + */ + dropPrimaryKey(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * AddForeignKey implements the [dbx.Builder.AddForeignKey] interface method. + */ + addForeignKey(table: string, name: string, cols: Array, refCols: Array, refTable: string, ...options: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropForeignKey implements the [dbx.Builder.DropForeignKey] interface method. + */ + dropForeignKey(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateIndex implements the [dbx.Builder.CreateIndex] interface method. + */ + createIndex(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * CreateUniqueIndex implements the [dbx.Builder.CreateUniqueIndex] interface method. + */ + createUniqueIndex(table: string, name: string, ...cols: string[]): (dbx.Query) + } + interface dualDBBuilder { + /** + * DropIndex implements the [dbx.Builder.DropIndex] interface method. + */ + dropIndex(table: string, name: string): (dbx.Query) + } + interface dualDBBuilder { + /** + * NewQuery implements the [dbx.Builder.NewQuery] interface method by + * routing the SELECT queries to the concurrent builder instance. + */ + newQuery(str: string): (dbx.Query) + } + interface defaultDBConnect { + (dbPath: string): (dbx.DB) + } + /** + * Model defines an interface with common methods that all db models should have. + * + * Note: for simplicity composite pk are not supported. + */ + interface Model { + [key:string]: any; + tableName(): string + pk(): any + lastSavedPK(): any + isNew(): boolean + markAsNew(): void + markAsNotNew(): void + } + /** + * BaseModel defines a base struct that is intended to be embedded into other custom models. + */ + interface BaseModel { + /** + * Id is the primary key of the model. + * It is usually autogenerated by the parent model implementation. + */ + id: string + } + interface BaseModel { + /** + * LastSavedPK returns the last saved primary key of the model. + * + * Its value is updated to the latest PK value after MarkAsNotNew() or PostScan() calls. + */ + lastSavedPK(): any + } + interface BaseModel { + pk(): any + } + interface BaseModel { + /** + * IsNew indicates what type of db query (insert or update) + * should be used with the model instance. + */ + isNew(): boolean + } + interface BaseModel { + /** + * MarkAsNew clears the pk field and marks the current model as "new" + * (aka. forces m.IsNew() to be true). + */ + markAsNew(): void + } + interface BaseModel { + /** + * MarkAsNew set the pk field to the Id value and marks the current model + * as NOT "new" (aka. forces m.IsNew() to be false). + */ + markAsNotNew(): void + } + interface BaseModel { + /** + * PostScan implements the [dbx.PostScanner] interface. + * + * It is usually executed right after the model is populated with the db row values. + */ + postScan(): void + } + interface BaseApp { + /** + * TableColumns returns all column names of a single table by its name. + */ + tableColumns(tableName: string): Array + } + interface TableInfoRow { + /** + * the `db:"pk"` tag has special semantic so we cannot rename + * the original field without specifying a custom mapper + */ + pk: number + index: number + name: string + type: string + notNull: boolean + defaultValue: sql.NullString + } + interface BaseApp { + /** + * TableInfo returns the "table_info" pragma result for the specified table. + */ + tableInfo(tableName: string): Array<(TableInfoRow | undefined)> + } + interface BaseApp { + /** + * TableIndexes returns a name grouped map with all non empty index of the specified table. + * + * Note: This method doesn't return an error on nonexisting table. + */ + tableIndexes(tableName: string): _TygojaDict + } + interface BaseApp { + /** + * DeleteTable drops the specified table. + * + * This method is a no-op if a table with the provided name doesn't exist. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "tableName" argument must come only from trusted input! + */ + deleteTable(tableName: string): void + } + interface BaseApp { + /** + * HasTable checks if a table (or view) with the provided name exists (case insensitive). + * in the data.db. + */ + hasTable(tableName: string): boolean + } + interface BaseApp { + /** + * AuxHasTable checks if a table (or view) with the provided name exists (case insensitive) + * in the auixiliary.db. + */ + auxHasTable(tableName: string): boolean + } + interface BaseApp { + /** + * Vacuum executes VACUUM on the data.db in order to reclaim unused data db disk space. + */ + vacuum(): void + } + interface BaseApp { + /** + * AuxVacuum executes VACUUM on the auxiliary.db in order to reclaim unused auxiliary db disk space. + */ + auxVacuum(): void + } + interface BaseApp { + /** + * RunInTransaction wraps fn into a transaction for the regular app database. + * + * It is safe to nest RunInTransaction calls as long as you use the callback's txApp. + */ + runInTransaction(fn: (txApp: App) => void): void + } + interface BaseApp { + /** + * AuxRunInTransaction wraps fn into a transaction for the auxiliary app database. + * + * It is safe to nest RunInTransaction calls as long as you use the callback's txApp. + */ + auxRunInTransaction(fn: (txApp: App) => void): void + } + /** + * TxAppInfo represents an active transaction context associated to an existing app instance. + */ + interface TxAppInfo { + } + interface TxAppInfo { + /** + * OnComplete registers the provided callback that will be invoked + * once the related transaction ends (either completes successfully or rollbacked with an error). + * + * The callback receives the transaction error (if any) as its argument. + * Any additional errors returned by the OnComplete callbacks will be + * joined together with txErr when returning the final transaction result. + */ + onComplete(fn: (txErr: Error) => void): void + } + /** + * RequestEvent defines the PocketBase router handler event. + */ + type _sAUHJSb = router.Event + interface RequestEvent extends _sAUHJSb { + app: App + auth?: Record + } + interface RequestEvent { + /** + * RealIP returns the "real" IP address from the configured trusted proxy headers. + * + * If Settings.TrustedProxy is not configured or the found IP is empty, + * it fallbacks to e.RemoteIP(). + * + * NB! + * Be careful when used in a security critical context as it relies on + * the trusted proxy to be properly configured and your app to be accessible only through it. + * If you are not sure, use e.RemoteIP(). + */ + realIP(): string + } + interface RequestEvent { + /** + * HasSuperuserAuth checks whether the current RequestEvent has superuser authentication loaded. + */ + hasSuperuserAuth(): boolean + } + interface RequestEvent { + /** + * RequestInfo parses the current request into RequestInfo instance. + * + * Note that the returned result is cached to avoid copying the request data multiple times + * but the auth state and other common store items are always refreshed in case they were changed by another handler. + */ + requestInfo(): (RequestInfo) + } + /** + * RequestInfo defines a HTTP request data struct, usually used + * as part of the `@request.*` filter resolver. + * + * The Query and Headers fields contains only the first value for each found entry. + */ + interface RequestInfo { + query: _TygojaDict + headers: _TygojaDict + body: _TygojaDict + auth?: Record + method: string + context: string + } + interface RequestInfo { + /** + * HasSuperuserAuth checks whether the current RequestInfo instance + * has superuser authentication loaded. + */ + hasSuperuserAuth(): boolean + } + interface RequestInfo { + /** + * Clone creates a new shallow copy of the current RequestInfo and its Auth record (if any). + */ + clone(): (RequestInfo) + } + type _sRxeJcl = hook.Event&RequestEvent + interface BatchRequestEvent extends _sRxeJcl { + batch: Array<(InternalRequest | undefined)> + } + interface InternalRequest { + /** + * note: for uploading files the value must be either *filesystem.File or []*filesystem.File + */ + body: _TygojaDict + headers: _TygojaDict + method: string + url: string + } + interface InternalRequest { + validate(): void + } + interface HookTagger { + [key:string]: any; + hookTags(): Array + } + interface baseModelEventData { + model: Model + } + interface baseModelEventData { + tags(): Array + } + interface baseRecordEventData { + record?: Record + } + interface baseRecordEventData { + tags(): Array + } + interface baseCollectionEventData { + collection?: Collection + } + interface baseCollectionEventData { + tags(): Array + } + type _stIkUqY = hook.Event + interface BootstrapEvent extends _stIkUqY { + app: App + } + type _sXpnKrF = hook.Event + interface TerminateEvent extends _sXpnKrF { + app: App + isRestart: boolean + } + type _sbqhhus = hook.Event + interface BackupEvent extends _sbqhhus { + app: App + context: context.Context + name: string // the name of the backup to create/restore. + exclude: Array // list of dir entries to exclude from the backup create/restore. + } + type _sKqvUjA = hook.Event + interface ServeEvent extends _sKqvUjA { + app: App + router?: router.Router + server?: http.Server + certManager?: any + /** + * Listener allow specifying a custom network listener. + * + * Leave it nil to use the default net.Listen("tcp", e.Server.Addr). + */ + listener: net.Listener + /** + * InstallerFunc is the "installer" function that is called after + * successful server tcp bind but only if there is no explicit + * superuser record created yet. + * + * It runs in a separate goroutine and its default value is [apis.DefaultInstallerFunc]. + * + * It receives a system superuser record as argument that you can use to generate + * a short-lived auth token (e.g. systemSuperuser.NewStaticAuthToken(30 * time.Minute)) + * and concatenate it as query param for your installer page + * (if you are using the client-side SDKs, you can then load the + * token with pb.authStore.save(token) and perform any Web API request + * e.g. creating a new superuser). + * + * Set it to nil if you want to skip the installer. + */ + installerFunc: (app: App, systemSuperuser: Record, baseURL: string) => void + } + type _sjhiLke = hook.Event&RequestEvent + interface SettingsListRequestEvent extends _sjhiLke { + settings?: Settings + } + type _sTFxZDn = hook.Event&RequestEvent + interface SettingsUpdateRequestEvent extends _sTFxZDn { + oldSettings?: Settings + newSettings?: Settings + } + type _sCjowmw = hook.Event + interface SettingsReloadEvent extends _sCjowmw { + app: App + } + type _sjxJayB = hook.Event + interface MailerEvent extends _sjxJayB { + app: App + mailer: mailer.Mailer + message?: mailer.Message + } + type _sewrHpL = MailerEvent&baseRecordEventData + interface MailerRecordEvent extends _sewrHpL { + meta: _TygojaDict + } + type _sXXWQHn = hook.Event&baseModelEventData + interface ModelEvent extends _sXXWQHn { + app: App + context: context.Context + /** + * Could be any of the ModelEventType* constants, like: + * - create + * - update + * - delete + * - validate + */ + type: string + } + type _sbRjKRu = ModelEvent + interface ModelErrorEvent extends _sbRjKRu { + error: Error + } + type _sfhiqsz = hook.Event&baseRecordEventData + interface RecordEvent extends _sfhiqsz { + app: App + context: context.Context + /** + * Could be any of the ModelEventType* constants, like: + * - create + * - update + * - delete + * - validate + */ + type: string + } + type _sXlwrts = RecordEvent + interface RecordErrorEvent extends _sXlwrts { + error: Error + } + type _sWuBJQW = hook.Event&baseCollectionEventData + interface CollectionEvent extends _sWuBJQW { + app: App + context: context.Context + /** + * Could be any of the ModelEventType* constants, like: + * - create + * - update + * - delete + * - validate + */ + type: string + } + type _srHYWqg = CollectionEvent + interface CollectionErrorEvent extends _srHYWqg { + error: Error + } + type _sovWxED = hook.Event&RequestEvent&baseRecordEventData + interface FileTokenRequestEvent extends _sovWxED { + token: string + } + type _sXopmWm = hook.Event&RequestEvent&baseCollectionEventData + interface FileDownloadRequestEvent extends _sXopmWm { + record?: Record + fileField?: FileField + servedPath: string + servedName: string + } + type _sIOhDGI = hook.Event&RequestEvent + interface CollectionsListRequestEvent extends _sIOhDGI { + collections: Array<(Collection | undefined)> + result?: search.Result + } + type _sXpNNuj = hook.Event&RequestEvent + interface CollectionsImportRequestEvent extends _sXpNNuj { + collectionsData: Array<_TygojaDict> + deleteMissing: boolean + } + type _sJNKbAM = hook.Event&RequestEvent&baseCollectionEventData + interface CollectionRequestEvent extends _sJNKbAM { + } + type _sfagCFf = hook.Event&RequestEvent + interface RealtimeConnectRequestEvent extends _sfagCFf { + client: subscriptions.Client + /** + * note: modifying it after the connect has no effect + */ + idleTimeout: time.Duration + } + type _sqcVbkS = hook.Event&RequestEvent + interface RealtimeMessageEvent extends _sqcVbkS { + client: subscriptions.Client + message?: subscriptions.Message + } + type _saNBgje = hook.Event&RequestEvent + interface RealtimeSubscribeRequestEvent extends _saNBgje { + client: subscriptions.Client + subscriptions: Array + } + type _sRZDGZw = hook.Event&RequestEvent&baseCollectionEventData + interface RecordsListRequestEvent extends _sRZDGZw { + /** + * @todo consider removing and maybe add as generic to the search.Result? + */ + records: Array<(Record | undefined)> + result?: search.Result + } + type _suTtljJ = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEvent extends _suTtljJ { + record?: Record + } + type _slvKadO = hook.Event&baseRecordEventData + interface RecordEnrichEvent extends _slvKadO { + app: App + requestInfo?: RequestInfo + } + type _saIEXsP = hook.Event&RequestEvent&baseCollectionEventData + interface RecordCreateOTPRequestEvent extends _saIEXsP { + record?: Record + password: string + } + type _smWAnpQ = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOTPRequestEvent extends _smWAnpQ { + record?: Record + otp?: OTP + } + type _smKrRVl = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRequestEvent extends _smKrRVl { + record?: Record + token: string + meta: any + authMethod: string + } + type _sPKSFBR = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithPasswordRequestEvent extends _sPKSFBR { + record?: Record + identity: string + identityField: string + password: string + } + type _seGNMvM = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOAuth2RequestEvent extends _seGNMvM { + providerName: string + providerClient: auth.Provider + record?: Record + oAuth2User?: auth.AuthUser + createData: _TygojaDict + isNewRecord: boolean + } + type _sNVzQZa = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRefreshRequestEvent extends _sNVzQZa { + record?: Record + } + type _sdkpEzX = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestPasswordResetRequestEvent extends _sdkpEzX { + record?: Record + } + type _sEScUnp = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmPasswordResetRequestEvent extends _sEScUnp { + record?: Record + } + type _sOQqOTQ = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestVerificationRequestEvent extends _sOQqOTQ { + record?: Record + } + type _sXFLvje = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmVerificationRequestEvent extends _sXFLvje { + record?: Record + } + type _sDnSdQC = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEmailChangeRequestEvent extends _sDnSdQC { + record?: Record + newEmail: string + } + type _sEUHTmE = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmEmailChangeRequestEvent extends _sEUHTmE { + record?: Record + newEmail: string + } + /** + * ExternalAuth defines a Record proxy for working with the externalAuths collection. + */ + type _skmdodV = Record + interface ExternalAuth extends _skmdodV { + } + interface newExternalAuth { + /** + * NewExternalAuth instantiates and returns a new blank *ExternalAuth model. + * + * Example usage: + * + * ``` + * ea := core.NewExternalAuth(app) + * ea.SetRecordRef(user.Id) + * ea.SetCollectionRef(user.Collection().Id) + * ea.SetProvider("google") + * ea.SetProviderId("...") + * app.Save(ea) + * ``` + */ + (app: App): (ExternalAuth) + } + interface ExternalAuth { + /** + * PreValidate implements the [PreValidator] interface and checks + * whether the proxy is properly loaded. + */ + preValidate(ctx: context.Context, app: App): void + } + interface ExternalAuth { + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + } + interface ExternalAuth { + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + interface ExternalAuth { + /** + * CollectionRef returns the "collectionRef" field value. + */ + collectionRef(): string + } + interface ExternalAuth { + /** + * SetCollectionRef updates the "collectionRef" record field value. + */ + setCollectionRef(collectionId: string): void + } + interface ExternalAuth { + /** + * RecordRef returns the "recordRef" record field value. + */ + recordRef(): string + } + interface ExternalAuth { + /** + * SetRecordRef updates the "recordRef" record field value. + */ + setRecordRef(recordId: string): void + } + interface ExternalAuth { + /** + * Provider returns the "provider" record field value. + */ + provider(): string + } + interface ExternalAuth { + /** + * SetProvider updates the "provider" record field value. + */ + setProvider(provider: string): void + } + interface ExternalAuth { + /** + * Provider returns the "providerId" record field value. + */ + providerId(): string + } + interface ExternalAuth { + /** + * SetProvider updates the "providerId" record field value. + */ + setProviderId(providerId: string): void + } + interface ExternalAuth { + /** + * Created returns the "created" record field value. + */ + created(): types.DateTime + } + interface ExternalAuth { + /** + * Updated returns the "updated" record field value. + */ + updated(): types.DateTime + } + interface BaseApp { + /** + * FindAllExternalAuthsByRecord returns all ExternalAuth models + * linked to the provided auth record. + */ + findAllExternalAuthsByRecord(authRecord: Record): Array<(ExternalAuth | undefined)> + } + interface BaseApp { + /** + * FindAllExternalAuthsByCollection returns all ExternalAuth models + * linked to the provided auth collection. + */ + findAllExternalAuthsByCollection(collection: Collection): Array<(ExternalAuth | undefined)> + } + interface BaseApp { + /** + * FindFirstExternalAuthByExpr returns the first available (the most recent created) + * ExternalAuth model that satisfies the non-nil expression. + */ + findFirstExternalAuthByExpr(expr: dbx.Expression): (ExternalAuth) + } + /** + * FieldFactoryFunc defines a simple function to construct a specific Field instance. + */ + interface FieldFactoryFunc {(): Field } + /** + * Field defines a common interface that all Collection fields should implement. + */ + interface Field { + [key:string]: any; + /** + * GetId returns the field id. + */ + getId(): string + /** + * SetId changes the field id. + */ + setId(id: string): void + /** + * GetName returns the field name. + */ + getName(): string + /** + * SetName changes the field name. + */ + setName(name: string): void + /** + * GetSystem returns the field system flag state. + */ + getSystem(): boolean + /** + * SetSystem changes the field system flag state. + */ + setSystem(system: boolean): void + /** + * GetHidden returns the field hidden flag state. + */ + getHidden(): boolean + /** + * SetHidden changes the field hidden flag state. + */ + setHidden(hidden: boolean): void + /** + * Type returns the unique type of the field. + */ + type(): string + /** + * ColumnType returns the DB column definition of the field. + */ + columnType(app: App): string + /** + * PrepareValue returns a properly formatted field value based on the provided raw one. + * + * This method is also called on record construction to initialize its default field value. + */ + prepareValue(record: Record, raw: any): any + /** + * ValidateSettings validates the current field value associated with the provided record. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + /** + * ValidateSettings validates the current field settings. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + /** + * MaxBodySizeCalculator defines an optional field interface for + * specifying the max size of a field value. + */ + interface MaxBodySizeCalculator { + [key:string]: any; + /** + * CalculateMaxBodySize returns the approximate max body size of a field value. + */ + calculateMaxBodySize(): number + } + interface SetterFunc {(record: Record, raw: any): void } + /** + * SetterFinder defines a field interface for registering custom field value setters. + */ + interface SetterFinder { + [key:string]: any; + /** + * FindSetter returns a single field value setter function + * by performing pattern-like field matching using the specified key. + * + * The key is usually just the field name but it could also + * contains "modifier" characters based on which you can perform custom set operations + * (ex. "users+" could be mapped to a function that will append new user to the existing field value). + * + * Return nil if you want to fallback to the default field value setter. + */ + findSetter(key: string): SetterFunc + } + interface GetterFunc {(record: Record): any } + /** + * GetterFinder defines a field interface for registering custom field value getters. + */ + interface GetterFinder { + [key:string]: any; + /** + * FindGetter returns a single field value getter function + * by performing pattern-like field matching using the specified key. + * + * The key is usually just the field name but it could also + * contains "modifier" characters based on which you can perform custom get operations + * (ex. "description:excerpt" could be mapped to a function that will return an excerpt of the current field value). + * + * Return nil if you want to fallback to the default field value setter. + */ + findGetter(key: string): GetterFunc + } + /** + * DriverValuer defines a Field interface for exporting and formatting + * a field value for the database. + */ + interface DriverValuer { + [key:string]: any; + /** + * DriverValue exports a single field value for persistence in the database. + */ + driverValue(record: Record): any + } + /** + * MultiValuer defines a field interface that every multi-valued (eg. with MaxSelect) field has. + */ + interface MultiValuer { + [key:string]: any; + /** + * IsMultiple checks whether the field is configured to support multiple or single values. + */ + isMultiple(): boolean + } + /** + * RecordInterceptor defines a field interface for reacting to various + * Record related operations (create, delete, validate, etc.). + */ + interface RecordInterceptor { + [key:string]: any; + /** + * Interceptor is invoked when a specific record action occurs + * allowing you to perform extra validations and normalization + * (ex. uploading or deleting files). + * + * Note that users must call actionFunc() manually if they want to + * execute the specific record action. + */ + intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void + } + interface defaultFieldIdValidationRule { + /** + * DefaultFieldIdValidationRule performs base validation on a field id value. + */ + (value: any): void + } + interface defaultFieldNameValidationRule { + /** + * DefaultFieldIdValidationRule performs base validation on a field name value. + */ + (value: any): void + } + /** + * AutodateField defines an "autodate" type field, aka. + * field which datetime value could be auto set on record create/update. + * + * This field is usually used for defining timestamp fields like "created" and "updated". + * + * Requires either both or at least one of the OnCreate or OnUpdate options to be set. + */ + interface AutodateField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * OnCreate auto sets the current datetime as field value on record create. + */ + onCreate: boolean + /** + * OnUpdate auto sets the current datetime as field value on record update. + */ + onUpdate: boolean + } + interface AutodateField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface AutodateField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface AutodateField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface AutodateField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface AutodateField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface AutodateField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface AutodateField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface AutodateField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface AutodateField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface AutodateField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface AutodateField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface AutodateField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface AutodateField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface AutodateField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + interface AutodateField { + /** + * Intercept implements the [RecordInterceptor] interface. + */ + intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void + } + /** + * BoolField defines "bool" type field to store a single true/false value. + * + * The respective zero record field value is false. + */ + interface BoolField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Required will require the field value to be always "true". + */ + required: boolean + } + interface BoolField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface BoolField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface BoolField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface BoolField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface BoolField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface BoolField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface BoolField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface BoolField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface BoolField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface BoolField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface BoolField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface BoolField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface BoolField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + /** + * DateField defines "date" type field to store a single [types.DateTime] value. + * + * The respective zero record field value is the zero [types.DateTime]. + */ + interface DateField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Min specifies the min allowed field value. + * + * Leave it empty to skip the validator. + */ + min: types.DateTime + /** + * Max specifies the max allowed field value. + * + * Leave it empty to skip the validator. + */ + max: types.DateTime + /** + * Required will require the field value to be non-zero [types.DateTime]. + */ + required: boolean + } + interface DateField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface DateField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface DateField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface DateField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface DateField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface DateField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface DateField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface DateField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface DateField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface DateField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface DateField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface DateField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface DateField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + /** + * EditorField defines "editor" type field to store HTML formatted text. + * + * The respective zero record field value is empty string. + */ + interface EditorField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). + * + * If zero, a default limit of ~5MB is applied. + */ + maxSize: number + /** + * ConvertURLs is usually used to instruct the editor whether to + * apply url conversion (eg. stripping the domain name in case the + * urls are using the same domain as the one where the editor is loaded). + * + * (see also https://www.tiny.cloud/docs/tinymce/6/url-handling/#convert_urls) + */ + convertURLs: boolean + /** + * Required will require the field value to be non-empty string. + */ + required: boolean + } + interface EditorField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface EditorField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface EditorField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface EditorField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface EditorField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface EditorField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface EditorField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface EditorField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface EditorField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface EditorField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface EditorField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface EditorField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface EditorField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface EditorField { + /** + * CalculateMaxBodySize implements the [MaxBodySizeCalculator] interface. + */ + calculateMaxBodySize(): number + } + /** + * EmailField defines "email" type field for storing a single email string address. + * + * The respective zero record field value is empty string. + */ + interface EmailField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * ExceptDomains will require the email domain to NOT be included in the listed ones. + * + * This validator can be set only if OnlyDomains is empty. + */ + exceptDomains: Array + /** + * OnlyDomains will require the email domain to be included in the listed ones. + * + * This validator can be set only if ExceptDomains is empty. + */ + onlyDomains: Array + /** + * Required will require the field value to be non-empty email string. + */ + required: boolean + } + interface EmailField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface EmailField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface EmailField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface EmailField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface EmailField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface EmailField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface EmailField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface EmailField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface EmailField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface EmailField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface EmailField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface EmailField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface EmailField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + /** + * FileField defines "file" type field for managing record file(s). + * + * Only the file name is stored as part of the record value. + * New files (aka. files to upload) are expected to be of *filesytem.File. + * + * If MaxSelect is not set or <= 1, then the field value is expected to be a single record id. + * + * If MaxSelect is > 1, then the field value is expected to be a slice of record ids. + * + * The respective zero record field value is either empty string (single) or empty string slice (multiple). + * + * --- + * + * The following additional setter keys are available: + * + * ``` + * - "fieldName+" - append one or more files to the existing record one. For example: + * + * // []string{"old1.txt", "old2.txt", "new1_ajkvass.txt", "new2_klhfnwd.txt"} + * record.Set("documents+", []*filesystem.File{new1, new2}) + * + * - "+fieldName" - prepend one or more files to the existing record one. For example: + * + * // []string{"new1_ajkvass.txt", "new2_klhfnwd.txt", "old1.txt", "old2.txt",} + * record.Set("+documents", []*filesystem.File{new1, new2}) + * + * - "fieldName-" - subtract/delete one or more files from the existing record one. For example: + * + * // []string{"old2.txt",} + * record.Set("documents-", "old1.txt") + * ``` + */ + interface FileField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * MaxSize specifies the maximum size of a single uploaded file (in bytes and up to 2^53-1). + * + * If zero, a default limit of 5MB is applied. + */ + maxSize: number + /** + * MaxSelect specifies the max allowed files. + * + * For multiple files the value must be > 1, otherwise fallbacks to single (default). + */ + maxSelect: number + /** + * MimeTypes specifies an optional list of the allowed file mime types. + * + * Leave it empty to disable the validator. + */ + mimeTypes: Array + /** + * Thumbs specifies an optional list of the supported thumbs for image based files. + * + * Each entry must be in one of the following formats: + * + * ``` + * - WxH (eg. 100x300) - crop to WxH viewbox (from center) + * - WxHt (eg. 100x300t) - crop to WxH viewbox (from top) + * - WxHb (eg. 100x300b) - crop to WxH viewbox (from bottom) + * - WxHf (eg. 100x300f) - fit inside a WxH viewbox (without cropping) + * - 0xH (eg. 0x300) - resize to H height preserving the aspect ratio + * - Wx0 (eg. 100x0) - resize to W width preserving the aspect ratio + * ``` + */ + thumbs: Array + /** + * Protected will require the users to provide a special file token to access the file. + * + * Note that by default all files are publicly accessible. + * + * For the majority of the cases this is fine because by default + * all file names have random part appended to their name which + * need to be known by the user before accessing the file. + */ + protected: boolean + /** + * Required will require the field value to have at least one file. + */ + required: boolean + } + interface FileField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface FileField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface FileField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface FileField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface FileField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface FileField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface FileField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface FileField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface FileField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface FileField { + /** + * IsMultiple implements MultiValuer interface and checks whether the + * current field options support multiple values. + */ + isMultiple(): boolean + } + interface FileField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface FileField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface FileField { + /** + * DriverValue implements the [DriverValuer] interface. + */ + driverValue(record: Record): any + } + interface FileField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface FileField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface FileField { + /** + * CalculateMaxBodySize implements the [MaxBodySizeCalculator] interface. + */ + calculateMaxBodySize(): number + } + interface FileField { + /** + * Intercept implements the [RecordInterceptor] interface. + * + * note: files delete after records deletion is handled globally by the app FileManager hook + */ + intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void + } + interface FileField { + /** + * FindGetter implements the [GetterFinder] interface. + */ + findGetter(key: string): GetterFunc + } + interface FileField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + /** + * GeoPointField defines "geoPoint" type field for storing latitude and longitude GPS coordinates. + * + * You can set the record field value as [types.GeoPoint], map or serialized json object with lat-lon props. + * The stored value is always converted to [types.GeoPoint]. + * Nil, empty map, empty bytes slice, etc. results in zero [types.GeoPoint]. + * + * Examples of updating a record's GeoPointField value programmatically: + * + * ``` + * record.Set("location", types.GeoPoint{Lat: 123, Lon: 456}) + * record.Set("location", map[string]any{"lat":123, "lon":456}) + * record.Set("location", []byte(`{"lat":123, "lon":456}`) + * ``` + */ + interface GeoPointField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Required will require the field coordinates to be non-zero (aka. not "Null Island"). + */ + required: boolean + } + interface GeoPointField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface GeoPointField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface GeoPointField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface GeoPointField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface GeoPointField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface GeoPointField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface GeoPointField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface GeoPointField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface GeoPointField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface GeoPointField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface GeoPointField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface GeoPointField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface GeoPointField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + /** + * JSONField defines "json" type field for storing any serialized JSON value. + * + * The respective zero record field value is the zero [types.JSONRaw]. + */ + interface JSONField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). + * + * If zero, a default limit of 1MB is applied. + */ + maxSize: number + /** + * Required will require the field value to be non-empty JSON value + * (aka. not "null", `""`, "[]", "{}"). + */ + required: boolean + } + interface JSONField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface JSONField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface JSONField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface JSONField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface JSONField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface JSONField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface JSONField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface JSONField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface JSONField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface JSONField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface JSONField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface JSONField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface JSONField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface JSONField { + /** + * CalculateMaxBodySize implements the [MaxBodySizeCalculator] interface. + */ + calculateMaxBodySize(): number + } + /** + * NumberField defines "number" type field for storing numeric (float64) value. + * + * The respective zero record field value is 0. + * + * The following additional setter keys are available: + * + * ``` + * - "fieldName+" - appends to the existing record value. For example: + * record.Set("total+", 5) + * - "fieldName-" - subtracts from the existing record value. For example: + * record.Set("total-", 5) + * ``` + */ + interface NumberField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Min specifies the min allowed field value. + * + * Leave it nil to skip the validator. + */ + min?: number + /** + * Max specifies the max allowed field value. + * + * Leave it nil to skip the validator. + */ + max?: number + /** + * OnlyInt will require the field value to be integer. + */ + onlyInt: boolean + /** + * Required will require the field value to be non-zero. + */ + required: boolean + } + interface NumberField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface NumberField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface NumberField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface NumberField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface NumberField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface NumberField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface NumberField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface NumberField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface NumberField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface NumberField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface NumberField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface NumberField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface NumberField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface NumberField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + /** + * PasswordField defines "password" type field for storing bcrypt hashed strings + * (usually used only internally for the "password" auth collection system field). + * + * If you want to set a direct bcrypt hash as record field value you can use the SetRaw method, for example: + * + * ``` + * // generates a bcrypt hash of "123456" and set it as field value + * // (record.GetString("password") returns the plain password until persisted, otherwise empty string) + * record.Set("password", "123456") + * + * // set directly a bcrypt hash of "123456" as field value + * // (record.GetString("password") returns empty string) + * record.SetRaw("password", "$2a$10$.5Elh8fgxypNUWhpUUr/xOa2sZm0VIaE0qWuGGl9otUfobb46T1Pq") + * ``` + * + * The following additional getter keys are available: + * + * ``` + * - "fieldName:hash" - returns the bcrypt hash string of the record field value (if any). For example: + * record.GetString("password:hash") + * ``` + */ + interface PasswordField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Pattern specifies an optional regex pattern to match against the field value. + * + * Leave it empty to skip the pattern check. + */ + pattern: string + /** + * Min specifies an optional required field string length. + */ + min: number + /** + * Max specifies an optional required field string length. + * + * If zero, fallback to max 71 bytes. + */ + max: number + /** + * Cost specifies the cost/weight/iteration/etc. bcrypt factor. + * + * If zero, fallback to [bcrypt.DefaultCost]. + * + * If explicitly set, must be between [bcrypt.MinCost] and [bcrypt.MaxCost]. + */ + cost: number + /** + * Required will require the field value to be non-empty string. + */ + required: boolean + } + interface PasswordField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface PasswordField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface PasswordField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface PasswordField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface PasswordField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface PasswordField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface PasswordField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface PasswordField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface PasswordField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface PasswordField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface PasswordField { + /** + * DriverValue implements the [DriverValuer] interface. + */ + driverValue(record: Record): any + } + interface PasswordField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface PasswordField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface PasswordField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface PasswordField { + /** + * Intercept implements the [RecordInterceptor] interface. + */ + intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void + } + interface PasswordField { + /** + * FindGetter implements the [GetterFinder] interface. + */ + findGetter(key: string): GetterFunc + } + interface PasswordField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + interface PasswordFieldValue { + lastError: Error + hash: string + plain: string + } + interface PasswordFieldValue { + validate(pass: string): boolean + } + /** + * RelationField defines "relation" type field for storing single or + * multiple collection record references. + * + * Requires the CollectionId option to be set. + * + * If MaxSelect is not set or <= 1, then the field value is expected to be a single record id. + * + * If MaxSelect is > 1, then the field value is expected to be a slice of record ids. + * + * The respective zero record field value is either empty string (single) or empty string slice (multiple). + * + * --- + * + * The following additional setter keys are available: + * + * ``` + * - "fieldName+" - append one or more values to the existing record one. For example: + * + * record.Set("categories+", []string{"new1", "new2"}) // []string{"old1", "old2", "new1", "new2"} + * + * - "+fieldName" - prepend one or more values to the existing record one. For example: + * + * record.Set("+categories", []string{"new1", "new2"}) // []string{"new1", "new2", "old1", "old2"} + * + * - "fieldName-" - subtract one or more values from the existing record one. For example: + * + * record.Set("categories-", "old1") // []string{"old2"} + * ``` + */ + interface RelationField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * CollectionId is the id of the related collection. + */ + collectionId: string + /** + * CascadeDelete indicates whether the root model should be deleted + * in case of delete of all linked relations. + */ + cascadeDelete: boolean + /** + * MinSelect indicates the min number of allowed relation records + * that could be linked to the main model. + * + * No min limit is applied if it is zero or negative value. + */ + minSelect: number + /** + * MaxSelect indicates the max number of allowed relation records + * that could be linked to the main model. + * + * For multiple select the value must be > 1, otherwise fallbacks to single (default). + * + * If MinSelect is set, MaxSelect must be at least >= MinSelect. + */ + maxSelect: number + /** + * Required will require the field value to be non-empty. + */ + required: boolean + } + interface RelationField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface RelationField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface RelationField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface RelationField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface RelationField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface RelationField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface RelationField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface RelationField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface RelationField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface RelationField { + /** + * IsMultiple implements [MultiValuer] interface and checks whether the + * current field options support multiple values. + */ + isMultiple(): boolean + } + interface RelationField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface RelationField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface RelationField { + /** + * DriverValue implements the [DriverValuer] interface. + */ + driverValue(record: Record): any + } + interface RelationField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface RelationField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface RelationField { + /** + * FindSetter implements [SetterFinder] interface method. + */ + findSetter(key: string): SetterFunc + } + /** + * SelectField defines "select" type field for storing single or + * multiple string values from a predefined list. + * + * Requires the Values option to be set. + * + * If MaxSelect is not set or <= 1, then the field value is expected to be a single Values element. + * + * If MaxSelect is > 1, then the field value is expected to be a subset of Values slice. + * + * The respective zero record field value is either empty string (single) or empty string slice (multiple). + * + * --- + * + * The following additional setter keys are available: + * + * ``` + * - "fieldName+" - append one or more values to the existing record one. For example: + * + * record.Set("roles+", []string{"new1", "new2"}) // []string{"old1", "old2", "new1", "new2"} + * + * - "+fieldName" - prepend one or more values to the existing record one. For example: + * + * record.Set("+roles", []string{"new1", "new2"}) // []string{"new1", "new2", "old1", "old2"} + * + * - "fieldName-" - subtract one or more values from the existing record one. For example: + * + * record.Set("roles-", "old1") // []string{"old2"} + * ``` + */ + interface SelectField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Values specifies the list of accepted values. + */ + values: Array + /** + * MaxSelect specifies the max allowed selected values. + * + * For multiple select the value must be > 1, otherwise fallbacks to single (default). + */ + maxSelect: number + /** + * Required will require the field value to be non-empty. + */ + required: boolean + } + interface SelectField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface SelectField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface SelectField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface SelectField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface SelectField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface SelectField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface SelectField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface SelectField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface SelectField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface SelectField { + /** + * IsMultiple implements [MultiValuer] interface and checks whether the + * current field options support multiple values. + */ + isMultiple(): boolean + } + interface SelectField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface SelectField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface SelectField { + /** + * DriverValue implements the [DriverValuer] interface. + */ + driverValue(record: Record): any + } + interface SelectField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface SelectField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface SelectField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + /** + * TextField defines "text" type field for storing any string value. + * + * The respective zero record field value is empty string. + * + * The following additional setter keys are available: + * + * - "fieldName:autogenerate" - autogenerate field value if AutogeneratePattern is set. For example: + * + * ``` + * record.Set("slug:autogenerate", "") // [random value] + * record.Set("slug:autogenerate", "abc-") // abc-[random value] + * ``` + */ + interface TextField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * Min specifies the minimum required string characters. + * + * if zero value, no min limit is applied. + */ + min: number + /** + * Max specifies the maximum allowed string characters. + * + * If zero, a default limit of 5000 is applied. + */ + max: number + /** + * Pattern specifies an optional regex pattern to match against the field value. + * + * Leave it empty to skip the pattern check. + */ + pattern: string + /** + * AutogeneratePattern specifies an optional regex pattern that could + * be used to generate random string from it and set it automatically + * on record create if no explicit value is set or when the `:autogenerate` modifier is used. + * + * Note: the generated value still needs to satisfy min, max, pattern (if set) + */ + autogeneratePattern: string + /** + * Required will require the field value to be non-empty string. + */ + required: boolean + /** + * PrimaryKey will mark the field as primary key. + * + * A single collection can have only 1 field marked as primary key. + */ + primaryKey: boolean + } + interface TextField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface TextField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface TextField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface TextField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface TextField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface TextField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface TextField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface TextField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface TextField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface TextField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface TextField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface TextField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface TextField { + /** + * ValidatePlainValue validates the provided string against the field options. + */ + validatePlainValue(value: string): void + } + interface TextField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface TextField { + /** + * Intercept implements the [RecordInterceptor] interface. + */ + intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void + } + interface TextField { + /** + * FindSetter implements the [SetterFinder] interface. + */ + findSetter(key: string): SetterFunc + } + /** + * URLField defines "url" type field for storing a single URL string value. + * + * The respective zero record field value is empty string. + */ + interface URLField { + /** + * Name (required) is the unique name of the field. + */ + name: string + /** + * Id is the unique stable field identifier. + * + * It is automatically generated from the name when adding to a collection FieldsList. + */ + id: string + /** + * System prevents the renaming and removal of the field. + */ + system: boolean + /** + * Hidden hides the field from the API response. + */ + hidden: boolean + /** + * Presentable hints the Dashboard UI to use the underlying + * field record value in the relation preview label. + */ + presentable: boolean + /** + * ExceptDomains will require the URL domain to NOT be included in the listed ones. + * + * This validator can be set only if OnlyDomains is empty. + */ + exceptDomains: Array + /** + * OnlyDomains will require the URL domain to be included in the listed ones. + * + * This validator can be set only if ExceptDomains is empty. + */ + onlyDomains: Array + /** + * Required will require the field value to be non-empty URL string. + */ + required: boolean + } + interface URLField { + /** + * Type implements [Field.Type] interface method. + */ + type(): string + } + interface URLField { + /** + * GetId implements [Field.GetId] interface method. + */ + getId(): string + } + interface URLField { + /** + * SetId implements [Field.SetId] interface method. + */ + setId(id: string): void + } + interface URLField { + /** + * GetName implements [Field.GetName] interface method. + */ + getName(): string + } + interface URLField { + /** + * SetName implements [Field.SetName] interface method. + */ + setName(name: string): void + } + interface URLField { + /** + * GetSystem implements [Field.GetSystem] interface method. + */ + getSystem(): boolean + } + interface URLField { + /** + * SetSystem implements [Field.SetSystem] interface method. + */ + setSystem(system: boolean): void + } + interface URLField { + /** + * GetHidden implements [Field.GetHidden] interface method. + */ + getHidden(): boolean + } + interface URLField { + /** + * SetHidden implements [Field.SetHidden] interface method. + */ + setHidden(hidden: boolean): void + } + interface URLField { + /** + * ColumnType implements [Field.ColumnType] interface method. + */ + columnType(app: App): string + } + interface URLField { + /** + * PrepareValue implements [Field.PrepareValue] interface method. + */ + prepareValue(record: Record, raw: any): any + } + interface URLField { + /** + * ValidateValue implements [Field.ValidateValue] interface method. + */ + validateValue(ctx: context.Context, app: App, record: Record): void + } + interface URLField { + /** + * ValidateSettings implements [Field.ValidateSettings] interface method. + */ + validateSettings(ctx: context.Context, app: App, collection: Collection): void + } + interface newFieldsList { + /** + * NewFieldsList creates a new FieldsList instance with the provided fields. + */ + (...fields: Field[]): FieldsList + } + /** + * FieldsList defines a Collection slice of fields. + */ + interface FieldsList extends Array{} + interface FieldsList { + /** + * Clone creates a deep clone of the current list. + */ + clone(): FieldsList + } + interface FieldsList { + /** + * FieldNames returns a slice with the name of all list fields. + */ + fieldNames(): Array + } + interface FieldsList { + /** + * AsMap returns a map with all registered list field. + * The returned map is indexed with each field name. + */ + asMap(): _TygojaDict + } + interface FieldsList { + /** + * GetById returns a single field by its id. + */ + getById(fieldId: string): Field + } + interface FieldsList { + /** + * GetByName returns a single field by its name. + */ + getByName(fieldName: string): Field + } + interface FieldsList { + /** + * RemoveById removes a single field by its id. + * + * This method does nothing if field with the specified id doesn't exist. + */ + removeById(fieldId: string): void + } + interface FieldsList { + /** + * RemoveByName removes a single field by its name. + * + * This method does nothing if field with the specified name doesn't exist. + */ + removeByName(fieldName: string): void + } + interface FieldsList { + /** + * Add adds one or more fields to the current list. + * + * By default this method will try to REPLACE existing fields with + * the new ones by their id or by their name if the new field doesn't have an explicit id. + * + * If no matching existing field is found, it will APPEND the field to the end of the list. + * + * In all cases, if any of the new fields don't have an explicit id it will auto generate a default one for them + * (the id value doesn't really matter and it is mostly used as a stable identifier in case of a field rename). + */ + add(...fields: Field[]): void + } + interface FieldsList { + /** + * AddAt is the same as Add but insert/move the fields at the specific position. + * + * If pos < 0, then this method acts the same as calling Add. + * + * If pos > FieldsList total items, then the specified fields are inserted/moved at the end of the list. + */ + addAt(pos: number, ...fields: Field[]): void + } + interface FieldsList { + /** + * AddMarshaledJSON parses the provided raw json data and adds the + * found fields into the current list (following the same rule as the Add method). + * + * The rawJSON argument could be one of: + * ``` + * - serialized array of field objects + * - single field object. + * ``` + * + * Example: + * + * ``` + * l.AddMarshaledJSON([]byte{`{"type":"text", name: "test"}`}) + * l.AddMarshaledJSON([]byte{`[{"type":"text", name: "test1"}, {"type":"text", name: "test2"}]`}) + * ``` + */ + addMarshaledJSON(rawJSON: string|Array): void + } + interface FieldsList { + /** + * AddMarshaledJSONAt is the same as AddMarshaledJSON but insert/move the fields at the specific position. + * + * If pos < 0, then this method acts the same as calling AddMarshaledJSON. + * + * If pos > FieldsList total items, then the specified fields are inserted/moved at the end of the list. + */ + addMarshaledJSONAt(pos: number, rawJSON: string|Array): void + } + interface FieldsList { + /** + * String returns the string representation of the current list. + */ + string(): string + } + interface onlyFieldType { + type: string + } + type _sOTxqnS = Field + interface fieldWithType extends _sOTxqnS { + type: string + } + interface fieldWithType { + unmarshalJSON(data: string|Array): void + } + interface FieldsList { + /** + * UnmarshalJSON implements [json.Unmarshaler] and + * loads the provided json data into the current FieldsList. + */ + unmarshalJSON(data: string|Array): void + } + interface FieldsList { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface FieldsList { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface FieldsList { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current FieldsList instance. + */ + scan(value: any): void + } + type _szUQMEc = BaseModel + interface Log extends _szUQMEc { + created: types.DateTime + data: types.JSONMap + message: string + level: number + } + interface Log { + tableName(): string + } + interface BaseApp { + /** + * LogQuery returns a new Log select query. + */ + logQuery(): (dbx.SelectQuery) + } + interface BaseApp { + /** + * FindLogById finds a single Log entry by its id. + */ + findLogById(id: string): (Log) + } + /** + * LogsStatsItem defines the total number of logs for a specific time period. + */ + interface LogsStatsItem { + date: types.DateTime + total: number + } + interface BaseApp { + /** + * LogsStats returns hourly grouped logs statistics. + */ + logsStats(expr: dbx.Expression): Array<(LogsStatsItem | undefined)> + } + interface BaseApp { + /** + * DeleteOldLogs delete all logs that are created before createdBefore. + * + * For better performance the logs delete is executed as plain SQL statement, + * aka. no delete model hook events will be fired. + */ + deleteOldLogs(createdBefore: time.Time): void + } + /** + * MFA defines a Record proxy for working with the mfas collection. + */ + type _sOqraWf = Record + interface MFA extends _sOqraWf { + } + interface newMFA { + /** + * NewMFA instantiates and returns a new blank *MFA model. + * + * Example usage: + * + * ``` + * mfa := core.NewMFA(app) + * mfa.SetRecordRef(user.Id) + * mfa.SetCollectionRef(user.Collection().Id) + * mfa.SetMethod(core.MFAMethodPassword) + * app.Save(mfa) + * ``` + */ + (app: App): (MFA) + } + interface MFA { + /** + * PreValidate implements the [PreValidator] interface and checks + * whether the proxy is properly loaded. + */ + preValidate(ctx: context.Context, app: App): void + } + interface MFA { + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + } + interface MFA { + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + interface MFA { + /** + * CollectionRef returns the "collectionRef" field value. + */ + collectionRef(): string + } + interface MFA { + /** + * SetCollectionRef updates the "collectionRef" record field value. + */ + setCollectionRef(collectionId: string): void + } + interface MFA { + /** + * RecordRef returns the "recordRef" record field value. + */ + recordRef(): string + } + interface MFA { + /** + * SetRecordRef updates the "recordRef" record field value. + */ + setRecordRef(recordId: string): void + } + interface MFA { + /** + * Method returns the "method" record field value. + */ + method(): string + } + interface MFA { + /** + * SetMethod updates the "method" record field value. + */ + setMethod(method: string): void + } + interface MFA { + /** + * Created returns the "created" record field value. + */ + created(): types.DateTime + } + interface MFA { + /** + * Updated returns the "updated" record field value. + */ + updated(): types.DateTime + } + interface MFA { + /** + * HasExpired checks if the mfa is expired, aka. whether it has been + * more than maxElapsed time since its creation. + */ + hasExpired(maxElapsed: time.Duration): boolean + } + interface BaseApp { + /** + * FindAllMFAsByRecord returns all MFA models linked to the provided auth record. + */ + findAllMFAsByRecord(authRecord: Record): Array<(MFA | undefined)> + } + interface BaseApp { + /** + * FindAllMFAsByCollection returns all MFA models linked to the provided collection. + */ + findAllMFAsByCollection(collection: Collection): Array<(MFA | undefined)> + } + interface BaseApp { + /** + * FindMFAById returns a single MFA model by its id. + */ + findMFAById(id: string): (MFA) + } + interface BaseApp { + /** + * DeleteAllMFAsByRecord deletes all MFA models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllMFAsByRecord(authRecord: Record): void + } + interface BaseApp { + /** + * DeleteExpiredMFAs deletes the expired MFAs for all auth collections. + */ + deleteExpiredMFAs(): void + } + interface Migration { + up: (txApp: App) => void + down: (txApp: App) => void + file: string + reapplyCondition: (txApp: App, runner: MigrationsRunner, fileName: string) => boolean + } + /** + * MigrationsList defines a list with migration definitions + */ + interface MigrationsList { + } + interface MigrationsList { + /** + * Item returns a single migration from the list by its index. + */ + item(index: number): (Migration) + } + interface MigrationsList { + /** + * Items returns the internal migrations list slice. + */ + items(): Array<(Migration | undefined)> + } + interface MigrationsList { + /** + * Copy copies all provided list migrations into the current one. + */ + copy(list: MigrationsList): void + } + interface MigrationsList { + /** + * Add adds adds an existing migration definition to the list. + * + * If m.File is not provided, it will try to get the name from its .go file. + * + * The list will be sorted automatically based on the migrations file name. + */ + add(m: Migration): void + } + interface MigrationsList { + /** + * Register adds new migration definition to the list. + * + * If optFilename is not provided, it will try to get the name from its .go file. + * + * The list will be sorted automatically based on the migrations file name. + */ + register(up: (txApp: App) => void, down: (txApp: App) => void, ...optFilename: string[]): void + } + /** + * MigrationsRunner defines a simple struct for managing the execution of db migrations. + */ + interface MigrationsRunner { + } + interface newMigrationsRunner { + /** + * NewMigrationsRunner creates and initializes a new db migrations MigrationsRunner instance. + */ + (app: App, migrationsList: MigrationsList): (MigrationsRunner) + } + interface MigrationsRunner { + /** + * Run interactively executes the current runner with the provided args. + * + * The following commands are supported: + * - up - applies all migrations + * - down [n] - reverts the last n (default 1) applied migrations + * - history-sync - syncs the migrations table with the runner's migrations list + */ + run(...args: string[]): void + } + interface MigrationsRunner { + /** + * Up executes all unapplied migrations for the provided runner. + * + * On success returns list with the applied migrations file names. + */ + up(): Array + } + interface MigrationsRunner { + /** + * Down reverts the last `toRevertCount` applied migrations + * (in the order they were applied). + * + * On success returns list with the reverted migrations file names. + */ + down(toRevertCount: number): Array + } + interface MigrationsRunner { + /** + * RemoveMissingAppliedMigrations removes the db entries of all applied migrations + * that are not listed in the runner's migrations list. + */ + removeMissingAppliedMigrations(): void + } + /** + * OTP defines a Record proxy for working with the otps collection. + */ + type _ssPdGSG = Record + interface OTP extends _ssPdGSG { + } + interface newOTP { + /** + * NewOTP instantiates and returns a new blank *OTP model. + * + * Example usage: + * + * ``` + * otp := core.NewOTP(app) + * otp.SetRecordRef(user.Id) + * otp.SetCollectionRef(user.Collection().Id) + * otp.SetPassword(security.RandomStringWithAlphabet(6, "1234567890")) + * app.Save(otp) + * ``` + */ + (app: App): (OTP) + } + interface OTP { + /** + * PreValidate implements the [PreValidator] interface and checks + * whether the proxy is properly loaded. + */ + preValidate(ctx: context.Context, app: App): void + } + interface OTP { + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + } + interface OTP { + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + interface OTP { + /** + * CollectionRef returns the "collectionRef" field value. + */ + collectionRef(): string + } + interface OTP { + /** + * SetCollectionRef updates the "collectionRef" record field value. + */ + setCollectionRef(collectionId: string): void + } + interface OTP { + /** + * RecordRef returns the "recordRef" record field value. + */ + recordRef(): string + } + interface OTP { + /** + * SetRecordRef updates the "recordRef" record field value. + */ + setRecordRef(recordId: string): void + } + interface OTP { + /** + * SentTo returns the "sentTo" record field value. + * + * It could be any string value (email, phone, message app id, etc.) + * and usually is used as part of the auth flow to update the verified + * user state in case for example the sentTo value matches with the user record email. + */ + sentTo(): string + } + interface OTP { + /** + * SetSentTo updates the "sentTo" record field value. + */ + setSentTo(val: string): void + } + interface OTP { + /** + * Created returns the "created" record field value. + */ + created(): types.DateTime + } + interface OTP { + /** + * Updated returns the "updated" record field value. + */ + updated(): types.DateTime + } + interface OTP { + /** + * HasExpired checks if the otp is expired, aka. whether it has been + * more than maxElapsed time since its creation. + */ + hasExpired(maxElapsed: time.Duration): boolean + } + interface BaseApp { + /** + * FindAllOTPsByRecord returns all OTP models linked to the provided auth record. + */ + findAllOTPsByRecord(authRecord: Record): Array<(OTP | undefined)> + } + interface BaseApp { + /** + * FindAllOTPsByCollection returns all OTP models linked to the provided collection. + */ + findAllOTPsByCollection(collection: Collection): Array<(OTP | undefined)> + } + interface BaseApp { + /** + * FindOTPById returns a single OTP model by its id. + */ + findOTPById(id: string): (OTP) + } + interface BaseApp { + /** + * DeleteAllOTPsByRecord deletes all OTP models associated with the provided record. + * + * Returns a combined error with the failed deletes. + */ + deleteAllOTPsByRecord(authRecord: Record): void + } + interface BaseApp { + /** + * DeleteExpiredOTPs deletes the expired OTPs for all auth collections. + */ + deleteExpiredOTPs(): void + } + /** + * RecordFieldResolver defines a custom search resolver struct for + * managing Record model search fields. + * + * Usually used together with `search.Provider`. + * Example: + * + * ``` + * resolver := resolvers.NewRecordFieldResolver( + * app, + * myCollection, + * &models.RequestInfo{...}, + * true, + * ) + * provider := search.NewProvider(resolver) + * ... + * ``` + */ + interface RecordFieldResolver { + } + interface RecordFieldResolver { + /** + * AllowedFields returns a copy of the resolver's allowed fields. + */ + allowedFields(): Array + } + interface RecordFieldResolver { + /** + * SetAllowedFields replaces the resolver's allowed fields with the new ones. + */ + setAllowedFields(newAllowedFields: Array): void + } + interface RecordFieldResolver { + /** + * AllowHiddenFields returns whether the current resolver allows filtering hidden fields. + */ + allowHiddenFields(): boolean + } + interface RecordFieldResolver { + /** + * SetAllowHiddenFields enables or disables hidden fields filtering. + */ + setAllowHiddenFields(allowHiddenFields: boolean): void + } + interface newRecordFieldResolver { + /** + * NewRecordFieldResolver creates and initializes a new `RecordFieldResolver`. + */ + (app: App, baseCollection: Collection, requestInfo: RequestInfo, allowHiddenFields: boolean): (RecordFieldResolver) + } + interface RecordFieldResolver { + /** + * UpdateQuery implements `search.FieldResolver` interface. + * + * Conditionally updates the provided search query based on the + * resolved fields (eg. dynamically joining relations). + */ + updateQuery(query: dbx.SelectQuery): void + } + interface RecordFieldResolver { + /** + * Resolve implements `search.FieldResolver` interface. + * + * Example of some resolvable fieldName formats: + * + * ``` + * id + * someSelect.each + * project.screen.status + * screen.project_via_prototype.name + * @request.context + * @request.method + * @request.query.filter + * @request.headers.x_token + * @request.auth.someRelation.name + * @request.body.someRelation.name + * @request.body.someField + * @request.body.someSelect:each + * @request.body.someField:isset + * @collection.product.name + * ``` + */ + resolve(fieldName: string): (search.ResolverResult) + } + interface mapExtractor { + [key:string]: any; + asMap(): _TygojaDict + } + /** + * join defines the specification for a single SQL JOIN clause. + */ + interface join { + } + /** + * multiMatchSubquery defines a record multi-match subquery expression. + */ + interface multiMatchSubquery { + } + interface multiMatchSubquery { + /** + * Build converts the expression into a SQL fragment. + * + * Implements [dbx.Expression] interface. + */ + build(db: dbx.DB, params: dbx.Params): string + } + interface runner { + } + type _scuJFmS = BaseModel + interface Record extends _scuJFmS { + } + interface newRecord { + /** + * NewRecord initializes a new empty Record model. + */ + (collection: Collection): (Record) + } + interface Record { + /** + * Collection returns the Collection model associated with the current Record model. + * + * NB! The returned collection is only for read purposes and it shouldn't be modified + * because it could have unintended side-effects on other Record models from the same collection. + */ + collection(): (Collection) + } + interface Record { + /** + * TableName returns the table name associated with the current Record model. + */ + tableName(): string + } + interface Record { + /** + * PostScan implements the [dbx.PostScanner] interface. + * + * It essentially refreshes/updates the current Record original state + * as if the model was fetched from the databases for the first time. + * + * Or in other words, it means that m.Original().FieldsData() will have + * the same values as m.Record().FieldsData(). + */ + postScan(): void + } + interface Record { + /** + * HookTags returns the hook tags associated with the current record. + */ + hookTags(): Array + } + interface Record { + /** + * BaseFilesPath returns the storage dir path used by the record. + */ + baseFilesPath(): string + } + interface Record { + /** + * Original returns a shallow copy of the current record model populated + * with its ORIGINAL db data state (aka. right after PostScan()) + * and everything else reset to the defaults. + * + * If record was created using NewRecord() the original will be always + * a blank record (until PostScan() is invoked). + */ + original(): (Record) + } + interface Record { + /** + * Fresh returns a shallow copy of the current record model populated + * with its LATEST data state and everything else reset to the defaults + * (aka. no expand, no unknown fields and with default visibility flags). + */ + fresh(): (Record) + } + interface Record { + /** + * Clone returns a shallow copy of the current record model with all of + * its collection and unknown fields data, expand and flags copied. + * + * use [Record.Fresh()] instead if you want a copy with only the latest + * collection fields data and everything else reset to the defaults. + */ + clone(): (Record) + } + interface Record { + /** + * Expand returns a shallow copy of the current Record model expand data (if any). + */ + expand(): _TygojaDict + } + interface Record { + /** + * SetExpand replaces the current Record's expand with the provided expand arg data (shallow copied). + */ + setExpand(expand: _TygojaDict): void + } + interface Record { + /** + * MergeExpand merges recursively the provided expand data into + * the current model's expand (if any). + * + * Note that if an expanded prop with the same key is a slice (old or new expand) + * then both old and new records will be merged into a new slice (aka. a :merge: [b,c] => [a,b,c]). + * Otherwise the "old" expanded record will be replace with the "new" one (aka. a :merge: aNew => aNew). + */ + mergeExpand(expand: _TygojaDict): void + } + interface Record { + /** + * FieldsData returns a shallow copy ONLY of the collection's fields record's data. + */ + fieldsData(): _TygojaDict + } + interface Record { + /** + * CustomData returns a shallow copy ONLY of the custom record fields data, + * aka. fields that are neither defined by the collection, nor special system ones. + * + * Note that custom fields prefixed with "@pbInternal" are always skipped. + */ + customData(): _TygojaDict + } + interface Record { + /** + * WithCustomData toggles the export/serialization of custom data fields + * (false by default). + */ + withCustomData(state: boolean): (Record) + } + interface Record { + /** + * IgnoreEmailVisibility toggles the flag to ignore the auth record email visibility check. + */ + ignoreEmailVisibility(state: boolean): (Record) + } + interface Record { + /** + * IgnoreUnchangedFields toggles the flag to ignore the unchanged fields + * from the DB export for the UPDATE SQL query. + * + * This could be used if you want to save only the record fields that you've changed + * without overwrite other untouched fields in case of concurrent update. + * + * Note that the fields change comparison is based on the current fields against m.Original() + * (aka. if you have performed save on the same Record instance multiple times you may have to refetch it, + * so that m.Original() could reflect the last saved change). + */ + ignoreUnchangedFields(state: boolean): (Record) + } + interface Record { + /** + * Set sets the provided key-value data pair into the current Record + * model directly as it is WITHOUT NORMALIZATIONS. + * + * See also [Record.Set]. + */ + setRaw(key: string, value: any): void + } + interface Record { + /** + * SetIfFieldExists sets the provided key-value data pair into the current Record model + * ONLY if key is existing Collection field name/modifier. + * + * This method does nothing if key is not a known Collection field name/modifier. + * + * On success returns the matched Field, otherwise - nil. + * + * To set any key-value, including custom/unknown fields, use the [Record.Set] method. + */ + setIfFieldExists(key: string, value: any): Field + } + interface Record { + /** + * Set sets the provided key-value data pair into the current Record model. + * + * If the record collection has field with name matching the provided "key", + * the value will be further normalized according to the field setter(s). + */ + set(key: string, value: any): void + } + interface Record { + getRaw(key: string): any + } + interface Record { + /** + * Get returns a normalized single record model data value for "key". + */ + get(key: string): any + } + interface Record { + /** + * Load bulk loads the provided data into the current Record model. + */ + load(data: _TygojaDict): void + } + interface Record { + /** + * GetBool returns the data value for "key" as a bool. + */ + getBool(key: string): boolean + } + interface Record { + /** + * GetString returns the data value for "key" as a string. + */ + getString(key: string): string + } + interface Record { + /** + * GetInt returns the data value for "key" as an int. + */ + getInt(key: string): number + } + interface Record { + /** + * GetFloat returns the data value for "key" as a float64. + */ + getFloat(key: string): number + } + interface Record { + /** + * GetDateTime returns the data value for "key" as a DateTime instance. + */ + getDateTime(key: string): types.DateTime + } + interface Record { + /** + * GetGeoPoint returns the data value for "key" as a GeoPoint instance. + */ + getGeoPoint(key: string): types.GeoPoint + } + interface Record { + /** + * GetStringSlice returns the data value for "key" as a slice of non-zero unique strings. + */ + getStringSlice(key: string): Array + } + interface Record { + /** + * GetUnsavedFiles returns the uploaded files for the provided "file" field key, + * (aka. the current [*filesytem.File] values) so that you can apply further + * validations or modifications (including changing the file name or content before persisting). + * + * Example: + * + * ``` + * files := record.GetUnsavedFiles("documents") + * for _, f := range files { + * f.Name = "doc_" + f.Name // add a prefix to each file name + * } + * app.Save(record) // the files are pointers so the applied changes will transparently reflect on the record value + * ``` + */ + getUnsavedFiles(key: string): Array<(filesystem.File | undefined)> + } + interface Record { + /** + * Deprecated: replaced with GetUnsavedFiles. + */ + getUploadedFiles(key: string): Array<(filesystem.File | undefined)> + } + interface Record { + /** + * Retrieves the "key" json field value and unmarshals it into "result". + * + * Example + * + * ``` + * result := struct { + * FirstName string `json:"first_name"` + * }{} + * err := m.UnmarshalJSONField("my_field_name", &result) + * ``` + */ + unmarshalJSONField(key: string, result: any): void + } + interface Record { + /** + * ExpandedOne retrieves a single relation Record from the already + * loaded expand data of the current model. + * + * If the requested expand relation is multiple, this method returns + * only first available Record from the expanded relation. + * + * Returns nil if there is no such expand relation loaded. + */ + expandedOne(relField: string): (Record) + } + interface Record { + /** + * ExpandedAll retrieves a slice of relation Records from the already + * loaded expand data of the current model. + * + * If the requested expand relation is single, this method normalizes + * the return result and will wrap the single model as a slice. + * + * Returns nil slice if there is no such expand relation loaded. + */ + expandedAll(relField: string): Array<(Record | undefined)> + } + interface Record { + /** + * FindFileFieldByFile returns the first file type field for which + * any of the record's data contains the provided filename. + */ + findFileFieldByFile(filename: string): (FileField) + } + interface Record { + /** + * DBExport implements the [DBExporter] interface and returns a key-value + * map with the data to be persisted when saving the Record in the database. + */ + dbExport(app: App): _TygojaDict + } + interface Record { + /** + * Hide hides the specified fields from the public safe serialization of the record. + */ + hide(...fieldNames: string[]): (Record) + } + interface Record { + /** + * Unhide forces to unhide the specified fields from the public safe serialization + * of the record (even when the collection field itself is marked as hidden). + */ + unhide(...fieldNames: string[]): (Record) + } + interface Record { + /** + * PublicExport exports only the record fields that are safe to be public. + * + * To export unknown data fields you need to set record.WithCustomData(true). + * + * For auth records, to force the export of the email field you need to set + * record.IgnoreEmailVisibility(true). + */ + publicExport(): _TygojaDict + } + interface Record { + /** + * MarshalJSON implements the [json.Marshaler] interface. + * + * Only the data exported by `PublicExport()` will be serialized. + */ + marshalJSON(): string|Array + } + interface Record { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(data: string|Array): void + } + interface Record { + /** + * ReplaceModifiers returns a new map with applied modifier + * values based on the current record and the specified data. + * + * The resolved modifier keys will be removed. + * + * Multiple modifiers will be applied one after another, + * while reusing the previous base key value result (ex. 1; -5; +2 => -2). + * + * Note that because Go doesn't guaranteed the iteration order of maps, + * we would explicitly apply shorter keys first for a more consistent and reproducible behavior. + * + * Example usage: + * + * ``` + * newData := record.ReplaceModifiers(data) + * // record: {"field": 10} + * // data: {"field+": 5} + * // result: {"field": 15} + * ``` + */ + replaceModifiers(data: _TygojaDict): _TygojaDict + } + interface Record { + /** + * Email returns the "email" record field value (usually available with Auth collections). + */ + email(): string + } + interface Record { + /** + * SetEmail sets the "email" record field value (usually available with Auth collections). + */ + setEmail(email: string): void + } + interface Record { + /** + * Verified returns the "emailVisibility" record field value (usually available with Auth collections). + */ + emailVisibility(): boolean + } + interface Record { + /** + * SetEmailVisibility sets the "emailVisibility" record field value (usually available with Auth collections). + */ + setEmailVisibility(visible: boolean): void + } + interface Record { + /** + * Verified returns the "verified" record field value (usually available with Auth collections). + */ + verified(): boolean + } + interface Record { + /** + * SetVerified sets the "verified" record field value (usually available with Auth collections). + */ + setVerified(verified: boolean): void + } + interface Record { + /** + * TokenKey returns the "tokenKey" record field value (usually available with Auth collections). + */ + tokenKey(): string + } + interface Record { + /** + * SetTokenKey sets the "tokenKey" record field value (usually available with Auth collections). + */ + setTokenKey(key: string): void + } + interface Record { + /** + * RefreshTokenKey generates and sets a new random auth record "tokenKey". + */ + refreshTokenKey(): void + } + interface Record { + /** + * SetPassword sets the "password" record field value (usually available with Auth collections). + */ + setPassword(password: string): void + } + interface Record { + /** + * SetRandomPassword sets the "password" auth record field to a random autogenerated value. + * + * The autogenerated password is ~30 characters and it is set directly as hash, + * aka. the field plain password value validators (length, pattern, etc.) are ignored + * (this is usually used as part of the auto created OTP or OAuth2 user flows). + */ + setRandomPassword(): string + } + interface Record { + /** + * ValidatePassword validates a plain password against the "password" record field. + * + * Returns false if the password is incorrect. + */ + validatePassword(password: string): boolean + } + interface Record { + /** + * IsSuperuser returns whether the current record is a superuser, aka. + * whether the record is from the _superusers collection. + */ + isSuperuser(): boolean + } + /** + * RecordProxy defines an interface for a Record proxy/project model, + * aka. custom model struct that acts on behalve the proxied Record to + * allow for example typed getter/setters for the Record fields. + * + * To implement the interface it is usually enough to embed the [BaseRecordProxy] struct. + */ + interface RecordProxy { + [key:string]: any; + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + /** + * BaseRecordProxy implements the [RecordProxy] interface and it is intended + * to be used as embed to custom user provided Record proxy structs. + */ + type _sxoMzyO = Record + interface BaseRecordProxy extends _sxoMzyO { + } + interface BaseRecordProxy { + /** + * ProxyRecord returns the proxied Record model. + */ + proxyRecord(): (Record) + } + interface BaseRecordProxy { + /** + * SetProxyRecord loads the specified record model into the current proxy. + */ + setProxyRecord(record: Record): void + } + interface BaseApp { + /** + * RecordQuery returns a new Record select query from a collection model, id or name. + * + * In case a collection id or name is provided and that collection doesn't + * actually exists, the generated query will be created with a cancelled context + * and will fail once an executor (Row(), One(), All(), etc.) is called. + */ + recordQuery(collectionModelOrIdentifier: any): (dbx.SelectQuery) + } + interface BaseApp { + /** + * FindRecordById finds the Record model by its id. + */ + findRecordById(collectionModelOrIdentifier: any, recordId: string, ...optFilters: ((q: dbx.SelectQuery) => void)[]): (Record) + } + interface BaseApp { + /** + * FindRecordsByIds finds all records by the specified ids. + * If no records are found, returns an empty slice. + */ + findRecordsByIds(collectionModelOrIdentifier: any, recordIds: Array, ...optFilters: ((q: dbx.SelectQuery) => void)[]): Array<(Record | undefined)> + } + interface BaseApp { + /** + * FindAllRecords finds all records matching specified db expressions. + * + * Returns all collection records if no expression is provided. + * + * Returns an empty slice if no records are found. + * + * Example: + * + * ``` + * // no extra expressions + * app.FindAllRecords("example") + * + * // with extra expressions + * expr1 := dbx.HashExp{"email": "test@example.com"} + * expr2 := dbx.NewExp("LOWER(username) = {:username}", dbx.Params{"username": "test"}) + * app.FindAllRecords("example", expr1, expr2) + * ``` + */ + findAllRecords(collectionModelOrIdentifier: any, ...exprs: dbx.Expression[]): Array<(Record | undefined)> + } + interface BaseApp { + /** + * FindFirstRecordByData returns the first found record matching + * the provided key-value pair. + */ + findFirstRecordByData(collectionModelOrIdentifier: any, key: string, value: any): (Record) + } + interface BaseApp { + /** + * FindRecordsByFilter returns limit number of records matching the + * provided string filter. + * + * NB! Use the last "params" argument to bind untrusted user variables! + * + * The filter argument is optional and can be empty string to target + * all available records. + * + * The sort argument is optional and can be empty string OR the same format + * used in the web APIs, ex. "-created,title". + * + * If the limit argument is <= 0, no limit is applied to the query and + * all matching records are returned. + * + * Returns an empty slice if no records are found. + * + * Example: + * + * ``` + * app.FindRecordsByFilter( + * "posts", + * "title ~ {:title} && visible = {:visible}", + * "-created", + * 10, + * 0, + * dbx.Params{"title": "lorem ipsum", "visible": true} + * ) + * ``` + */ + findRecordsByFilter(collectionModelOrIdentifier: any, filter: string, sort: string, limit: number, offset: number, ...params: dbx.Params[]): Array<(Record | undefined)> + } + interface BaseApp { + /** + * FindFirstRecordByFilter returns the first available record matching the provided filter (if any). + * + * NB! Use the last params argument to bind untrusted user variables! + * + * Returns sql.ErrNoRows if no record is found. + * + * Example: + * + * ``` + * app.FindFirstRecordByFilter("posts", "") + * app.FindFirstRecordByFilter("posts", "slug={:slug} && status='public'", dbx.Params{"slug": "test"}) + * ``` + */ + findFirstRecordByFilter(collectionModelOrIdentifier: any, filter: string, ...params: dbx.Params[]): (Record) + } + interface BaseApp { + /** + * CountRecords returns the total number of records in a collection. + */ + countRecords(collectionModelOrIdentifier: any, ...exprs: dbx.Expression[]): number + } + interface BaseApp { + /** + * FindAuthRecordByToken finds the auth record associated with the provided JWT + * (auth, file, verifyEmail, changeEmail, passwordReset types). + * + * Optionally specify a list of validTypes to check tokens only from those types. + * + * Returns an error if the JWT is invalid, expired or not associated to an auth collection record. + */ + findAuthRecordByToken(token: string, ...validTypes: string[]): (Record) + } + interface BaseApp { + /** + * FindAuthRecordByEmail finds the auth record associated with the provided email. + * + * The email check would be case-insensitive if the related collection + * email unique index has COLLATE NOCASE specified for the email column. + * + * Returns an error if it is not an auth collection or the record is not found. + */ + findAuthRecordByEmail(collectionModelOrIdentifier: any, email: string): (Record) + } + interface BaseApp { + /** + * CanAccessRecord checks if a record is allowed to be accessed by the + * specified requestInfo and accessRule. + * + * Rule and db checks are ignored in case requestInfo.Auth is a superuser. + * + * The returned error indicate that something unexpected happened during + * the check (eg. invalid rule or db query error). + * + * The method always return false on invalid rule or db query error. + * + * Example: + * + * ``` + * requestInfo, _ := e.RequestInfo() + * record, _ := app.FindRecordById("example", "RECORD_ID") + * rule := types.Pointer("@request.auth.id != '' || status = 'public'") + * // ... or use one of the record collection's rule, eg. record.Collection().ViewRule + * + * if ok, _ := app.CanAccessRecord(record, requestInfo, rule); ok { ... } + * ``` + */ + canAccessRecord(record: Record, requestInfo: RequestInfo, accessRule: string): boolean + } + /** + * ExpandFetchFunc defines the function that is used to fetch the expanded relation records. + */ + interface ExpandFetchFunc {(relCollection: Collection, relIds: Array): Array<(Record | undefined)> } + interface BaseApp { + /** + * ExpandRecord expands the relations of a single Record model. + * + * If optFetchFunc is not set, then a default function will be used + * that returns all relation records. + * + * Returns a map with the failed expand parameters and their errors. + */ + expandRecord(record: Record, expands: Array, optFetchFunc: ExpandFetchFunc): _TygojaDict + } + interface BaseApp { + /** + * ExpandRecords expands the relations of the provided Record models list. + * + * If optFetchFunc is not set, then a default function will be used + * that returns all relation records. + * + * Returns a map with the failed expand parameters and their errors. + */ + expandRecords(records: Array<(Record | undefined)>, expands: Array, optFetchFunc: ExpandFetchFunc): _TygojaDict + } + interface Record { + /** + * NewStaticAuthToken generates and returns a new static record authentication token. + * + * Static auth tokens are similar to the regular auth tokens, but are + * non-refreshable and support custom duration. + * + * Zero or negative duration will fallback to the duration from the auth collection settings. + */ + newStaticAuthToken(duration: time.Duration): string + } + interface Record { + /** + * NewAuthToken generates and returns a new record authentication token. + */ + newAuthToken(): string + } + interface Record { + /** + * NewVerificationToken generates and returns a new record verification token. + */ + newVerificationToken(): string + } + interface Record { + /** + * NewPasswordResetToken generates and returns a new auth record password reset request token. + */ + newPasswordResetToken(): string + } + interface Record { + /** + * NewEmailChangeToken generates and returns a new auth record change email request token. + */ + newEmailChangeToken(newEmail: string): string + } + interface Record { + /** + * NewFileToken generates and returns a new record private file access token. + */ + newFileToken(): string + } + interface settings { + smtp: SMTPConfig + backups: BackupsConfig + s3: S3Config + meta: MetaConfig + rateLimits: RateLimitsConfig + trustedProxy: TrustedProxyConfig + batch: BatchConfig + logs: LogsConfig + } + /** + * Settings defines the PocketBase app settings. + */ + type _sRnLRaV = settings + interface Settings extends _sRnLRaV { + } + interface Settings { + /** + * TableName implements [Model.TableName] interface method. + */ + tableName(): string + } + interface Settings { + /** + * PK implements [Model.LastSavedPK] interface method. + */ + lastSavedPK(): any + } + interface Settings { + /** + * PK implements [Model.PK] interface method. + */ + pk(): any + } + interface Settings { + /** + * IsNew implements [Model.IsNew] interface method. + */ + isNew(): boolean + } + interface Settings { + /** + * MarkAsNew implements [Model.MarkAsNew] interface method. + */ + markAsNew(): void + } + interface Settings { + /** + * MarkAsNew implements [Model.MarkAsNotNew] interface method. + */ + markAsNotNew(): void + } + interface Settings { + /** + * PostScan implements [Model.PostScan] interface method. + */ + postScan(): void + } + interface Settings { + /** + * String returns a serialized string representation of the current settings. + */ + string(): string + } + interface Settings { + /** + * DBExport prepares and exports the current settings for db persistence. + */ + dbExport(app: App): _TygojaDict + } + interface Settings { + /** + * PostValidate implements the [PostValidator] interface and defines + * the Settings model validations. + */ + postValidate(ctx: context.Context, app: App): void + } + interface Settings { + /** + * Merge merges the "other" settings into the current one. + */ + merge(other: Settings): void + } + interface Settings { + /** + * Clone creates a new deep copy of the current settings. + */ + clone(): (Settings) + } + interface Settings { + /** + * MarshalJSON implements the [json.Marshaler] interface. + * + * Note that sensitive fields (S3 secret, SMTP password, etc.) are excluded. + */ + marshalJSON(): string|Array + } + interface SMTPConfig { + enabled: boolean + port: number + host: string + username: string + password: string + /** + * SMTP AUTH - PLAIN (default) or LOGIN + */ + authMethod: string + /** + * Whether to enforce TLS encryption for the mail server connection. + * + * When set to false StartTLS command is send, leaving the server + * to decide whether to upgrade the connection or not. + */ + tls: boolean + /** + * LocalName is optional domain name or IP address used for the + * EHLO/HELO exchange (if not explicitly set, defaults to "localhost"). + * + * This is required only by some SMTP servers, such as Gmail SMTP-relay. + */ + localName: string + } + interface SMTPConfig { + /** + * Validate makes SMTPConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface S3Config { + enabled: boolean + bucket: string + region: string + endpoint: string + accessKey: string + secret: string + forcePathStyle: boolean + } + interface S3Config { + /** + * Validate makes S3Config validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface BatchConfig { + enabled: boolean + /** + * MaxRequests is the maximum allowed batch request to execute. + */ + maxRequests: number + /** + * Timeout is the the max duration in seconds to wait before cancelling the batch transaction. + */ + timeout: number + /** + * MaxBodySize is the maximum allowed batch request body size in bytes. + * + * If not set, fallbacks to max ~128MB. + */ + maxBodySize: number + } + interface BatchConfig { + /** + * Validate makes BatchConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface BackupsConfig { + /** + * Cron is a cron expression to schedule auto backups, eg. "* * * * *". + * + * Leave it empty to disable the auto backups functionality. + */ + cron: string + /** + * CronMaxKeep is the the max number of cron generated backups to + * keep before removing older entries. + * + * This field works only when the cron config has valid cron expression. + */ + cronMaxKeep: number + /** + * S3 is an optional S3 storage config specifying where to store the app backups. + */ + s3: S3Config + } + interface BackupsConfig { + /** + * Validate makes BackupsConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface MetaConfig { + appName: string + appURL: string + senderName: string + senderAddress: string + hideControls: boolean + } + interface MetaConfig { + /** + * Validate makes MetaConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface LogsConfig { + maxDays: number + minLevel: number + logIP: boolean + logAuthId: boolean + } + interface LogsConfig { + /** + * Validate makes LogsConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface TrustedProxyConfig { + /** + * Headers is a list of explicit trusted header(s) to check. + */ + headers: Array + /** + * UseLeftmostIP specifies to use the left-mostish IP from the trusted headers. + * + * Note that this could be insecure when used with X-Forwarded-For header + * because some proxies like AWS ELB allow users to prepend their own header value + * before appending the trusted ones. + */ + useLeftmostIP: boolean + } + interface TrustedProxyConfig { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface TrustedProxyConfig { + /** + * Validate makes RateLimitRule validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface RateLimitsConfig { + rules: Array + enabled: boolean + } + interface RateLimitsConfig { + /** + * FindRateLimitRule returns the first matching rule based on the provided labels. + * + * Optionally you can further specify a list of valid RateLimitRule.Audience values to further filter the matching rule + * (aka. the rule Audience will have to exist in one of the specified options). + */ + findRateLimitRule(searchLabels: Array, ...optOnlyAudience: string[]): [RateLimitRule, boolean] + } + interface RateLimitsConfig { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface RateLimitsConfig { + /** + * Validate makes RateLimitsConfig validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface RateLimitRule { + /** + * Label is the identifier of the current rule. + * + * It could be a tag, complete path or path prerefix (when ends with `/`). + * + * Example supported labels: + * ``` + * - test_a (plain text "tag") + * - users:create + * - *:create + * - / + * - /api + * - POST /api/collections/ + * ``` + */ + label: string + /** + * Audience specifies the auth group the rule should apply for: + * ``` + * - "" - both guests and authenticated users (default) + * - "@guest" - only for guests + * - "@auth" - only for authenticated users + * ``` + */ + audience: string + /** + * Duration specifies the interval (in seconds) per which to reset + * the counted/accumulated rate limiter tokens. + */ + duration: number + /** + * MaxRequests is the max allowed number of requests per Duration. + */ + maxRequests: number + } + interface RateLimitRule { + /** + * Validate makes RateLimitRule validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface RateLimitRule { + /** + * DurationTime returns the tag's Duration as [time.Duration]. + */ + durationTime(): time.Duration + } + interface RateLimitRule { + /** + * String returns a string representation of the rule. + */ + string(): string + } + type _srLVmcx = BaseModel + interface Param extends _srLVmcx { + created: types.DateTime + updated: types.DateTime + value: types.JSONRaw + } + interface Param { + tableName(): string + } + interface BaseApp { + /** + * ReloadSettings initializes and reloads the stored application settings. + * + * If no settings were stored it will persist the current app ones. + */ + reloadSettings(): void + } + interface BaseApp { + /** + * DeleteView drops the specified view name. + * + * This method is a no-op if a view with the provided name doesn't exist. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "name" argument must come only from trusted input! + */ + deleteView(name: string): void + } + interface BaseApp { + /** + * SaveView creates (or updates already existing) persistent SQL view. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "selectQuery" argument must come only from trusted input! + */ + saveView(name: string, selectQuery: string): void + } + interface BaseApp { + /** + * CreateViewFields creates a new FieldsList from the provided select query. + * + * There are some caveats: + * - The select query must have an "id" column. + * - Wildcard ("*") columns are not supported to avoid accidentally leaking sensitive data. + */ + createViewFields(selectQuery: string): FieldsList + } + interface BaseApp { + /** + * FindRecordByViewFile returns the original Record of the provided view collection file. + */ + findRecordByViewFile(viewCollectionModelOrIdentifier: any, fileFieldName: string, filename: string): (Record) + } + interface queryField { + } + interface identifier { + } + interface identifiersParser { + } +} + +/** + * Package mails implements various helper methods for sending common + * emails like forgotten password, verification, etc. + */ +namespace mails { + interface sendRecordAuthAlert { + /** + * SendRecordAuthAlert sends a new device login alert to the specified auth record. + */ + (app: CoreApp, authRecord: core.Record): void + } + interface sendRecordOTP { + /** + * SendRecordOTP sends OTP email to the specified auth record. + * + * This method will also update the "sentTo" field of the related OTP record to the mail sent To address (if the OTP exists and not already assigned). + */ + (app: CoreApp, authRecord: core.Record, otpId: string, pass: string): void + } + interface sendRecordPasswordReset { + /** + * SendRecordPasswordReset sends a password reset request email to the specified auth record. + */ + (app: CoreApp, authRecord: core.Record): void + } + interface sendRecordVerification { + /** + * SendRecordVerification sends a verification request email to the specified auth record. + */ + (app: CoreApp, authRecord: core.Record): void + } + interface sendRecordChangeEmail { + /** + * SendRecordChangeEmail sends a change email confirmation email to the specified auth record. + */ + (app: CoreApp, authRecord: core.Record, newEmail: string): void + } +} + +namespace forms { + // @ts-ignore + import validation = ozzo_validation + /** + * AppleClientSecretCreate is a form struct to generate a new Apple Client Secret. + * + * Reference: https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens + */ + interface AppleClientSecretCreate { + /** + * ClientId is the identifier of your app (aka. Service ID). + */ + clientId: string + /** + * TeamId is a 10-character string associated with your developer account + * (usually could be found next to your name in the Apple Developer site). + */ + teamId: string + /** + * KeyId is a 10-character key identifier generated for the "Sign in with Apple" + * private key associated with your developer account. + */ + keyId: string + /** + * PrivateKey is the private key associated to your app. + * Usually wrapped within -----BEGIN PRIVATE KEY----- X -----END PRIVATE KEY-----. + */ + privateKey: string + /** + * Duration specifies how long the generated JWT should be considered valid. + * The specified value must be in seconds and max 15777000 (~6months). + */ + duration: number + } + interface newAppleClientSecretCreate { + /** + * NewAppleClientSecretCreate creates a new [AppleClientSecretCreate] form with initializer + * config created from the provided [CoreApp] instances. + */ + (app: CoreApp): (AppleClientSecretCreate) + } + interface AppleClientSecretCreate { + /** + * Validate makes the form validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface AppleClientSecretCreate { + /** + * Submit validates the form and returns a new Apple Client Secret JWT. + */ + submit(): string + } + interface RecordUpsert { + } + interface newRecordUpsert { + /** + * NewRecordUpsert creates a new [RecordUpsert] form from the provided [CoreApp] and [core.Record] instances + * (for create you could pass a pointer to an empty Record - core.NewRecord(collection)). + */ + (app: CoreApp, record: core.Record): (RecordUpsert) + } + interface RecordUpsert { + /** + * SetContext assigns ctx as context of the current form. + */ + setContext(ctx: context.Context): void + } + interface RecordUpsert { + /** + * SetApp replaces the current form app instance. + * + * This could be used for example if you want to change at later stage + * before submission to change from regular -> transactional app instance. + */ + setApp(app: CoreApp): void + } + interface RecordUpsert { + /** + * SetRecord replaces the current form record instance. + */ + setRecord(record: core.Record): void + } + interface RecordUpsert { + /** + * ResetAccess resets the form access level to the accessLevelDefault. + */ + resetAccess(): void + } + interface RecordUpsert { + /** + * GrantManagerAccess updates the form access level to "manager" allowing + * directly changing some system record fields (often used with auth collection records). + */ + grantManagerAccess(): void + } + interface RecordUpsert { + /** + * GrantSuperuserAccess updates the form access level to "superuser" allowing + * directly changing all system record fields, including those marked as "Hidden". + */ + grantSuperuserAccess(): void + } + interface RecordUpsert { + /** + * HasManageAccess reports whether the form has "manager" or "superuser" level access. + */ + hasManageAccess(): boolean + } + interface RecordUpsert { + /** + * Load loads the provided data into the form and the related record. + */ + load(data: _TygojaDict): void + } + interface RecordUpsert { + /** + * Deprecated: It was previously used as part of the record create action but it is not needed anymore and will be removed in the future. + * + * DrySubmit performs a temp form submit within a transaction and reverts it at the end. + * For actual record persistence, check the [RecordUpsert.Submit()] method. + * + * This method doesn't perform validations, handle file uploads/deletes or trigger app save events! + */ + drySubmit(callback: (txApp: CoreApp, drySavedRecord: core.Record) => void): void + } + interface RecordUpsert { + /** + * Submit validates the form specific validations and attempts to save the form record. + */ + submit(): void + } + /** + * TestEmailSend is a email template test request form. + */ + interface TestEmailSend { + email: string + template: string + collection: string // optional, fallbacks to _superusers + } + interface newTestEmailSend { + /** + * NewTestEmailSend creates and initializes new TestEmailSend form. + */ + (app: CoreApp): (TestEmailSend) + } + interface TestEmailSend { + /** + * Validate makes the form validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface TestEmailSend { + /** + * Submit validates and sends a test email to the form.Email address. + */ + submit(): void + } + /** + * TestS3Filesystem defines a S3 filesystem connection test. + */ + interface TestS3Filesystem { + /** + * The name of the filesystem - storage or backups + */ + filesystem: string + } + interface newTestS3Filesystem { + /** + * NewTestS3Filesystem creates and initializes new TestS3Filesystem form. + */ + (app: CoreApp): (TestS3Filesystem) + } + interface TestS3Filesystem { + /** + * Validate makes the form validatable by implementing [validation.Validatable] interface. + */ + validate(): void + } + interface TestS3Filesystem { + /** + * Submit validates and performs a S3 filesystem connection test. + */ + submit(): void + } +} + +namespace apis { + interface toApiError { + /** + * ToApiError wraps err into ApiError instance (if not already). + */ + (err: Error): (router.ApiError) + } + interface newApiError { + /** + * NewApiError is an alias for [router.NewApiError]. + */ + (status: number, message: string, errData: any): (router.ApiError) + } + interface newBadRequestError { + /** + * NewBadRequestError is an alias for [router.NewBadRequestError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface newNotFoundError { + /** + * NewNotFoundError is an alias for [router.NewNotFoundError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface newForbiddenError { + /** + * NewForbiddenError is an alias for [router.NewForbiddenError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface newUnauthorizedError { + /** + * NewUnauthorizedError is an alias for [router.NewUnauthorizedError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface newTooManyRequestsError { + /** + * NewTooManyRequestsError is an alias for [router.NewTooManyRequestsError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface newInternalServerError { + /** + * NewInternalServerError is an alias for [router.NewInternalServerError]. + */ + (message: string, errData: any): (router.ApiError) + } + interface backupFileInfo { + modified: types.DateTime + key: string + size: number + } + // @ts-ignore + import validation = ozzo_validation + interface backupCreateForm { + name: string + } + interface backupUploadForm { + file?: filesystem.File + } + interface newRouter { + /** + * NewRouter returns a new router instance loaded with the default app middlewares and api routes. + */ + (app: CoreApp): (router.Router) + } + interface wrapStdHandler { + /** + * WrapStdHandler wraps Go [http.Handler] into a PocketBase handler func. + */ + (h: http.Handler): (_arg0: core.RequestEvent) => void + } + interface wrapStdMiddleware { + /** + * WrapStdMiddleware wraps Go [func(http.Handler) http.Handle] into a PocketBase middleware func. + */ + (m: (_arg0: http.Handler) => http.Handler): (_arg0: core.RequestEvent) => void + } + interface mustSubFS { + /** + * MustSubFS returns an [fs.FS] corresponding to the subtree rooted at fsys's dir. + * + * This is similar to [fs.Sub] but panics on failure. + */ + (fsys: fs.FS, dir: string): fs.FS + } + interface _static { + /** + * Static is a handler function to serve static directory content from fsys. + * + * If a file resource is missing and indexFallback is set, the request + * will be forwarded to the base index.html (useful for SPA with pretty urls). + * + * NB! Expects the route to have a "{path...}" wildcard parameter. + * + * Special redirects: + * ``` + * - if "path" is a file that ends in index.html, it is redirected to its non-index.html version (eg. /test/index.html -> /test/) + * - if "path" is a directory that has index.html, the index.html file is rendered, + * otherwise if missing - returns 404 or fallback to the root index.html if indexFallback is set + * ``` + * + * Example: + * + * ``` + * fsys := os.DirFS("./pb_public") + * router.GET("/files/{path...}", apis.Static(fsys, false)) + * ``` + */ + (fsys: fs.FS, indexFallback: boolean): (_arg0: core.RequestEvent) => void + } + interface HandleFunc {(e: core.RequestEvent): void } + interface BatchActionHandlerFunc {(app: CoreApp, ir: core.InternalRequest, params: _TygojaDict, next: (data: any) => void): HandleFunc } + interface BatchRequestResult { + body: any + status: number + } + interface batchRequestsForm { + requests: Array<(core.InternalRequest | undefined)> + } + interface batchProcessor { + } + interface batchProcessor { + process(batch: Array<(core.InternalRequest | undefined)>, timeout: time.Duration): void + } + interface BatchResponseError { + } + interface BatchResponseError { + error(): string + } + interface BatchResponseError { + code(): string + } + interface BatchResponseError { + resolve(errData: _TygojaDict): any + } + interface BatchResponseError { + marshalJSON(): string|Array + } + interface collectionsImportForm { + collections: Array<_TygojaDict> + deleteMissing: boolean + } + interface fileApi { + } + interface defaultInstallerFunc { + /** + * DefaultInstallerFunc is the default PocketBase installer function. + * + * It will attempt to open a link in the browser (with a short-lived auth + * token for the systemSuperuser) to the installer UI so that users can + * create their own custom superuser record. + * + * See https://github.com/pocketbase/pocketbase/discussions/5814. + */ + (app: CoreApp, systemSuperuser: core.Record, baseURL: string): void + } + interface requireGuestOnly { + /** + * RequireGuestOnly middleware requires a request to NOT have a valid + * Authorization header. + * + * This middleware is the opposite of [apis.RequireAuth()]. + */ + (): (hook.Handler) + } + interface requireAuth { + /** + * RequireAuth middleware requires a request to have a valid record Authorization header. + * + * The auth record could be from any collection. + * You can further filter the allowed record auth collections by specifying their names. + * + * Example: + * + * ``` + * apis.RequireAuth() // any auth collection + * apis.RequireAuth("_superusers", "users") // only the listed auth collections + * ``` + */ + (...optCollectionNames: string[]): (hook.Handler) + } + interface requireSuperuserAuth { + /** + * RequireSuperuserAuth middleware requires a request to have + * a valid superuser Authorization header. + */ + (): (hook.Handler) + } + interface requireSuperuserOrOwnerAuth { + /** + * RequireSuperuserOrOwnerAuth middleware requires a request to have + * a valid superuser or regular record owner Authorization header set. + * + * This middleware is similar to [apis.RequireAuth()] but + * for the auth record token expects to have the same id as the path + * parameter ownerIdPathParam (default to "id" if empty). + */ + (ownerIdPathParam: string): (hook.Handler) + } + interface requireSameCollectionContextAuth { + /** + * RequireSameCollectionContextAuth middleware requires a request to have + * a valid record Authorization header and the auth record's collection to + * match the one from the route path parameter (default to "collection" if collectionParam is empty). + */ + (collectionPathParam: string): (hook.Handler) + } + interface skipSuccessActivityLog { + /** + * SkipSuccessActivityLog is a helper middleware that instructs the global + * activity logger to log only requests that have failed/returned an error. + */ + (): (hook.Handler) + } + interface bodyLimit { + /** + * BodyLimit returns a middleware handler that changes the default request body size limit. + * + * If limitBytes <= 0, no limit is applied. + * + * Otherwise, if the request body size exceeds the configured limitBytes, + * it sends 413 error response. + */ + (limitBytes: number): (hook.Handler) + } + type _sgGCJGH = io.ReadCloser + interface limitedReader extends _sgGCJGH { + } + interface limitedReader { + read(b: string|Array): number + } + interface limitedReader { + reread(): void + } + /** + * CORSConfig defines the config for CORS middleware. + */ + interface CORSConfig { + /** + * AllowOrigins determines the value of the Access-Control-Allow-Origin + * response header. This header defines a list of origins that may access the + * resource. The wildcard characters '*' and '?' are supported and are + * converted to regex fragments '.*' and '.' accordingly. + * + * Security: use extreme caution when handling the origin, and carefully + * validate any logic. Remember that attackers may register hostile domain names. + * See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html + * + * Optional. Default value []string{"*"}. + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + */ + allowOrigins: Array + /** + * AllowOriginFunc is a custom function to validate the origin. It takes the + * origin as an argument and returns true if allowed or false otherwise. If + * an error is returned, it is returned by the handler. If this option is + * set, AllowOrigins is ignored. + * + * Security: use extreme caution when handling the origin, and carefully + * validate any logic. Remember that attackers may register hostile domain names. + * See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html + * + * Optional. + */ + allowOriginFunc: (origin: string) => boolean + /** + * AllowMethods determines the value of the Access-Control-Allow-Methods + * response header. This header specified the list of methods allowed when + * accessing the resource. This is used in response to a preflight request. + * + * Optional. Default value DefaultCORSConfig.AllowMethods. + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods + */ + allowMethods: Array + /** + * AllowHeaders determines the value of the Access-Control-Allow-Headers + * response header. This header is used in response to a preflight request to + * indicate which HTTP headers can be used when making the actual request. + * + * Optional. Default value []string{}. + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers + */ + allowHeaders: Array + /** + * AllowCredentials determines the value of the + * Access-Control-Allow-Credentials response header. This header indicates + * whether or not the response to the request can be exposed when the + * credentials mode (Request.credentials) is true. When used as part of a + * response to a preflight request, this indicates whether or not the actual + * request can be made using credentials. See also + * [MDN: Access-Control-Allow-Credentials]. + * + * Optional. Default value false, in which case the header is not set. + * + * Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`. + * See "Exploiting CORS misconfigurations for Bitcoins and bounties", + * https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials + */ + allowCredentials: boolean + /** + * UnsafeWildcardOriginWithAllowCredentials UNSAFE/INSECURE: allows wildcard '*' origin to be used with AllowCredentials + * flag. In that case we consider any origin allowed and send it back to the client with `Access-Control-Allow-Origin` header. + * + * This is INSECURE and potentially leads to [cross-origin](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties) + * attacks. See: https://github.com/labstack/echo/issues/2400 for discussion on the subject. + * + * Optional. Default value is false. + */ + unsafeWildcardOriginWithAllowCredentials: boolean + /** + * ExposeHeaders determines the value of Access-Control-Expose-Headers, which + * defines a list of headers that clients are allowed to access. + * + * Optional. Default value []string{}, in which case the header is not set. + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header + */ + exposeHeaders: Array + /** + * MaxAge determines the value of the Access-Control-Max-Age response header. + * This header indicates how long (in seconds) the results of a preflight + * request can be cached. + * The header is set only if MaxAge != 0, negative value sends "0" which instructs browsers not to cache that response. + * + * Optional. Default value 0 - meaning header is not sent. + * + * See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age + */ + maxAge: number + } + interface cors { + /** + * CORS returns a CORS middleware. + */ + (config: CORSConfig): (hook.Handler) + } + /** + * GzipConfig defines the config for Gzip middleware. + */ + interface GzipConfig { + /** + * Gzip compression level. + * Optional. Default value -1. + */ + level: number + /** + * Length threshold before gzip compression is applied. + * Optional. Default value 0. + * + * Most of the time you will not need to change the default. Compressing + * a short response might increase the transmitted data because of the + * gzip format overhead. Compressing the response will also consume CPU + * and time on the server and the client (for decompressing). Depending on + * your use case such a threshold might be useful. + * + * See also: + * https://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits + */ + minLength: number + } + interface gzip { + /** + * Gzip returns a middleware which compresses HTTP response using Gzip compression scheme. + */ + (): (hook.Handler) + } + interface gzipWithConfig { + /** + * GzipWithConfig returns a middleware which compresses HTTP response using gzip compression scheme. + */ + (config: GzipConfig): (hook.Handler) + } + type _szvGyiW = http.ResponseWriter&io.Writer + interface gzipResponseWriter extends _szvGyiW { + } + interface gzipResponseWriter { + writeHeader(code: number): void + } + interface gzipResponseWriter { + write(b: string|Array): number + } + interface gzipResponseWriter { + flush(): void + } + interface gzipResponseWriter { + hijack(): [net.Conn, (bufio.ReadWriter)] + } + interface gzipResponseWriter { + push(target: string, opts: http.PushOptions): void + } + interface gzipResponseWriter { + unwrap(): http.ResponseWriter + } + type _sGuNRIn = sync.RWMutex + interface rateLimiter extends _sGuNRIn { + } + type _sOQsqyW = sync.Mutex + interface fixedWindow extends _sOQsqyW { + } + interface realtimeSubscribeForm { + clientId: string + subscriptions: Array + } + /** + * recordData represents the broadcasted record subscrition message data. + */ + interface recordData { + record: any // map or core.Record + action: string + } + interface EmailChangeConfirmForm { + token: string + password: string + } + interface emailChangeRequestForm { + newEmail: string + } + interface impersonateForm { + /** + * Duration is the optional custom token duration in seconds. + */ + duration: number + } + interface otpResponse { + enabled: boolean + duration: number // in seconds + } + interface mfaResponse { + enabled: boolean + duration: number // in seconds + } + interface passwordResponse { + identityFields: Array + enabled: boolean + } + interface oauth2Response { + providers: Array + enabled: boolean + } + interface providerInfo { + name: string + displayName: string + state: string + authURL: string + /** + * @todo + * deprecated: use AuthURL instead + * AuthUrl will be removed after dropping v0.22 support + */ + authUrl: string + /** + * technically could be omitted if the provider doesn't support PKCE, + * but to avoid breaking existing typed clients we'll return them as empty string + */ + codeVerifier: string + codeChallenge: string + codeChallengeMethod: string + } + interface authMethodsResponse { + password: passwordResponse + oauth2: oauth2Response + mfa: mfaResponse + otp: otpResponse + /** + * legacy fields + * @todo remove after dropping v0.22 support + */ + authProviders: Array + usernamePassword: boolean + emailPassword: boolean + } + interface createOTPForm { + email: string + } + interface recordConfirmPasswordResetForm { + token: string + password: string + passwordConfirm: string + } + interface recordRequestPasswordResetForm { + email: string + } + interface recordConfirmVerificationForm { + token: string + } + interface recordRequestVerificationForm { + email: string + } + interface recordOAuth2LoginForm { + /** + * Additional data that will be used for creating a new auth record + * if an existing OAuth2 account doesn't exist. + */ + createData: _TygojaDict + /** + * The name of the OAuth2 client provider (eg. "google") + */ + provider: string + /** + * The authorization code returned from the initial request. + */ + code: string + /** + * The optional PKCE code verifier as part of the code_challenge sent with the initial request. + */ + codeVerifier: string + /** + * The redirect url sent with the initial request. + */ + redirectURL: string + /** + * @todo + * deprecated: use RedirectURL instead + * RedirectUrl will be removed after dropping v0.22 support + */ + redirectUrl: string + } + interface oauth2RedirectData { + state: string + code: string + error: string + /** + * returned by Apple only + */ + appleUser: string + } + interface authWithOTPForm { + otpId: string + password: string + } + interface authWithPasswordForm { + identity: string + password: string + /** + * IdentityField specifies the field to use to search for the identity + * (leave it empty for "auto" detection). + */ + identityField: string + } + // @ts-ignore + import cryptoRand = rand + interface recordAuthResponse { + /** + * RecordAuthResponse writes standardized json record auth response + * into the specified request context. + * + * The authMethod argument specify the name of the current authentication method (eg. password, oauth2, etc.) + * that it is used primarily as an auth identifier during MFA and for login alerts. + * + * Set authMethod to empty string if you want to ignore the MFA checks and the login alerts + * (can be also adjusted additionally via the OnRecordAuthRequest hook). + */ + (e: core.RequestEvent, authRecord: core.Record, authMethod: string, meta: any): void + } + interface enrichRecord { + /** + * EnrichRecord parses the request context and enrich the provided record: + * ``` + * - expands relations (if defaultExpands and/or ?expand query param is set) + * - ensures that the emails of the auth record and its expanded auth relations + * are visible only for the current logged superuser, record owner or record with manage access + * ``` + */ + (e: core.RequestEvent, record: core.Record, ...defaultExpands: string[]): void + } + interface enrichRecords { + /** + * EnrichRecords parses the request context and enriches the provided records: + * ``` + * - expands relations (if defaultExpands and/or ?expand query param is set) + * - ensures that the emails of the auth records and their expanded auth relations + * are visible only for the current logged superuser, record owner or record with manage access + * ``` + * + * Note: Expects all records to be from the same collection! + */ + (e: core.RequestEvent, records: Array<(core.Record | undefined)>, ...defaultExpands: string[]): void + } + interface iterator { + } + /** + * ServeConfig defines a configuration struct for apis.Serve(). + */ + interface ServeConfig { + /** + * ShowStartBanner indicates whether to show or hide the server start console message. + */ + showStartBanner: boolean + /** + * HttpAddr is the TCP address to listen for the HTTP server (eg. "127.0.0.1:80"). + */ + httpAddr: string + /** + * HttpsAddr is the TCP address to listen for the HTTPS server (eg. "127.0.0.1:443"). + */ + httpsAddr: string + /** + * Optional domains list to use when issuing the TLS certificate. + * + * If not set, the host from the bound server address will be used. + * + * For convenience, for each "non-www" domain a "www" entry and + * redirect will be automatically added. + */ + certificateDomains: Array + /** + * AllowedOrigins is an optional list of CORS origins (default to "*"). + */ + allowedOrigins: Array + } + interface serve { + /** + * Serve starts a new app web server. + * + * NB! The app should be bootstrapped before starting the web server. + * + * Example: + * + * ``` + * app.Bootstrap() + * apis.Serve(app, apis.ServeConfig{ + * HttpAddr: "127.0.0.1:8080", + * ShowStartBanner: false, + * }) + * ``` + */ + (app: CoreApp, config: ServeConfig): void + } + interface serverErrorLogWriter { + } + interface serverErrorLogWriter { + write(p: string|Array): number + } +} + +namespace pocketbase { + /** + * PocketBase defines a PocketBase app launcher. + * + * It implements [CoreApp] via embedding and all of the app interface methods + * could be accessed directly through the instance (eg. PocketBase.DataDir()). + */ + type _sEvOybl = CoreApp + interface PocketBase extends _sEvOybl { + /** + * RootCmd is the main console command + */ + rootCmd?: cobra.Command + } + /** + * Config is the PocketBase initialization config struct. + */ + interface Config { + /** + * hide the default console server info on app startup + */ + hideStartBanner: boolean + /** + * optional default values for the console flags + */ + defaultDev: boolean + defaultDataDir: string // if not set, it will fallback to "./pb_data" + defaultEncryptionEnv: string + defaultQueryTimeout: time.Duration // default to core.DefaultQueryTimeout (in seconds) + /** + * optional DB configurations + */ + dataMaxOpenConns: number // default to core.DefaultDataMaxOpenConns + dataMaxIdleConns: number // default to core.DefaultDataMaxIdleConns + auxMaxOpenConns: number // default to core.DefaultAuxMaxOpenConns + auxMaxIdleConns: number // default to core.DefaultAuxMaxIdleConns + dbConnect: core.DBConnectFunc // default to core.dbConnect + } + interface _new { + /** + * New creates a new PocketBase instance with the default configuration. + * Use [NewWithConfig] if you want to provide a custom configuration. + * + * Note that the application will not be initialized/bootstrapped yet, + * aka. DB connections, migrations, app settings, etc. will not be accessible. + * Everything will be initialized when [PocketBase.Start] is executed. + * If you want to initialize the application before calling [PocketBase.Start], + * then you'll have to manually call [PocketBase.Bootstrap]. + */ + (): (PocketBase) + } + interface newWithConfig { + /** + * NewWithConfig creates a new PocketBase instance with the provided config. + * + * Note that the application will not be initialized/bootstrapped yet, + * aka. DB connections, migrations, app settings, etc. will not be accessible. + * Everything will be initialized when [PocketBase.Start] is executed. + * If you want to initialize the application before calling [PocketBase.Start], + * then you'll have to manually call [PocketBase.Bootstrap]. + */ + (config: Config): (PocketBase) + } + interface PocketBase { + /** + * Start starts the application, aka. registers the default system + * commands (serve, superuser, version) and executes pb.RootCmd. + */ + start(): void + } + interface PocketBase { + /** + * Execute initializes the application (if not already) and executes + * the pb.RootCmd with graceful shutdown support. + * + * This method differs from pb.Start() by not registering the default + * system commands! + */ + execute(): void + } + /** + * coloredWriter is a small wrapper struct to construct a [color.Color] writter. + */ + interface coloredWriter { + } + interface coloredWriter { + /** + * Write writes the p bytes using the colored writer. + */ + write(p: string|Array): number + } +} + +/** + * Package template is a thin wrapper around the standard html/template + * and text/template packages that implements a convenient registry to + * load and cache templates on the fly concurrently. + * + * It was created to assist the JSVM plugin HTML rendering, but could be used in other Go code. + * + * Example: + * + * ``` + * registry := template.NewRegistry() + * + * html1, err := registry.LoadFiles( + * // the files set wil be parsed only once and then cached + * "layout.html", + * "content.html", + * ).Render(map[string]any{"name": "John"}) + * + * html2, err := registry.LoadFiles( + * // reuse the already parsed and cached files set + * "layout.html", + * "content.html", + * ).Render(map[string]any{"name": "Jane"}) + * ``` + */ +namespace template { + interface newRegistry { + /** + * NewRegistry creates and initializes a new templates registry with + * some defaults (eg. global "raw" template function for unescaped HTML). + * + * Use the Registry.Load* methods to load templates into the registry. + */ + (): (Registry) + } + /** + * Registry defines a templates registry that is safe to be used by multiple goroutines. + * + * Use the Registry.Load* methods to load templates into the registry. + */ + interface Registry { + } + interface Registry { + /** + * AddFuncs registers new global template functions. + * + * The key of each map entry is the function name that will be used in the templates. + * If a function with the map entry name already exists it will be replaced with the new one. + * + * The value of each map entry is a function that must have either a + * single return value, or two return values of which the second has type error. + * + * Example: + * + * ``` + * r.AddFuncs(map[string]any{ + * "toUpper": func(str string) string { + * return strings.ToUppser(str) + * }, + * ... + * }) + * ``` + */ + addFuncs(funcs: _TygojaDict): (Registry) + } + interface Registry { + /** + * LoadFiles caches (if not already) the specified filenames set as a + * single template and returns a ready to use Renderer instance. + * + * There must be at least 1 filename specified. + */ + loadFiles(...filenames: string[]): (Renderer) + } + interface Registry { + /** + * LoadString caches (if not already) the specified inline string as a + * single template and returns a ready to use Renderer instance. + */ + loadString(text: string): (Renderer) + } + interface Registry { + /** + * LoadFS caches (if not already) the specified fs and globPatterns + * pair as single template and returns a ready to use Renderer instance. + * + * There must be at least 1 file matching the provided globPattern(s) + * (note that most file names serves as glob patterns matching themselves). + */ + loadFS(fsys: fs.FS, ...globPatterns: string[]): (Renderer) + } + /** + * Renderer defines a single parsed template. + */ + interface Renderer { + } + interface Renderer { + /** + * Render executes the template with the specified data as the dot object + * and returns the result as plain string. + */ + render(data: any): string + } +} + +/** + * Package sync provides basic synchronization primitives such as mutual + * exclusion locks. Other than the [Once] and [WaitGroup] types, most are intended + * for use by low-level library routines. Higher-level synchronization is + * better done via channels and communication. + * + * Values containing the types defined in this package should not be copied. + */ +namespace sync { + // @ts-ignore + import isync = sync + /** + * A Mutex is a mutual exclusion lock. + * The zero value for a Mutex is an unlocked mutex. + * + * A Mutex must not be copied after first use. + * + * In the terminology of [the Go memory model], + * the n'th call to [Mutex.Unlock] “synchronizes before” the m'th call to [Mutex.Lock] + * for any n < m. + * A successful call to [Mutex.TryLock] is equivalent to a call to Lock. + * A failed call to TryLock does not establish any “synchronizes before” + * relation at all. + * + * [the Go memory model]: https://go.dev/ref/mem + */ + interface Mutex { + } + interface Mutex { + /** + * Lock locks m. + * If the lock is already in use, the calling goroutine + * blocks until the mutex is available. + */ + lock(): void + } + interface Mutex { + /** + * TryLock tries to lock m and reports whether it succeeded. + * + * Note that while correct uses of TryLock do exist, they are rare, + * and use of TryLock is often a sign of a deeper problem + * in a particular use of mutexes. + */ + tryLock(): boolean + } + interface Mutex { + /** + * Unlock unlocks m. + * It is a run-time error if m is not locked on entry to Unlock. + * + * A locked [Mutex] is not associated with a particular goroutine. + * It is allowed for one goroutine to lock a Mutex and then + * arrange for another goroutine to unlock it. + */ + unlock(): void + } + /** + * A RWMutex is a reader/writer mutual exclusion lock. + * The lock can be held by an arbitrary number of readers or a single writer. + * The zero value for a RWMutex is an unlocked mutex. + * + * A RWMutex must not be copied after first use. + * + * If any goroutine calls [RWMutex.Lock] while the lock is already held by + * one or more readers, concurrent calls to [RWMutex.RLock] will block until + * the writer has acquired (and released) the lock, to ensure that + * the lock eventually becomes available to the writer. + * Note that this prohibits recursive read-locking. + * A [RWMutex.RLock] cannot be upgraded into a [RWMutex.Lock], + * nor can a [RWMutex.Lock] be downgraded into a [RWMutex.RLock]. + * + * In the terminology of [the Go memory model], + * the n'th call to [RWMutex.Unlock] “synchronizes before” the m'th call to Lock + * for any n < m, just as for [Mutex]. + * For any call to RLock, there exists an n such that + * the n'th call to Unlock “synchronizes before” that call to RLock, + * and the corresponding call to [RWMutex.RUnlock] “synchronizes before” + * the n+1'th call to Lock. + * + * [the Go memory model]: https://go.dev/ref/mem + */ + interface RWMutex { + } + interface RWMutex { + /** + * RLock locks rw for reading. + * + * It should not be used for recursive read locking; a blocked Lock + * call excludes new readers from acquiring the lock. See the + * documentation on the [RWMutex] type. + */ + rLock(): void + } + interface RWMutex { + /** + * TryRLock tries to lock rw for reading and reports whether it succeeded. + * + * Note that while correct uses of TryRLock do exist, they are rare, + * and use of TryRLock is often a sign of a deeper problem + * in a particular use of mutexes. + */ + tryRLock(): boolean + } + interface RWMutex { + /** + * RUnlock undoes a single [RWMutex.RLock] call; + * it does not affect other simultaneous readers. + * It is a run-time error if rw is not locked for reading + * on entry to RUnlock. + */ + rUnlock(): void + } + interface RWMutex { + /** + * Lock locks rw for writing. + * If the lock is already locked for reading or writing, + * Lock blocks until the lock is available. + */ + lock(): void + } + interface RWMutex { + /** + * TryLock tries to lock rw for writing and reports whether it succeeded. + * + * Note that while correct uses of TryLock do exist, they are rare, + * and use of TryLock is often a sign of a deeper problem + * in a particular use of mutexes. + */ + tryLock(): boolean + } + interface RWMutex { + /** + * Unlock unlocks rw for writing. It is a run-time error if rw is + * not locked for writing on entry to Unlock. + * + * As with Mutexes, a locked [RWMutex] is not associated with a particular + * goroutine. One goroutine may [RWMutex.RLock] ([RWMutex.Lock]) a RWMutex and then + * arrange for another goroutine to [RWMutex.RUnlock] ([RWMutex.Unlock]) it. + */ + unlock(): void + } + interface RWMutex { + /** + * RLocker returns a [Locker] interface that implements + * the [Locker.Lock] and [Locker.Unlock] methods by calling rw.RLock and rw.RUnlock. + */ + rLocker(): Locker + } +} + +/** + * Package io provides basic interfaces to I/O primitives. + * Its primary job is to wrap existing implementations of such primitives, + * such as those in package os, into shared public interfaces that + * abstract the functionality, plus some other related primitives. + * + * Because these interfaces and primitives wrap lower-level operations with + * various implementations, unless otherwise informed clients should not + * assume they are safe for parallel execution. + */ +namespace io { + /** + * Reader is the interface that wraps the basic Read method. + * + * Read reads up to len(p) bytes into p. It returns the number of bytes + * read (0 <= n <= len(p)) and any error encountered. Even if Read + * returns n < len(p), it may use all of p as scratch space during the call. + * If some data is available but not len(p) bytes, Read conventionally + * returns what is available instead of waiting for more. + * + * When Read encounters an error or end-of-file condition after + * successfully reading n > 0 bytes, it returns the number of + * bytes read. It may return the (non-nil) error from the same call + * or return the error (and n == 0) from a subsequent call. + * An instance of this general case is that a Reader returning + * a non-zero number of bytes at the end of the input stream may + * return either err == EOF or err == nil. The next Read should + * return 0, EOF. + * + * Callers should always process the n > 0 bytes returned before + * considering the error err. Doing so correctly handles I/O errors + * that happen after reading some bytes and also both of the + * allowed EOF behaviors. + * + * If len(p) == 0, Read should always return n == 0. It may return a + * non-nil error if some error condition is known, such as EOF. + * + * Implementations of Read are discouraged from returning a + * zero byte count with a nil error, except when len(p) == 0. + * Callers should treat a return of 0 and nil as indicating that + * nothing happened; in particular it does not indicate EOF. + * + * Implementations must not retain p. + */ + interface Reader { + [key:string]: any; + read(p: string|Array): number + } + /** + * Writer is the interface that wraps the basic Write method. + * + * Write writes len(p) bytes from p to the underlying data stream. + * It returns the number of bytes written from p (0 <= n <= len(p)) + * and any error encountered that caused the write to stop early. + * Write must return a non-nil error if it returns n < len(p). + * Write must not modify the slice data, even temporarily. + * + * Implementations must not retain p. + */ + interface Writer { + [key:string]: any; + write(p: string|Array): number + } + /** + * ReadCloser is the interface that groups the basic Read and Close methods. + */ + interface ReadCloser { + [key:string]: any; + } + /** + * ReadSeekCloser is the interface that groups the basic Read, Seek and Close + * methods. + */ + interface ReadSeekCloser { + [key:string]: any; + } +} + +/** + * Package bytes implements functions for the manipulation of byte slices. + * It is analogous to the facilities of the [strings] package. + */ +namespace bytes { + /** + * A Reader implements the [io.Reader], [io.ReaderAt], [io.WriterTo], [io.Seeker], + * [io.ByteScanner], and [io.RuneScanner] interfaces by reading from + * a byte slice. + * Unlike a [Buffer], a Reader is read-only and supports seeking. + * The zero value for Reader operates like a Reader of an empty slice. + */ + interface Reader { + } + interface Reader { + /** + * Len returns the number of bytes of the unread portion of the + * slice. + */ + len(): number + } + interface Reader { + /** + * Size returns the original length of the underlying byte slice. + * Size is the number of bytes available for reading via [Reader.ReadAt]. + * The result is unaffected by any method calls except [Reader.Reset]. + */ + size(): number + } + interface Reader { + /** + * Read implements the [io.Reader] interface. + */ + read(b: string|Array): number + } + interface Reader { + /** + * ReadAt implements the [io.ReaderAt] interface. + */ + readAt(b: string|Array, off: number): number + } + interface Reader { + /** + * ReadByte implements the [io.ByteReader] interface. + */ + readByte(): number + } + interface Reader { + /** + * UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface. + */ + unreadByte(): void + } + interface Reader { + /** + * ReadRune implements the [io.RuneReader] interface. + */ + readRune(): [number, number] + } + interface Reader { + /** + * UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface. + */ + unreadRune(): void + } + interface Reader { + /** + * Seek implements the [io.Seeker] interface. + */ + seek(offset: number, whence: number): number + } + interface Reader { + /** + * WriteTo implements the [io.WriterTo] interface. + */ + writeTo(w: io.Writer): number + } + interface Reader { + /** + * Reset resets the [Reader] to be reading from b. + */ + reset(b: string|Array): void + } +} + +/** + * Package syscall contains an interface to the low-level operating system + * primitives. The details vary depending on the underlying system, and + * by default, godoc will display the syscall documentation for the current + * system. If you want godoc to display syscall documentation for another + * system, set $GOOS and $GOARCH to the desired system. For example, if + * you want to view documentation for freebsd/arm on linux/amd64, set $GOOS + * to freebsd and $GOARCH to arm. + * The primary use of syscall is inside other packages that provide a more + * portable interface to the system, such as "os", "time" and "net". Use + * those packages rather than this one if you can. + * For details of the functions and data types in this package consult + * the manuals for the appropriate operating system. + * These calls return err == nil to indicate success; otherwise + * err is an operating system error describing the failure. + * On most systems, that error has type [Errno]. + * + * NOTE: Most of the functions, types, and constants defined in + * this package are also available in the [golang.org/x/sys] package. + * That package has more system call support than this one, + * and most new code should prefer that package where possible. + * See https://golang.org/s/go1.4-syscall for more information. + */ +namespace syscall { + // @ts-ignore + import errpkg = errors + interface SysProcAttr { + chroot: string // Chroot. + credential?: Credential // Credential. + /** + * Ptrace tells the child to call ptrace(PTRACE_TRACEME). + * Call runtime.LockOSThread before starting a process with this set, + * and don't call UnlockOSThread until done with PtraceSyscall calls. + */ + ptrace: boolean + setsid: boolean // Create session. + /** + * Setpgid sets the process group ID of the child to Pgid, + * or, if Pgid == 0, to the new child's process ID. + */ + setpgid: boolean + /** + * Setctty sets the controlling terminal of the child to + * file descriptor Ctty. Ctty must be a descriptor number + * in the child process: an index into ProcAttr.Files. + * This is only meaningful if Setsid is true. + */ + setctty: boolean + noctty: boolean // Detach fd 0 from controlling terminal. + ctty: number // Controlling TTY fd. + /** + * Foreground places the child process group in the foreground. + * This implies Setpgid. The Ctty field must be set to + * the descriptor of the controlling TTY. + * Unlike Setctty, in this case Ctty must be a descriptor + * number in the parent process. + */ + foreground: boolean + pgid: number // Child's process group ID if Setpgid. + /** + * Pdeathsig, if non-zero, is a signal that the kernel will send to + * the child process when the creating thread dies. Note that the signal + * is sent on thread termination, which may happen before process termination. + * There are more details at https://go.dev/issue/27505. + */ + pdeathsig: Signal + cloneflags: number // Flags for clone calls. + unshareflags: number // Flags for unshare calls. + uidMappings: Array // User ID mappings for user namespaces. + gidMappings: Array // Group ID mappings for user namespaces. + /** + * GidMappingsEnableSetgroups enabling setgroups syscall. + * If false, then setgroups syscall will be disabled for the child process. + * This parameter is no-op if GidMappings == nil. Otherwise for unprivileged + * users this should be set to false for mappings work. + */ + gidMappingsEnableSetgroups: boolean + ambientCaps: Array // Ambient capabilities. + useCgroupFD: boolean // Whether to make use of the CgroupFD field. + cgroupFD: number // File descriptor of a cgroup to put the new process into. + /** + * PidFD, if not nil, is used to store the pidfd of a child, if the + * functionality is supported by the kernel, or -1. Note *PidFD is + * changed only if the process starts successfully. + */ + pidFD?: number + } + // @ts-ignore + import errorspkg = errors + /** + * A RawConn is a raw network connection. + */ + interface RawConn { + [key:string]: any; + /** + * Control invokes f on the underlying connection's file + * descriptor or handle. + * The file descriptor fd is guaranteed to remain valid while + * f executes but not after f returns. + */ + control(f: (fd: number) => void): void + /** + * Read invokes f on the underlying connection's file + * descriptor or handle; f is expected to try to read from the + * file descriptor. + * If f returns true, Read returns. Otherwise Read blocks + * waiting for the connection to be ready for reading and + * tries again repeatedly. + * The file descriptor is guaranteed to remain valid while f + * executes but not after f returns. + */ + read(f: (fd: number) => boolean): void + /** + * Write is like Read but for writing. + */ + write(f: (fd: number) => boolean): void + } + // @ts-ignore + import runtimesyscall = syscall + /** + * An Errno is an unsigned number describing an error condition. + * It implements the error interface. The zero Errno is by convention + * a non-error, so code to convert from Errno to error should use: + * + * ``` + * err = nil + * if errno != 0 { + * err = errno + * } + * ``` + * + * Errno values can be tested against error values using [errors.Is]. + * For example: + * + * ``` + * _, _, err := syscall.Syscall(...) + * if errors.Is(err, fs.ErrNotExist) ... + * ``` + */ + interface Errno extends Number{} + interface Errno { + error(): string + } + interface Errno { + is(target: Error): boolean + } + interface Errno { + temporary(): boolean + } + interface Errno { + timeout(): boolean + } +} + +/** + * Package time provides functionality for measuring and displaying time. + * + * The calendrical calculations always assume a Gregorian calendar, with + * no leap seconds. + * + * # Monotonic Clocks + * + * Operating systems provide both a “wall clock,” which is subject to + * changes for clock synchronization, and a “monotonic clock,” which is + * not. The general rule is that the wall clock is for telling time and + * the monotonic clock is for measuring time. Rather than split the API, + * in this package the Time returned by [time.Now] contains both a wall + * clock reading and a monotonic clock reading; later time-telling + * operations use the wall clock reading, but later time-measuring + * operations, specifically comparisons and subtractions, use the + * monotonic clock reading. + * + * For example, this code always computes a positive elapsed time of + * approximately 20 milliseconds, even if the wall clock is changed during + * the operation being timed: + * + * ``` + * start := time.Now() + * ... operation that takes 20 milliseconds ... + * t := time.Now() + * elapsed := t.Sub(start) + * ``` + * + * Other idioms, such as [time.Since](start), [time.Until](deadline), and + * time.Now().Before(deadline), are similarly robust against wall clock + * resets. + * + * The rest of this section gives the precise details of how operations + * use monotonic clocks, but understanding those details is not required + * to use this package. + * + * The Time returned by time.Now contains a monotonic clock reading. + * If Time t has a monotonic clock reading, t.Add adds the same duration to + * both the wall clock and monotonic clock readings to compute the result. + * Because t.AddDate(y, m, d), t.Round(d), and t.Truncate(d) are wall time + * computations, they always strip any monotonic clock reading from their results. + * Because t.In, t.Local, and t.UTC are used for their effect on the interpretation + * of the wall time, they also strip any monotonic clock reading from their results. + * The canonical way to strip a monotonic clock reading is to use t = t.Round(0). + * + * If Times t and u both contain monotonic clock readings, the operations + * t.After(u), t.Before(u), t.Equal(u), t.Compare(u), and t.Sub(u) are carried out + * using the monotonic clock readings alone, ignoring the wall clock + * readings. If either t or u contains no monotonic clock reading, these + * operations fall back to using the wall clock readings. + * + * On some systems the monotonic clock will stop if the computer goes to sleep. + * On such a system, t.Sub(u) may not accurately reflect the actual + * time that passed between t and u. The same applies to other functions and + * methods that subtract times, such as [Since], [Until], [Time.Before], [Time.After], + * [Time.Add], [Time.Equal] and [Time.Compare]. In some cases, you may need to strip + * the monotonic clock to get accurate results. + * + * Because the monotonic clock reading has no meaning outside + * the current process, the serialized forms generated by t.GobEncode, + * t.MarshalBinary, t.MarshalJSON, and t.MarshalText omit the monotonic + * clock reading, and t.Format provides no format for it. Similarly, the + * constructors [time.Date], [time.Parse], [time.ParseInLocation], and [time.Unix], + * as well as the unmarshalers t.GobDecode, t.UnmarshalBinary. + * t.UnmarshalJSON, and t.UnmarshalText always create times with + * no monotonic clock reading. + * + * The monotonic clock reading exists only in [Time] values. It is not + * a part of [Duration] values or the Unix times returned by t.Unix and + * friends. + * + * Note that the Go == operator compares not just the time instant but + * also the [Location] and the monotonic clock reading. See the + * documentation for the Time type for a discussion of equality + * testing for Time values. + * + * For debugging, the result of t.String does include the monotonic + * clock reading if present. If t != u because of different monotonic clock readings, + * that difference will be visible when printing t.String() and u.String(). + * + * # Timer Resolution + * + * [Timer] resolution varies depending on the Go runtime, the operating system + * and the underlying hardware. + * On Unix, the resolution is ~1ms. + * On Windows version 1803 and newer, the resolution is ~0.5ms. + * On older Windows versions, the default resolution is ~16ms, but + * a higher resolution may be requested using [golang.org/x/sys/windows.TimeBeginPeriod]. + */ +namespace time { + interface Time { + /** + * String returns the time formatted using the format string + * + * ``` + * "2006-01-02 15:04:05.999999999 -0700 MST" + * ``` + * + * If the time has a monotonic clock reading, the returned string + * includes a final field "m=±", where value is the monotonic + * clock reading formatted as a decimal number of seconds. + * + * The returned string is meant for debugging; for a stable serialized + * representation, use t.MarshalText, t.MarshalBinary, or t.Format + * with an explicit format string. + */ + string(): string + } + interface Time { + /** + * GoString implements [fmt.GoStringer] and formats t to be printed in Go source + * code. + */ + goString(): string + } + interface Time { + /** + * Format returns a textual representation of the time value formatted according + * to the layout defined by the argument. See the documentation for the + * constant called [Layout] to see how to represent the layout format. + * + * The executable example for [Time.Format] demonstrates the working + * of the layout string in detail and is a good reference. + */ + format(layout: string): string + } + interface Time { + /** + * AppendFormat is like [Time.Format] but appends the textual + * representation to b and returns the extended buffer. + */ + appendFormat(b: string|Array, layout: string): string|Array + } + /** + * A Time represents an instant in time with nanosecond precision. + * + * Programs using times should typically store and pass them as values, + * not pointers. That is, time variables and struct fields should be of + * type [time.Time], not *time.Time. + * + * A Time value can be used by multiple goroutines simultaneously except + * that the methods [Time.GobDecode], [Time.UnmarshalBinary], [Time.UnmarshalJSON] and + * [Time.UnmarshalText] are not concurrency-safe. + * + * Time instants can be compared using the [Time.Before], [Time.After], and [Time.Equal] methods. + * The [Time.Sub] method subtracts two instants, producing a [Duration]. + * The [Time.Add] method adds a Time and a Duration, producing a Time. + * + * The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. + * As this time is unlikely to come up in practice, the [Time.IsZero] method gives + * a simple way of detecting a time that has not been initialized explicitly. + * + * Each time has an associated [Location]. The methods [Time.Local], [Time.UTC], and Time.In return a + * Time with a specific Location. Changing the Location of a Time value with + * these methods does not change the actual instant it represents, only the time + * zone in which to interpret it. + * + * Representations of a Time value saved by the [Time.GobEncode], [Time.MarshalBinary], [Time.AppendBinary], + * [Time.MarshalJSON], [Time.MarshalText] and [Time.AppendText] methods store the [Time.Location]'s offset, + * but not the location name. They therefore lose information about Daylight Saving Time. + * + * In addition to the required “wall clock” reading, a Time may contain an optional + * reading of the current process's monotonic clock, to provide additional precision + * for comparison or subtraction. + * See the “Monotonic Clocks” section in the package documentation for details. + * + * Note that the Go == operator compares not just the time instant but also the + * Location and the monotonic clock reading. Therefore, Time values should not + * be used as map or database keys without first guaranteeing that the + * identical Location has been set for all values, which can be achieved + * through use of the UTC or Local method, and that the monotonic clock reading + * has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) + * to t == u, since t.Equal uses the most accurate comparison available and + * correctly handles the case when only one of its arguments has a monotonic + * clock reading. + */ + interface Time { + } + interface Time { + /** + * IsZero reports whether t represents the zero time instant, + * January 1, year 1, 00:00:00 UTC. + */ + isZero(): boolean + } + interface Time { + /** + * After reports whether the time instant t is after u. + */ + after(u: Time): boolean + } + interface Time { + /** + * Before reports whether the time instant t is before u. + */ + before(u: Time): boolean + } + interface Time { + /** + * Compare compares the time instant t with u. If t is before u, it returns -1; + * if t is after u, it returns +1; if they're the same, it returns 0. + */ + compare(u: Time): number + } + interface Time { + /** + * Equal reports whether t and u represent the same time instant. + * Two times can be equal even if they are in different locations. + * For example, 6:00 +0200 and 4:00 UTC are Equal. + * See the documentation on the Time type for the pitfalls of using == with + * Time values; most code should use Equal instead. + */ + equal(u: Time): boolean + } + interface Time { + /** + * Date returns the year, month, and day in which t occurs. + */ + date(): [number, Month, number] + } + interface Time { + /** + * Year returns the year in which t occurs. + */ + year(): number + } + interface Time { + /** + * Month returns the month of the year specified by t. + */ + month(): Month + } + interface Time { + /** + * Day returns the day of the month specified by t. + */ + day(): number + } + interface Time { + /** + * Weekday returns the day of the week specified by t. + */ + weekday(): Weekday + } + interface Time { + /** + * ISOWeek returns the ISO 8601 year and week number in which t occurs. + * Week ranges from 1 to 53. Jan 01 to Jan 03 of year n might belong to + * week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1 + * of year n+1. + */ + isoWeek(): [number, number] + } + interface Time { + /** + * Clock returns the hour, minute, and second within the day specified by t. + */ + clock(): [number, number, number] + } + interface Time { + /** + * Hour returns the hour within the day specified by t, in the range [0, 23]. + */ + hour(): number + } + interface Time { + /** + * Minute returns the minute offset within the hour specified by t, in the range [0, 59]. + */ + minute(): number + } + interface Time { + /** + * Second returns the second offset within the minute specified by t, in the range [0, 59]. + */ + second(): number + } + interface Time { + /** + * Nanosecond returns the nanosecond offset within the second specified by t, + * in the range [0, 999999999]. + */ + nanosecond(): number + } + interface Time { + /** + * YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years, + * and [1,366] in leap years. + */ + yearDay(): number + } + /** + * A Duration represents the elapsed time between two instants + * as an int64 nanosecond count. The representation limits the + * largest representable duration to approximately 290 years. + */ + interface Duration extends Number{} + interface Duration { + /** + * String returns a string representing the duration in the form "72h3m0.5s". + * Leading zero units are omitted. As a special case, durations less than one + * second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure + * that the leading digit is non-zero. The zero duration formats as 0s. + */ + string(): string + } + interface Duration { + /** + * Nanoseconds returns the duration as an integer nanosecond count. + */ + nanoseconds(): number + } + interface Duration { + /** + * Microseconds returns the duration as an integer microsecond count. + */ + microseconds(): number + } + interface Duration { + /** + * Milliseconds returns the duration as an integer millisecond count. + */ + milliseconds(): number + } + interface Duration { + /** + * Seconds returns the duration as a floating point number of seconds. + */ + seconds(): number + } + interface Duration { + /** + * Minutes returns the duration as a floating point number of minutes. + */ + minutes(): number + } + interface Duration { + /** + * Hours returns the duration as a floating point number of hours. + */ + hours(): number + } + interface Duration { + /** + * Truncate returns the result of rounding d toward zero to a multiple of m. + * If m <= 0, Truncate returns d unchanged. + */ + truncate(m: Duration): Duration + } + interface Duration { + /** + * Round returns the result of rounding d to the nearest multiple of m. + * The rounding behavior for halfway values is to round away from zero. + * If the result exceeds the maximum (or minimum) + * value that can be stored in a [Duration], + * Round returns the maximum (or minimum) duration. + * If m <= 0, Round returns d unchanged. + */ + round(m: Duration): Duration + } + interface Duration { + /** + * Abs returns the absolute value of d. + * As a special case, Duration([math.MinInt64]) is converted to Duration([math.MaxInt64]), + * reducing its magnitude by 1 nanosecond. + */ + abs(): Duration + } + interface Time { + /** + * Add returns the time t+d. + */ + add(d: Duration): Time + } + interface Time { + /** + * Sub returns the duration t-u. If the result exceeds the maximum (or minimum) + * value that can be stored in a [Duration], the maximum (or minimum) duration + * will be returned. + * To compute t-d for a duration d, use t.Add(-d). + */ + sub(u: Time): Duration + } + interface Time { + /** + * AddDate returns the time corresponding to adding the + * given number of years, months, and days to t. + * For example, AddDate(-1, 2, 3) applied to January 1, 2011 + * returns March 4, 2010. + * + * Note that dates are fundamentally coupled to timezones, and calendrical + * periods like days don't have fixed durations. AddDate uses the Location of + * the Time value to determine these durations. That means that the same + * AddDate arguments can produce a different shift in absolute time depending on + * the base Time value and its Location. For example, AddDate(0, 0, 1) applied + * to 12:00 on March 27 always returns 12:00 on March 28. At some locations and + * in some years this is a 24 hour shift. In others it's a 23 hour shift due to + * daylight savings time transitions. + * + * AddDate normalizes its result in the same way that Date does, + * so, for example, adding one month to October 31 yields + * December 1, the normalized form for November 31. + */ + addDate(years: number, months: number, days: number): Time + } + interface Time { + /** + * UTC returns t with the location set to UTC. + */ + utc(): Time + } + interface Time { + /** + * Local returns t with the location set to local time. + */ + local(): Time + } + interface Time { + /** + * In returns a copy of t representing the same time instant, but + * with the copy's location information set to loc for display + * purposes. + * + * In panics if loc is nil. + */ + in(loc: Location): Time + } + interface Time { + /** + * Location returns the time zone information associated with t. + */ + location(): (Location) + } + interface Time { + /** + * Zone computes the time zone in effect at time t, returning the abbreviated + * name of the zone (such as "CET") and its offset in seconds east of UTC. + */ + zone(): [string, number] + } + interface Time { + /** + * ZoneBounds returns the bounds of the time zone in effect at time t. + * The zone begins at start and the next zone begins at end. + * If the zone begins at the beginning of time, start will be returned as a zero Time. + * If the zone goes on forever, end will be returned as a zero Time. + * The Location of the returned times will be the same as t. + */ + zoneBounds(): [Time, Time] + } + interface Time { + /** + * Unix returns t as a Unix time, the number of seconds elapsed + * since January 1, 1970 UTC. The result does not depend on the + * location associated with t. + * Unix-like operating systems often record time as a 32-bit + * count of seconds, but since the method here returns a 64-bit + * value it is valid for billions of years into the past or future. + */ + unix(): number + } + interface Time { + /** + * UnixMilli returns t as a Unix time, the number of milliseconds elapsed since + * January 1, 1970 UTC. The result is undefined if the Unix time in + * milliseconds cannot be represented by an int64 (a date more than 292 million + * years before or after 1970). The result does not depend on the + * location associated with t. + */ + unixMilli(): number + } + interface Time { + /** + * UnixMicro returns t as a Unix time, the number of microseconds elapsed since + * January 1, 1970 UTC. The result is undefined if the Unix time in + * microseconds cannot be represented by an int64 (a date before year -290307 or + * after year 294246). The result does not depend on the location associated + * with t. + */ + unixMicro(): number + } + interface Time { + /** + * UnixNano returns t as a Unix time, the number of nanoseconds elapsed + * since January 1, 1970 UTC. The result is undefined if the Unix time + * in nanoseconds cannot be represented by an int64 (a date before the year + * 1678 or after 2262). Note that this means the result of calling UnixNano + * on the zero Time is undefined. The result does not depend on the + * location associated with t. + */ + unixNano(): number + } + interface Time { + /** + * AppendBinary implements the [encoding.BinaryAppender] interface. + */ + appendBinary(b: string|Array): string|Array + } + interface Time { + /** + * MarshalBinary implements the [encoding.BinaryMarshaler] interface. + */ + marshalBinary(): string|Array + } + interface Time { + /** + * UnmarshalBinary implements the [encoding.BinaryUnmarshaler] interface. + */ + unmarshalBinary(data: string|Array): void + } + interface Time { + /** + * GobEncode implements the gob.GobEncoder interface. + */ + gobEncode(): string|Array + } + interface Time { + /** + * GobDecode implements the gob.GobDecoder interface. + */ + gobDecode(data: string|Array): void + } + interface Time { + /** + * MarshalJSON implements the [encoding/json.Marshaler] interface. + * The time is a quoted string in the RFC 3339 format with sub-second precision. + * If the timestamp cannot be represented as valid RFC 3339 + * (e.g., the year is out of range), then an error is reported. + */ + marshalJSON(): string|Array + } + interface Time { + /** + * UnmarshalJSON implements the [encoding/json.Unmarshaler] interface. + * The time must be a quoted string in the RFC 3339 format. + */ + unmarshalJSON(data: string|Array): void + } + interface Time { + /** + * AppendText implements the [encoding.TextAppender] interface. + * The time is formatted in RFC 3339 format with sub-second precision. + * If the timestamp cannot be represented as valid RFC 3339 + * (e.g., the year is out of range), then an error is returned. + */ + appendText(b: string|Array): string|Array + } + interface Time { + /** + * MarshalText implements the [encoding.TextMarshaler] interface. The output + * matches that of calling the [Time.AppendText] method. + * + * See [Time.AppendText] for more information. + */ + marshalText(): string|Array + } + interface Time { + /** + * UnmarshalText implements the [encoding.TextUnmarshaler] interface. + * The time must be in the RFC 3339 format. + */ + unmarshalText(data: string|Array): void + } + interface Time { + /** + * IsDST reports whether the time in the configured location is in Daylight Savings Time. + */ + isDST(): boolean + } + interface Time { + /** + * Truncate returns the result of rounding t down to a multiple of d (since the zero time). + * If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged. + * + * Truncate operates on the time as an absolute duration since the + * zero time; it does not operate on the presentation form of the + * time. Thus, Truncate(Hour) may return a time with a non-zero + * minute, depending on the time's Location. + */ + truncate(d: Duration): Time + } + interface Time { + /** + * Round returns the result of rounding t to the nearest multiple of d (since the zero time). + * The rounding behavior for halfway values is to round up. + * If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged. + * + * Round operates on the time as an absolute duration since the + * zero time; it does not operate on the presentation form of the + * time. Thus, Round(Hour) may return a time with a non-zero + * minute, depending on the time's Location. + */ + round(d: Duration): Time + } +} + +/** + * Package context defines the Context type, which carries deadlines, + * cancellation signals, and other request-scoped values across API boundaries + * and between processes. + * + * Incoming requests to a server should create a [Context], and outgoing + * calls to servers should accept a Context. The chain of function + * calls between them must propagate the Context, optionally replacing + * it with a derived Context created using [WithCancel], [WithDeadline], + * [WithTimeout], or [WithValue]. + * + * A Context may be canceled to indicate that work done on its behalf should stop. + * A Context with a deadline is canceled after the deadline passes. + * When a Context is canceled, all Contexts derived from it are also canceled. + * + * The [WithCancel], [WithDeadline], and [WithTimeout] functions take a + * Context (the parent) and return a derived Context (the child) and a + * [CancelFunc]. Calling the CancelFunc directly cancels the child and its + * children, removes the parent's reference to the child, and stops + * any associated timers. Failing to call the CancelFunc leaks the + * child and its children until the parent is canceled. The go vet tool + * checks that CancelFuncs are used on all control-flow paths. + * + * The [WithCancelCause], [WithDeadlineCause], and [WithTimeoutCause] functions + * return a [CancelCauseFunc], which takes an error and records it as + * the cancellation cause. Calling [Cause] on the canceled context + * or any of its children retrieves the cause. If no cause is specified, + * Cause(ctx) returns the same value as ctx.Err(). + * + * Programs that use Contexts should follow these rules to keep interfaces + * consistent across packages and enable static analysis tools to check context + * propagation: + * + * Do not store Contexts inside a struct type; instead, pass a Context + * explicitly to each function that needs it. This is discussed further in + * https://go.dev/blog/context-and-structs. The Context should be the first + * parameter, typically named ctx: + * + * ``` + * func DoSomething(ctx context.Context, arg Arg) error { + * // ... use ctx ... + * } + * ``` + * + * Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] + * if you are unsure about which Context to use. + * + * Use context Values only for request-scoped data that transits processes and + * APIs, not for passing optional parameters to functions. + * + * The same Context may be passed to functions running in different goroutines; + * Contexts are safe for simultaneous use by multiple goroutines. + * + * See https://go.dev/blog/context for example code for a server that uses + * Contexts. + */ +namespace context { + /** + * A Context carries a deadline, a cancellation signal, and other values across + * API boundaries. + * + * Context's methods may be called by multiple goroutines simultaneously. + */ + interface Context { + [key:string]: any; + /** + * Deadline returns the time when work done on behalf of this context + * should be canceled. Deadline returns ok==false when no deadline is + * set. Successive calls to Deadline return the same results. + */ + deadline(): [time.Time, boolean] + /** + * Done returns a channel that's closed when work done on behalf of this + * context should be canceled. Done may return nil if this context can + * never be canceled. Successive calls to Done return the same value. + * The close of the Done channel may happen asynchronously, + * after the cancel function returns. + * + * WithCancel arranges for Done to be closed when cancel is called; + * WithDeadline arranges for Done to be closed when the deadline + * expires; WithTimeout arranges for Done to be closed when the timeout + * elapses. + * + * Done is provided for use in select statements: + * + * // Stream generates values with DoSomething and sends them to out + * // until DoSomething returns an error or ctx.Done is closed. + * func Stream(ctx context.Context, out chan<- Value) error { + * for { + * v, err := DoSomething(ctx) + * if err != nil { + * return err + * } + * select { + * case <-ctx.Done(): + * return ctx.Err() + * case out <- v: + * } + * } + * } + * + * See https://blog.golang.org/pipelines for more examples of how to use + * a Done channel for cancellation. + */ + done(): undefined + /** + * If Done is not yet closed, Err returns nil. + * If Done is closed, Err returns a non-nil error explaining why: + * DeadlineExceeded if the context's deadline passed, + * or Canceled if the context was canceled for some other reason. + * After Err returns a non-nil error, successive calls to Err return the same error. + */ + err(): void + /** + * Value returns the value associated with this context for key, or nil + * if no value is associated with key. Successive calls to Value with + * the same key returns the same result. + * + * Use context values only for request-scoped data that transits + * processes and API boundaries, not for passing optional parameters to + * functions. + * + * A key identifies a specific value in a Context. Functions that wish + * to store values in Context typically allocate a key in a global + * variable then use that key as the argument to context.WithValue and + * Context.Value. A key can be any type that supports equality; + * packages should define keys as an unexported type to avoid + * collisions. + * + * Packages that define a Context key should provide type-safe accessors + * for the values stored using that key: + * + * ``` + * // Package user defines a User type that's stored in Contexts. + * package user + * + * import "context" + * + * // User is the type of value stored in the Contexts. + * type User struct {...} + * + * // key is an unexported type for keys defined in this package. + * // This prevents collisions with keys defined in other packages. + * type key int + * + * // userKey is the key for user.User values in Contexts. It is + * // unexported; clients use user.NewContext and user.FromContext + * // instead of using this key directly. + * var userKey key + * + * // NewContext returns a new Context that carries value u. + * func NewContext(ctx context.Context, u *User) context.Context { + * return context.WithValue(ctx, userKey, u) + * } + * + * // FromContext returns the User value stored in ctx, if any. + * func FromContext(ctx context.Context) (*User, bool) { + * u, ok := ctx.Value(userKey).(*User) + * return u, ok + * } + * ``` + */ + value(key: any): any + } +} + +/** + * Package fs defines basic interfaces to a file system. + * A file system can be provided by the host operating system + * but also by other packages. + * + * See the [testing/fstest] package for support with testing + * implementations of file systems. + */ +namespace fs { + /** + * An FS provides access to a hierarchical file system. + * + * The FS interface is the minimum implementation required of the file system. + * A file system may implement additional interfaces, + * such as [ReadFileFS], to provide additional or optimized functionality. + * + * [testing/fstest.TestFS] may be used to test implementations of an FS for + * correctness. + */ + interface FS { + [key:string]: any; + /** + * Open opens the named file. + * [File.Close] must be called to release any associated resources. + * + * When Open returns an error, it should be of type *PathError + * with the Op field set to "open", the Path field set to name, + * and the Err field describing the problem. + * + * Open should reject attempts to open names that do not satisfy + * ValidPath(name), returning a *PathError with Err set to + * ErrInvalid or ErrNotExist. + */ + open(name: string): File + } + /** + * A File provides access to a single file. + * The File interface is the minimum implementation required of the file. + * Directory files should also implement [ReadDirFile]. + * A file may implement [io.ReaderAt] or [io.Seeker] as optimizations. + */ + interface File { + [key:string]: any; + stat(): FileInfo + read(_arg0: string|Array): number + close(): void + } + /** + * A DirEntry is an entry read from a directory + * (using the [ReadDir] function or a [ReadDirFile]'s ReadDir method). + */ + interface DirEntry { + [key:string]: any; + /** + * Name returns the name of the file (or subdirectory) described by the entry. + * This name is only the final element of the path (the base name), not the entire path. + * For example, Name would return "hello.go" not "home/gopher/hello.go". + */ + name(): string + /** + * IsDir reports whether the entry describes a directory. + */ + isDir(): boolean + /** + * Type returns the type bits for the entry. + * The type bits are a subset of the usual FileMode bits, those returned by the FileMode.Type method. + */ + type(): FileMode + /** + * Info returns the FileInfo for the file or subdirectory described by the entry. + * The returned FileInfo may be from the time of the original directory read + * or from the time of the call to Info. If the file has been removed or renamed + * since the directory read, Info may return an error satisfying errors.Is(err, ErrNotExist). + * If the entry denotes a symbolic link, Info reports the information about the link itself, + * not the link's target. + */ + info(): FileInfo + } + /** + * A FileInfo describes a file and is returned by [Stat]. + */ + interface FileInfo { + [key:string]: any; + name(): string // base name of the file + size(): number // length in bytes for regular files; system-dependent for others + mode(): FileMode // file mode bits + modTime(): time.Time // modification time + isDir(): boolean // abbreviation for Mode().IsDir() + sys(): any // underlying data source (can return nil) + } + /** + * A FileMode represents a file's mode and permission bits. + * The bits have the same definition on all systems, so that + * information about files can be moved from one system + * to another portably. Not all bits apply to all systems. + * The only required bit is [ModeDir] for directories. + */ + interface FileMode extends Number{} + interface FileMode { + string(): string + } + interface FileMode { + /** + * IsDir reports whether m describes a directory. + * That is, it tests for the [ModeDir] bit being set in m. + */ + isDir(): boolean + } + interface FileMode { + /** + * IsRegular reports whether m describes a regular file. + * That is, it tests that no mode type bits are set. + */ + isRegular(): boolean + } + interface FileMode { + /** + * Perm returns the Unix permission bits in m (m & [ModePerm]). + */ + perm(): FileMode + } + interface FileMode { + /** + * Type returns type bits in m (m & [ModeType]). + */ + type(): FileMode + } + /** + * PathError records an error and the operation and file path that caused it. + */ + interface PathError { + op: string + path: string + err: Error + } + interface PathError { + error(): string + } + interface PathError { + unwrap(): void + } + interface PathError { + /** + * Timeout reports whether this error represents a timeout. + */ + timeout(): boolean + } + /** + * WalkDirFunc is the type of the function called by [WalkDir] to visit + * each file or directory. + * + * The path argument contains the argument to [WalkDir] as a prefix. + * That is, if WalkDir is called with root argument "dir" and finds a file + * named "a" in that directory, the walk function will be called with + * argument "dir/a". + * + * The d argument is the [DirEntry] for the named path. + * + * The error result returned by the function controls how [WalkDir] + * continues. If the function returns the special value [SkipDir], WalkDir + * skips the current directory (path if d.IsDir() is true, otherwise + * path's parent directory). If the function returns the special value + * [SkipAll], WalkDir skips all remaining files and directories. Otherwise, + * if the function returns a non-nil error, WalkDir stops entirely and + * returns that error. + * + * The err argument reports an error related to path, signaling that + * [WalkDir] will not walk into that directory. The function can decide how + * to handle that error; as described earlier, returning the error will + * cause WalkDir to stop walking the entire tree. + * + * [WalkDir] calls the function with a non-nil err argument in two cases. + * + * First, if the initial [Stat] on the root directory fails, WalkDir + * calls the function with path set to root, d set to nil, and err set to + * the error from [fs.Stat]. + * + * Second, if a directory's ReadDir method (see [ReadDirFile]) fails, WalkDir calls the + * function with path set to the directory's path, d set to an + * [DirEntry] describing the directory, and err set to the error from + * ReadDir. In this second case, the function is called twice with the + * path of the directory: the first call is before the directory read is + * attempted and has err set to nil, giving the function a chance to + * return [SkipDir] or [SkipAll] and avoid the ReadDir entirely. The second call + * is after a failed ReadDir and reports the error from ReadDir. + * (If ReadDir succeeds, there is no second call.) + * + * The differences between WalkDirFunc compared to [path/filepath.WalkFunc] are: + * + * ``` + * - The second argument has type [DirEntry] instead of [FileInfo]. + * - The function is called before reading a directory, to allow [SkipDir] + * or [SkipAll] to bypass the directory read entirely or skip all remaining + * files and directories respectively. + * - If a directory read fails, the function is called a second time + * for that directory to report the error. + * ``` + */ + interface WalkDirFunc {(path: string, d: DirEntry, err: Error): void } +} + +/** + * Package net provides a portable interface for network I/O, including + * TCP/IP, UDP, domain name resolution, and Unix domain sockets. + * + * Although the package provides access to low-level networking + * primitives, most clients will need only the basic interface provided + * by the [Dial], [Listen], and Accept functions and the associated + * [Conn] and [Listener] interfaces. The crypto/tls package uses + * the same interfaces and similar Dial and Listen functions. + * + * The Dial function connects to a server: + * + * ``` + * conn, err := net.Dial("tcp", "golang.org:80") + * if err != nil { + * // handle error + * } + * fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") + * status, err := bufio.NewReader(conn).ReadString('\n') + * // ... + * ``` + * + * The Listen function creates servers: + * + * ``` + * ln, err := net.Listen("tcp", ":8080") + * if err != nil { + * // handle error + * } + * for { + * conn, err := ln.Accept() + * if err != nil { + * // handle error + * } + * go handleConnection(conn) + * } + * ``` + * + * # Name Resolution + * + * The method for resolving domain names, whether indirectly with functions like Dial + * or directly with functions like [LookupHost] and [LookupAddr], varies by operating system. + * + * On Unix systems, the resolver has two options for resolving names. + * It can use a pure Go resolver that sends DNS requests directly to the servers + * listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C + * library routines such as getaddrinfo and getnameinfo. + * + * On Unix the pure Go resolver is preferred over the cgo resolver, because a blocked DNS + * request consumes only a goroutine, while a blocked C call consumes an operating system thread. + * When cgo is available, the cgo-based resolver is used instead under a variety of + * conditions: on systems that do not let programs make direct DNS requests (OS X), + * when the LOCALDOMAIN environment variable is present (even if empty), + * when the RES_OPTIONS or HOSTALIASES environment variable is non-empty, + * when the ASR_CONFIG environment variable is non-empty (OpenBSD only), + * when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the + * Go resolver does not implement. + * + * On all systems (except Plan 9), when the cgo resolver is being used + * this package applies a concurrent cgo lookup limit to prevent the system + * from running out of system threads. Currently, it is limited to 500 concurrent lookups. + * + * The resolver decision can be overridden by setting the netdns value of the + * GODEBUG environment variable (see package runtime) to go or cgo, as in: + * + * ``` + * export GODEBUG=netdns=go # force pure Go resolver + * export GODEBUG=netdns=cgo # force native resolver (cgo, win32) + * ``` + * + * The decision can also be forced while building the Go source tree + * by setting the netgo or netcgo build tag. + * The netgo build tag disables entirely the use of the native (CGO) resolver, + * meaning the Go resolver is the only one that can be used. + * With the netcgo build tag the native and the pure Go resolver are compiled into the binary, + * but the native (CGO) resolver is preferred over the Go resolver. + * With netcgo, the Go resolver can still be forced at runtime with GODEBUG=netdns=go. + * + * A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver + * to print debugging information about its decisions. + * To force a particular resolver while also printing debugging information, + * join the two settings by a plus sign, as in GODEBUG=netdns=go+1. + * + * The Go resolver will send an EDNS0 additional header with a DNS request, + * to signal a willingness to accept a larger DNS packet size. + * This can reportedly cause sporadic failures with the DNS server run + * by some modems and routers. Setting GODEBUG=netedns0=0 will disable + * sending the additional header. + * + * On macOS, if Go code that uses the net package is built with + * -buildmode=c-archive, linking the resulting archive into a C program + * requires passing -lresolv when linking the C code. + * + * On Plan 9, the resolver always accesses /net/cs and /net/dns. + * + * On Windows, in Go 1.18.x and earlier, the resolver always used C + * library functions, such as GetAddrInfo and DnsQuery. + */ +namespace net { + /** + * Conn is a generic stream-oriented network connection. + * + * Multiple goroutines may invoke methods on a Conn simultaneously. + */ + interface Conn { + [key:string]: any; + /** + * Read reads data from the connection. + * Read can be made to time out and return an error after a fixed + * time limit; see SetDeadline and SetReadDeadline. + */ + read(b: string|Array): number + /** + * Write writes data to the connection. + * Write can be made to time out and return an error after a fixed + * time limit; see SetDeadline and SetWriteDeadline. + */ + write(b: string|Array): number + /** + * Close closes the connection. + * Any blocked Read or Write operations will be unblocked and return errors. + */ + close(): void + /** + * LocalAddr returns the local network address, if known. + */ + localAddr(): Addr + /** + * RemoteAddr returns the remote network address, if known. + */ + remoteAddr(): Addr + /** + * SetDeadline sets the read and write deadlines associated + * with the connection. It is equivalent to calling both + * SetReadDeadline and SetWriteDeadline. + * + * A deadline is an absolute time after which I/O operations + * fail instead of blocking. The deadline applies to all future + * and pending I/O, not just the immediately following call to + * Read or Write. After a deadline has been exceeded, the + * connection can be refreshed by setting a deadline in the future. + * + * If the deadline is exceeded a call to Read or Write or to other + * I/O methods will return an error that wraps os.ErrDeadlineExceeded. + * This can be tested using errors.Is(err, os.ErrDeadlineExceeded). + * The error's Timeout method will return true, but note that there + * are other possible errors for which the Timeout method will + * return true even if the deadline has not been exceeded. + * + * An idle timeout can be implemented by repeatedly extending + * the deadline after successful Read or Write calls. + * + * A zero value for t means I/O operations will not time out. + */ + setDeadline(t: time.Time): void + /** + * SetReadDeadline sets the deadline for future Read calls + * and any currently-blocked Read call. + * A zero value for t means Read will not time out. + */ + setReadDeadline(t: time.Time): void + /** + * SetWriteDeadline sets the deadline for future Write calls + * and any currently-blocked Write call. + * Even if write times out, it may return n > 0, indicating that + * some of the data was successfully written. + * A zero value for t means Write will not time out. + */ + setWriteDeadline(t: time.Time): void + } + /** + * A Listener is a generic network listener for stream-oriented protocols. + * + * Multiple goroutines may invoke methods on a Listener simultaneously. + */ + interface Listener { + [key:string]: any; + /** + * Accept waits for and returns the next connection to the listener. + */ + accept(): Conn + /** + * Close closes the listener. + * Any blocked Accept operations will be unblocked and return errors. + */ + close(): void + /** + * Addr returns the listener's network address. + */ + addr(): Addr + } +} + +/** + * Package syntax parses regular expressions into parse trees and compiles + * parse trees into programs. Most clients of regular expressions will use the + * facilities of package [regexp] (such as [regexp.Compile] and [regexp.Match]) instead of this package. + * + * # Syntax + * + * The regular expression syntax understood by this package when parsing with the [Perl] flag is as follows. + * Parts of the syntax can be disabled by passing alternate flags to [Parse]. + * + * Single characters: + * + * ``` + * . any character, possibly including newline (flag s=true) + * [xyz] character class + * [^xyz] negated character class + * \d Perl character class + * \D negated Perl character class + * [[:alpha:]] ASCII character class + * [[:^alpha:]] negated ASCII character class + * \pN Unicode character class (one-letter name) + * \p{Greek} Unicode character class + * \PN negated Unicode character class (one-letter name) + * \P{Greek} negated Unicode character class + * ``` + * + * Composites: + * + * ``` + * xy x followed by y + * x|y x or y (prefer x) + * ``` + * + * Repetitions: + * + * ``` + * x* zero or more x, prefer more + * x+ one or more x, prefer more + * x? zero or one x, prefer one + * x{n,m} n or n+1 or ... or m x, prefer more + * x{n,} n or more x, prefer more + * x{n} exactly n x + * x*? zero or more x, prefer fewer + * x+? one or more x, prefer fewer + * x?? zero or one x, prefer zero + * x{n,m}? n or n+1 or ... or m x, prefer fewer + * x{n,}? n or more x, prefer fewer + * x{n}? exactly n x + * ``` + * + * Implementation restriction: The counting forms x{n,m}, x{n,}, and x{n} + * reject forms that create a minimum or maximum repetition count above 1000. + * Unlimited repetitions are not subject to this restriction. + * + * Grouping: + * + * ``` + * (re) numbered capturing group (submatch) + * (?Pre) named & numbered capturing group (submatch) + * (?re) named & numbered capturing group (submatch) + * (?:re) non-capturing group + * (?flags) set flags within current group; non-capturing + * (?flags:re) set flags during re; non-capturing + * + * Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are: + * + * i case-insensitive (default false) + * m multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false) + * s let . match \n (default false) + * U ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false) + * ``` + * + * Empty strings: + * + * ``` + * ^ at beginning of text or line (flag m=true) + * $ at end of text (like \z not \Z) or line (flag m=true) + * \A at beginning of text + * \b at ASCII word boundary (\w on one side and \W, \A, or \z on the other) + * \B not at ASCII word boundary + * \z at end of text + * ``` + * + * Escape sequences: + * + * ``` + * \a bell (== \007) + * \f form feed (== \014) + * \t horizontal tab (== \011) + * \n newline (== \012) + * \r carriage return (== \015) + * \v vertical tab character (== \013) + * \* literal *, for any punctuation character * + * \123 octal character code (up to three digits) + * \x7F hex character code (exactly two digits) + * \x{10FFFF} hex character code + * \Q...\E literal text ... even if ... has punctuation + * ``` + * + * Character class elements: + * + * ``` + * x single character + * A-Z character range (inclusive) + * \d Perl character class + * [:foo:] ASCII character class foo + * \p{Foo} Unicode character class Foo + * \pF Unicode character class F (one-letter name) + * ``` + * + * Named character classes as character class elements: + * + * ``` + * [\d] digits (== \d) + * [^\d] not digits (== \D) + * [\D] not digits (== \D) + * [^\D] not not digits (== \d) + * [[:name:]] named ASCII class inside character class (== [:name:]) + * [^[:name:]] named ASCII class inside negated character class (== [:^name:]) + * [\p{Name}] named Unicode property inside character class (== \p{Name}) + * [^\p{Name}] named Unicode property inside negated character class (== \P{Name}) + * ``` + * + * Perl character classes (all ASCII-only): + * + * ``` + * \d digits (== [0-9]) + * \D not digits (== [^0-9]) + * \s whitespace (== [\t\n\f\r ]) + * \S not whitespace (== [^\t\n\f\r ]) + * \w word characters (== [0-9A-Za-z_]) + * \W not word characters (== [^0-9A-Za-z_]) + * ``` + * + * ASCII character classes: + * + * ``` + * [[:alnum:]] alphanumeric (== [0-9A-Za-z]) + * [[:alpha:]] alphabetic (== [A-Za-z]) + * [[:ascii:]] ASCII (== [\x00-\x7F]) + * [[:blank:]] blank (== [\t ]) + * [[:cntrl:]] control (== [\x00-\x1F\x7F]) + * [[:digit:]] digits (== [0-9]) + * [[:graph:]] graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]) + * [[:lower:]] lower case (== [a-z]) + * [[:print:]] printable (== [ -~] == [ [:graph:]]) + * [[:punct:]] punctuation (== [!-/:-@[-`{-~]) + * [[:space:]] whitespace (== [\t\n\v\f\r ]) + * [[:upper:]] upper case (== [A-Z]) + * [[:word:]] word characters (== [0-9A-Za-z_]) + * [[:xdigit:]] hex digit (== [0-9A-Fa-f]) + * ``` + * + * Unicode character classes are those in [unicode.Categories] and [unicode.Scripts]. + */ +namespace syntax { + /** + * Flags control the behavior of the parser and record information about regexp context. + */ + interface Flags extends Number{} +} + +/** + * Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html + * + * See README.md for more info. + */ +namespace jwt { + /** + * MapClaims is a claims type that uses the map[string]any for JSON + * decoding. This is the default claims type if you don't supply one + */ + interface MapClaims extends _TygojaDict{} + interface MapClaims { + /** + * GetExpirationTime implements the Claims interface. + */ + getExpirationTime(): (NumericDate) + } + interface MapClaims { + /** + * GetNotBefore implements the Claims interface. + */ + getNotBefore(): (NumericDate) + } + interface MapClaims { + /** + * GetIssuedAt implements the Claims interface. + */ + getIssuedAt(): (NumericDate) + } + interface MapClaims { + /** + * GetAudience implements the Claims interface. + */ + getAudience(): ClaimStrings + } + interface MapClaims { + /** + * GetIssuer implements the Claims interface. + */ + getIssuer(): string + } + interface MapClaims { + /** + * GetSubject implements the Claims interface. + */ + getSubject(): string + } +} + +/** + * Package types implements some commonly used db serializable types + * like datetime, json, etc. + */ +namespace types { + /** + * DateTime represents a [time.Time] instance in UTC that is wrapped + * and serialized using the app default date layout. + */ + interface DateTime { + } + interface DateTime { + /** + * Time returns the internal [time.Time] instance. + */ + time(): time.Time + } + interface DateTime { + /** + * Add returns a new DateTime based on the current DateTime + the specified duration. + */ + add(duration: time.Duration): DateTime + } + interface DateTime { + /** + * Sub returns a [time.Duration] by subtracting the specified DateTime from the current one. + * + * If the result exceeds the maximum (or minimum) value that can be stored in a [time.Duration], + * the maximum (or minimum) duration will be returned. + */ + sub(u: DateTime): time.Duration + } + interface DateTime { + /** + * AddDate returns a new DateTime based on the current one + duration. + * + * It follows the same rules as [time.AddDate]. + */ + addDate(years: number, months: number, days: number): DateTime + } + interface DateTime { + /** + * After reports whether the current DateTime instance is after u. + */ + after(u: DateTime): boolean + } + interface DateTime { + /** + * Before reports whether the current DateTime instance is before u. + */ + before(u: DateTime): boolean + } + interface DateTime { + /** + * Compare compares the current DateTime instance with u. + * If the current instance is before u, it returns -1. + * If the current instance is after u, it returns +1. + * If they're the same, it returns 0. + */ + compare(u: DateTime): number + } + interface DateTime { + /** + * Equal reports whether the current DateTime and u represent the same time instant. + * Two DateTime can be equal even if they are in different locations. + * For example, 6:00 +0200 and 4:00 UTC are Equal. + */ + equal(u: DateTime): boolean + } + interface DateTime { + /** + * Unix returns the current DateTime as a Unix time, aka. + * the number of seconds elapsed since January 1, 1970 UTC. + */ + unix(): number + } + interface DateTime { + /** + * IsZero checks whether the current DateTime instance has zero time value. + */ + isZero(): boolean + } + interface DateTime { + /** + * String serializes the current DateTime instance into a formatted + * UTC date string. + * + * The zero value is serialized to an empty string. + */ + string(): string + } + interface DateTime { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface DateTime { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface DateTime { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface DateTime { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current DateTime instance. + */ + scan(value: any): void + } + /** + * GeoPoint defines a struct for storing geo coordinates as serialized json object + * (e.g. {lon:0,lat:0}). + * + * Note: using object notation and not a plain array to avoid the confusion + * as there doesn't seem to be a fixed standard for the coordinates order. + */ + interface GeoPoint { + lon: number + lat: number + } + interface GeoPoint { + /** + * String returns the string representation of the current GeoPoint instance. + */ + string(): string + } + interface GeoPoint { + /** + * AsMap implements [core.mapExtractor] and returns a value suitable + * to be used in an API rule expression. + */ + asMap(): _TygojaDict + } + interface GeoPoint { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface GeoPoint { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current GeoPoint instance. + * + * The value argument could be nil (no-op), another GeoPoint instance, + * map or serialized json object with lat-lon props. + */ + scan(value: any): void + } + /** + * JSONArray defines a slice that is safe for json and db read/write. + */ + interface JSONArray extends Array{} + interface JSONArray { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONArray { + /** + * String returns the string representation of the current json array. + */ + string(): string + } + interface JSONArray { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONArray { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONArray[T] instance. + */ + scan(value: any): void + } + /** + * JSONMap defines a map that is safe for json and db read/write. + */ + interface JSONMap extends _TygojaDict{} + interface JSONMap { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONMap { + /** + * String returns the string representation of the current json map. + */ + string(): string + } + interface JSONMap { + /** + * Get retrieves a single value from the current JSONMap[T]. + * + * This helper was added primarily to assist the goja integration since custom map types + * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). + */ + get(key: string): T + } + interface JSONMap { + /** + * Set sets a single value in the current JSONMap[T]. + * + * This helper was added primarily to assist the goja integration since custom map types + * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). + */ + set(key: string, value: T): void + } + interface JSONMap { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONMap { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONMap[T] instance. + */ + scan(value: any): void + } + /** + * JSONRaw defines a json value type that is safe for db read/write. + */ + interface JSONRaw extends Array{} + interface JSONRaw { + /** + * String returns the current JSONRaw instance as a json encoded string. + */ + string(): string + } + interface JSONRaw { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONRaw { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface JSONRaw { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONRaw { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONRaw instance. + */ + scan(value: any): void + } +} + +/** + * Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer + * object, creating another object (Reader or Writer) that also implements + * the interface but provides buffering and some help for textual I/O. + */ +namespace bufio { + /** + * ReadWriter stores pointers to a [Reader] and a [Writer]. + * It implements [io.ReadWriter]. + */ + type _sfdaCHj = Reader&Writer + interface ReadWriter extends _sfdaCHj { + } +} + +/** + * Package multipart implements MIME multipart parsing, as defined in RFC + * 2046. + * + * The implementation is sufficient for HTTP (RFC 2388) and the multipart + * bodies generated by popular browsers. + * + * # Limits + * + * To protect against malicious inputs, this package sets limits on the size + * of the MIME data it processes. + * + * [Reader.NextPart] and [Reader.NextRawPart] limit the number of headers in a + * part to 10000 and [Reader.ReadForm] limits the total number of headers in all + * FileHeaders to 10000. + * These limits may be adjusted with the GODEBUG=multipartmaxheaders= + * setting. + * + * Reader.ReadForm further limits the number of parts in a form to 1000. + * This limit may be adjusted with the GODEBUG=multipartmaxparts= + * setting. + */ +namespace multipart { + /** + * A FileHeader describes a file part of a multipart request. + */ + interface FileHeader { + filename: string + header: textproto.MIMEHeader + size: number + } + interface FileHeader { + /** + * Open opens and returns the [FileHeader]'s associated File. + */ + open(): File + } +} + +/** + * Package http provides HTTP client and server implementations. + * + * [Get], [Head], [Post], and [PostForm] make HTTP (or HTTPS) requests: + * + * ``` + * resp, err := http.Get("http://example.com/") + * ... + * resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) + * ... + * resp, err := http.PostForm("http://example.com/form", + * url.Values{"key": {"Value"}, "id": {"123"}}) + * ``` + * + * The caller must close the response body when finished with it: + * + * ``` + * resp, err := http.Get("http://example.com/") + * if err != nil { + * // handle error + * } + * defer resp.Body.Close() + * body, err := io.ReadAll(resp.Body) + * // ... + * ``` + * + * # Clients and Transports + * + * For control over HTTP client headers, redirect policy, and other + * settings, create a [Client]: + * + * ``` + * client := &http.Client{ + * CheckRedirect: redirectPolicyFunc, + * } + * + * resp, err := client.Get("http://example.com") + * // ... + * + * req, err := http.NewRequest("GET", "http://example.com", nil) + * // ... + * req.Header.Add("If-None-Match", `W/"wyzzy"`) + * resp, err := client.Do(req) + * // ... + * ``` + * + * For control over proxies, TLS configuration, keep-alives, + * compression, and other settings, create a [Transport]: + * + * ``` + * tr := &http.Transport{ + * MaxIdleConns: 10, + * IdleConnTimeout: 30 * time.Second, + * DisableCompression: true, + * } + * client := &http.Client{Transport: tr} + * resp, err := client.Get("https://example.com") + * ``` + * + * Clients and Transports are safe for concurrent use by multiple + * goroutines and for efficiency should only be created once and re-used. + * + * # Servers + * + * ListenAndServe starts an HTTP server with a given address and handler. + * The handler is usually nil, which means to use [DefaultServeMux]. + * [Handle] and [HandleFunc] add handlers to [DefaultServeMux]: + * + * ``` + * http.Handle("/foo", fooHandler) + * + * http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { + * fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) + * }) + * + * log.Fatal(http.ListenAndServe(":8080", nil)) + * ``` + * + * More control over the server's behavior is available by creating a + * custom Server: + * + * ``` + * s := &http.Server{ + * Addr: ":8080", + * Handler: myHandler, + * ReadTimeout: 10 * time.Second, + * WriteTimeout: 10 * time.Second, + * MaxHeaderBytes: 1 << 20, + * } + * log.Fatal(s.ListenAndServe()) + * ``` + * + * # HTTP/2 + * + * Starting with Go 1.6, the http package has transparent support for the + * HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2 + * can do so by setting [Transport.TLSNextProto] (for clients) or + * [Server.TLSNextProto] (for servers) to a non-nil, empty + * map. Alternatively, the following GODEBUG settings are + * currently supported: + * + * ``` + * GODEBUG=http2client=0 # disable HTTP/2 client support + * GODEBUG=http2server=0 # disable HTTP/2 server support + * GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs + * GODEBUG=http2debug=2 # ... even more verbose, with frame dumps + * ``` + * + * Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug + * + * The http package's [Transport] and [Server] both automatically enable + * HTTP/2 support for simple configurations. To enable HTTP/2 for more + * complex configurations, to use lower-level HTTP/2 features, or to use + * a newer version of Go's http2 package, import "golang.org/x/net/http2" + * directly and use its ConfigureTransport and/or ConfigureServer + * functions. Manually configuring HTTP/2 via the golang.org/x/net/http2 + * package takes precedence over the net/http package's built-in HTTP/2 + * support. + */ +namespace http { + // @ts-ignore + import mathrand = rand + /** + * PushOptions describes options for [Pusher.Push]. + */ + interface PushOptions { + /** + * Method specifies the HTTP method for the promised request. + * If set, it must be "GET" or "HEAD". Empty means "GET". + */ + method: string + /** + * Header specifies additional promised request headers. This cannot + * include HTTP/2 pseudo header fields like ":path" and ":scheme", + * which will be added automatically. + */ + header: Header + } + // @ts-ignore + import urlpkg = url + /** + * A Request represents an HTTP request received by a server + * or to be sent by a client. + * + * The field semantics differ slightly between client and server + * usage. In addition to the notes on the fields below, see the + * documentation for [Request.Write] and [RoundTripper]. + */ + interface Request { + /** + * Method specifies the HTTP method (GET, POST, PUT, etc.). + * For client requests, an empty string means GET. + */ + method: string + /** + * URL specifies either the URI being requested (for server + * requests) or the URL to access (for client requests). + * + * For server requests, the URL is parsed from the URI + * supplied on the Request-Line as stored in RequestURI. For + * most requests, fields other than Path and RawQuery will be + * empty. (See RFC 7230, Section 5.3) + * + * For client requests, the URL's Host specifies the server to + * connect to, while the Request's Host field optionally + * specifies the Host header value to send in the HTTP + * request. + */ + url?: url.URL + /** + * The protocol version for incoming server requests. + * + * For client requests, these fields are ignored. The HTTP + * client code always uses either HTTP/1.1 or HTTP/2. + * See the docs on Transport for details. + */ + proto: string // "HTTP/1.0" + protoMajor: number // 1 + protoMinor: number // 0 + /** + * Header contains the request header fields either received + * by the server or to be sent by the client. + * + * If a server received a request with header lines, + * + * ``` + * Host: example.com + * accept-encoding: gzip, deflate + * Accept-Language: en-us + * fOO: Bar + * foo: two + * ``` + * + * then + * + * ``` + * Header = map[string][]string{ + * "Accept-Encoding": {"gzip, deflate"}, + * "Accept-Language": {"en-us"}, + * "Foo": {"Bar", "two"}, + * } + * ``` + * + * For incoming requests, the Host header is promoted to the + * Request.Host field and removed from the Header map. + * + * HTTP defines that header names are case-insensitive. The + * request parser implements this by using CanonicalHeaderKey, + * making the first character and any characters following a + * hyphen uppercase and the rest lowercase. + * + * For client requests, certain headers such as Content-Length + * and Connection are automatically written when needed and + * values in Header may be ignored. See the documentation + * for the Request.Write method. + */ + header: Header + /** + * Body is the request's body. + * + * For client requests, a nil body means the request has no + * body, such as a GET request. The HTTP Client's Transport + * is responsible for calling the Close method. + * + * For server requests, the Request Body is always non-nil + * but will return EOF immediately when no body is present. + * The Server will close the request body. The ServeHTTP + * Handler does not need to. + * + * Body must allow Read to be called concurrently with Close. + * In particular, calling Close should unblock a Read waiting + * for input. + */ + body: io.ReadCloser + /** + * GetBody defines an optional func to return a new copy of + * Body. It is used for client requests when a redirect requires + * reading the body more than once. Use of GetBody still + * requires setting Body. + * + * For server requests, it is unused. + */ + getBody: () => io.ReadCloser + /** + * ContentLength records the length of the associated content. + * The value -1 indicates that the length is unknown. + * Values >= 0 indicate that the given number of bytes may + * be read from Body. + * + * For client requests, a value of 0 with a non-nil Body is + * also treated as unknown. + */ + contentLength: number + /** + * TransferEncoding lists the transfer encodings from outermost to + * innermost. An empty list denotes the "identity" encoding. + * TransferEncoding can usually be ignored; chunked encoding is + * automatically added and removed as necessary when sending and + * receiving requests. + */ + transferEncoding: Array + /** + * Close indicates whether to close the connection after + * replying to this request (for servers) or after sending this + * request and reading its response (for clients). + * + * For server requests, the HTTP server handles this automatically + * and this field is not needed by Handlers. + * + * For client requests, setting this field prevents re-use of + * TCP connections between requests to the same hosts, as if + * Transport.DisableKeepAlives were set. + */ + close: boolean + /** + * For server requests, Host specifies the host on which the + * URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this + * is either the value of the "Host" header or the host name + * given in the URL itself. For HTTP/2, it is the value of the + * ":authority" pseudo-header field. + * It may be of the form "host:port". For international domain + * names, Host may be in Punycode or Unicode form. Use + * golang.org/x/net/idna to convert it to either format if + * needed. + * To prevent DNS rebinding attacks, server Handlers should + * validate that the Host header has a value for which the + * Handler considers itself authoritative. The included + * ServeMux supports patterns registered to particular host + * names and thus protects its registered Handlers. + * + * For client requests, Host optionally overrides the Host + * header to send. If empty, the Request.Write method uses + * the value of URL.Host. Host may contain an international + * domain name. + */ + host: string + /** + * Form contains the parsed form data, including both the URL + * field's query parameters and the PATCH, POST, or PUT form data. + * This field is only available after ParseForm is called. + * The HTTP client ignores Form and uses Body instead. + */ + form: url.Values + /** + * PostForm contains the parsed form data from PATCH, POST + * or PUT body parameters. + * + * This field is only available after ParseForm is called. + * The HTTP client ignores PostForm and uses Body instead. + */ + postForm: url.Values + /** + * MultipartForm is the parsed multipart form, including file uploads. + * This field is only available after ParseMultipartForm is called. + * The HTTP client ignores MultipartForm and uses Body instead. + */ + multipartForm?: multipart.Form + /** + * Trailer specifies additional headers that are sent after the request + * body. + * + * For server requests, the Trailer map initially contains only the + * trailer keys, with nil values. (The client declares which trailers it + * will later send.) While the handler is reading from Body, it must + * not reference Trailer. After reading from Body returns EOF, Trailer + * can be read again and will contain non-nil values, if they were sent + * by the client. + * + * For client requests, Trailer must be initialized to a map containing + * the trailer keys to later send. The values may be nil or their final + * values. The ContentLength must be 0 or -1, to send a chunked request. + * After the HTTP request is sent the map values can be updated while + * the request body is read. Once the body returns EOF, the caller must + * not mutate Trailer. + * + * Few HTTP clients, servers, or proxies support HTTP trailers. + */ + trailer: Header + /** + * RemoteAddr allows HTTP servers and other software to record + * the network address that sent the request, usually for + * logging. This field is not filled in by ReadRequest and + * has no defined format. The HTTP server in this package + * sets RemoteAddr to an "IP:port" address before invoking a + * handler. + * This field is ignored by the HTTP client. + */ + remoteAddr: string + /** + * RequestURI is the unmodified request-target of the + * Request-Line (RFC 7230, Section 3.1.1) as sent by the client + * to a server. Usually the URL field should be used instead. + * It is an error to set this field in an HTTP client request. + */ + requestURI: string + /** + * TLS allows HTTP servers and other software to record + * information about the TLS connection on which the request + * was received. This field is not filled in by ReadRequest. + * The HTTP server in this package sets the field for + * TLS-enabled connections before invoking a handler; + * otherwise it leaves the field nil. + * This field is ignored by the HTTP client. + */ + tls?: any + /** + * Cancel is an optional channel whose closure indicates that the client + * request should be regarded as canceled. Not all implementations of + * RoundTripper may support Cancel. + * + * For server requests, this field is not applicable. + * + * Deprecated: Set the Request's context with NewRequestWithContext + * instead. If a Request's Cancel field and context are both + * set, it is undefined whether Cancel is respected. + */ + cancel: undefined + /** + * Response is the redirect response which caused this request + * to be created. This field is only populated during client + * redirects. + */ + response?: Response + /** + * Pattern is the [ServeMux] pattern that matched the request. + * It is empty if the request was not matched against a pattern. + */ + pattern: string + } + interface Request { + /** + * Context returns the request's context. To change the context, use + * [Request.Clone] or [Request.WithContext]. + * + * The returned context is always non-nil; it defaults to the + * background context. + * + * For outgoing client requests, the context controls cancellation. + * + * For incoming server requests, the context is canceled when the + * client's connection closes, the request is canceled (with HTTP/2), + * or when the ServeHTTP method returns. + */ + context(): context.Context + } + interface Request { + /** + * WithContext returns a shallow copy of r with its context changed + * to ctx. The provided ctx must be non-nil. + * + * For outgoing client request, the context controls the entire + * lifetime of a request and its response: obtaining a connection, + * sending the request, and reading the response headers and body. + * + * To create a new request with a context, use [NewRequestWithContext]. + * To make a deep copy of a request with a new context, use [Request.Clone]. + */ + withContext(ctx: context.Context): (Request) + } + interface Request { + /** + * Clone returns a deep copy of r with its context changed to ctx. + * The provided ctx must be non-nil. + * + * Clone only makes a shallow copy of the Body field. + * + * For an outgoing client request, the context controls the entire + * lifetime of a request and its response: obtaining a connection, + * sending the request, and reading the response headers and body. + */ + clone(ctx: context.Context): (Request) + } + interface Request { + /** + * ProtoAtLeast reports whether the HTTP protocol used + * in the request is at least major.minor. + */ + protoAtLeast(major: number, minor: number): boolean + } + interface Request { + /** + * UserAgent returns the client's User-Agent, if sent in the request. + */ + userAgent(): string + } + interface Request { + /** + * Cookies parses and returns the HTTP cookies sent with the request. + */ + cookies(): Array<(Cookie | undefined)> + } + interface Request { + /** + * CookiesNamed parses and returns the named HTTP cookies sent with the request + * or an empty slice if none matched. + */ + cookiesNamed(name: string): Array<(Cookie | undefined)> + } + interface Request { + /** + * Cookie returns the named cookie provided in the request or + * [ErrNoCookie] if not found. + * If multiple cookies match the given name, only one cookie will + * be returned. + */ + cookie(name: string): (Cookie) + } + interface Request { + /** + * AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, + * AddCookie does not attach more than one [Cookie] header field. That + * means all cookies, if any, are written into the same line, + * separated by semicolon. + * AddCookie only sanitizes c's name and value, and does not sanitize + * a Cookie header already present in the request. + */ + addCookie(c: Cookie): void + } + interface Request { + /** + * Referer returns the referring URL, if sent in the request. + * + * Referer is misspelled as in the request itself, a mistake from the + * earliest days of HTTP. This value can also be fetched from the + * [Header] map as Header["Referer"]; the benefit of making it available + * as a method is that the compiler can diagnose programs that use the + * alternate (correct English) spelling req.Referrer() but cannot + * diagnose programs that use Header["Referrer"]. + */ + referer(): string + } + interface Request { + /** + * MultipartReader returns a MIME multipart reader if this is a + * multipart/form-data or a multipart/mixed POST request, else returns nil and an error. + * Use this function instead of [Request.ParseMultipartForm] to + * process the request body as a stream. + */ + multipartReader(): (multipart.Reader) + } + interface Request { + /** + * Write writes an HTTP/1.1 request, which is the header and body, in wire format. + * This method consults the following fields of the request: + * + * ``` + * Host + * URL + * Method (defaults to "GET") + * Header + * ContentLength + * TransferEncoding + * Body + * ``` + * + * If Body is present, Content-Length is <= 0 and [Request.TransferEncoding] + * hasn't been set to "identity", Write adds "Transfer-Encoding: + * chunked" to the header. Body is closed after it is sent. + */ + write(w: io.Writer): void + } + interface Request { + /** + * WriteProxy is like [Request.Write] but writes the request in the form + * expected by an HTTP proxy. In particular, [Request.WriteProxy] writes the + * initial Request-URI line of the request with an absolute URI, per + * section 5.3 of RFC 7230, including the scheme and host. + * In either case, WriteProxy also writes a Host header, using + * either r.Host or r.URL.Host. + */ + writeProxy(w: io.Writer): void + } + interface Request { + /** + * BasicAuth returns the username and password provided in the request's + * Authorization header, if the request uses HTTP Basic Authentication. + * See RFC 2617, Section 2. + */ + basicAuth(): [string, string, boolean] + } + interface Request { + /** + * SetBasicAuth sets the request's Authorization header to use HTTP + * Basic Authentication with the provided username and password. + * + * With HTTP Basic Authentication the provided username and password + * are not encrypted. It should generally only be used in an HTTPS + * request. + * + * The username may not contain a colon. Some protocols may impose + * additional requirements on pre-escaping the username and + * password. For instance, when used with OAuth2, both arguments must + * be URL encoded first with [url.QueryEscape]. + */ + setBasicAuth(username: string, password: string): void + } + interface Request { + /** + * ParseForm populates r.Form and r.PostForm. + * + * For all requests, ParseForm parses the raw query from the URL and updates + * r.Form. + * + * For POST, PUT, and PATCH requests, it also reads the request body, parses it + * as a form and puts the results into both r.PostForm and r.Form. Request body + * parameters take precedence over URL query string values in r.Form. + * + * If the request Body's size has not already been limited by [MaxBytesReader], + * the size is capped at 10MB. + * + * For other HTTP methods, or when the Content-Type is not + * application/x-www-form-urlencoded, the request Body is not read, and + * r.PostForm is initialized to a non-nil, empty value. + * + * [Request.ParseMultipartForm] calls ParseForm automatically. + * ParseForm is idempotent. + */ + parseForm(): void + } + interface Request { + /** + * ParseMultipartForm parses a request body as multipart/form-data. + * The whole request body is parsed and up to a total of maxMemory bytes of + * its file parts are stored in memory, with the remainder stored on + * disk in temporary files. + * ParseMultipartForm calls [Request.ParseForm] if necessary. + * If ParseForm returns an error, ParseMultipartForm returns it but also + * continues parsing the request body. + * After one call to ParseMultipartForm, subsequent calls have no effect. + */ + parseMultipartForm(maxMemory: number): void + } + interface Request { + /** + * FormValue returns the first value for the named component of the query. + * The precedence order: + * 1. application/x-www-form-urlencoded form body (POST, PUT, PATCH only) + * 2. query parameters (always) + * 3. multipart/form-data form body (always) + * + * FormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] + * if necessary and ignores any errors returned by these functions. + * If key is not present, FormValue returns the empty string. + * To access multiple values of the same key, call ParseForm and + * then inspect [Request.Form] directly. + */ + formValue(key: string): string + } + interface Request { + /** + * PostFormValue returns the first value for the named component of the POST, + * PUT, or PATCH request body. URL query parameters are ignored. + * PostFormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary and ignores + * any errors returned by these functions. + * If key is not present, PostFormValue returns the empty string. + */ + postFormValue(key: string): string + } + interface Request { + /** + * FormFile returns the first file for the provided form key. + * FormFile calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary. + */ + formFile(key: string): [multipart.File, (multipart.FileHeader)] + } + interface Request { + /** + * PathValue returns the value for the named path wildcard in the [ServeMux] pattern + * that matched the request. + * It returns the empty string if the request was not matched against a pattern + * or there is no such wildcard in the pattern. + */ + pathValue(name: string): string + } + interface Request { + /** + * SetPathValue sets name to value, so that subsequent calls to r.PathValue(name) + * return value. + */ + setPathValue(name: string, value: string): void + } + /** + * A Handler responds to an HTTP request. + * + * [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter] + * and then return. Returning signals that the request is finished; it + * is not valid to use the [ResponseWriter] or read from the + * [Request.Body] after or concurrently with the completion of the + * ServeHTTP call. + * + * Depending on the HTTP client software, HTTP protocol version, and + * any intermediaries between the client and the Go server, it may not + * be possible to read from the [Request.Body] after writing to the + * [ResponseWriter]. Cautious handlers should read the [Request.Body] + * first, and then reply. + * + * Except for reading the body, handlers should not modify the + * provided Request. + * + * If ServeHTTP panics, the server (the caller of ServeHTTP) assumes + * that the effect of the panic was isolated to the active request. + * It recovers the panic, logs a stack trace to the server error log, + * and either closes the network connection or sends an HTTP/2 + * RST_STREAM, depending on the HTTP protocol. To abort a handler so + * the client sees an interrupted response but the server doesn't log + * an error, panic with the value [ErrAbortHandler]. + */ + interface Handler { + [key:string]: any; + serveHTTP(_arg0: ResponseWriter, _arg1: Request): void + } + /** + * A ResponseWriter interface is used by an HTTP handler to + * construct an HTTP response. + * + * A ResponseWriter may not be used after [Handler.ServeHTTP] has returned. + */ + interface ResponseWriter { + [key:string]: any; + /** + * Header returns the header map that will be sent by + * [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which + * [Handler] implementations can set HTTP trailers. + * + * Changing the header map after a call to [ResponseWriter.WriteHeader] (or + * [ResponseWriter.Write]) has no effect unless the HTTP status code was of the + * 1xx class or the modified headers are trailers. + * + * There are two ways to set Trailers. The preferred way is to + * predeclare in the headers which trailers you will later + * send by setting the "Trailer" header to the names of the + * trailer keys which will come later. In this case, those + * keys of the Header map are treated as if they were + * trailers. See the example. The second way, for trailer + * keys not known to the [Handler] until after the first [ResponseWriter.Write], + * is to prefix the [Header] map keys with the [TrailerPrefix] + * constant value. + * + * To suppress automatic response headers (such as "Date"), set + * their value to nil. + */ + header(): Header + /** + * Write writes the data to the connection as part of an HTTP reply. + * + * If [ResponseWriter.WriteHeader] has not yet been called, Write calls + * WriteHeader(http.StatusOK) before writing the data. If the Header + * does not contain a Content-Type line, Write adds a Content-Type set + * to the result of passing the initial 512 bytes of written data to + * [DetectContentType]. Additionally, if the total size of all written + * data is under a few KB and there are no Flush calls, the + * Content-Length header is added automatically. + * + * Depending on the HTTP protocol version and the client, calling + * Write or WriteHeader may prevent future reads on the + * Request.Body. For HTTP/1.x requests, handlers should read any + * needed request body data before writing the response. Once the + * headers have been flushed (due to either an explicit Flusher.Flush + * call or writing enough data to trigger a flush), the request body + * may be unavailable. For HTTP/2 requests, the Go HTTP server permits + * handlers to continue to read the request body while concurrently + * writing the response. However, such behavior may not be supported + * by all HTTP/2 clients. Handlers should read before writing if + * possible to maximize compatibility. + */ + write(_arg0: string|Array): number + /** + * WriteHeader sends an HTTP response header with the provided + * status code. + * + * If WriteHeader is not called explicitly, the first call to Write + * will trigger an implicit WriteHeader(http.StatusOK). + * Thus explicit calls to WriteHeader are mainly used to + * send error codes or 1xx informational responses. + * + * The provided code must be a valid HTTP 1xx-5xx status code. + * Any number of 1xx headers may be written, followed by at most + * one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx + * headers may be buffered. Use the Flusher interface to send + * buffered data. The header map is cleared when 2xx-5xx headers are + * sent, but not with 1xx headers. + * + * The server will automatically send a 100 (Continue) header + * on the first read from the request body if the request has + * an "Expect: 100-continue" header. + */ + writeHeader(statusCode: number): void + } + /** + * A Server defines parameters for running an HTTP server. + * The zero value for Server is a valid configuration. + */ + interface Server { + /** + * Addr optionally specifies the TCP address for the server to listen on, + * in the form "host:port". If empty, ":http" (port 80) is used. + * The service names are defined in RFC 6335 and assigned by IANA. + * See net.Dial for details of the address format. + */ + addr: string + handler: Handler // handler to invoke, http.DefaultServeMux if nil + /** + * DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler, + * otherwise responds with 200 OK and Content-Length: 0. + */ + disableGeneralOptionsHandler: boolean + /** + * TLSConfig optionally provides a TLS configuration for use + * by ServeTLS and ListenAndServeTLS. Note that this value is + * cloned by ServeTLS and ListenAndServeTLS, so it's not + * possible to modify the configuration with methods like + * tls.Config.SetSessionTicketKeys. To use + * SetSessionTicketKeys, use Server.Serve with a TLS Listener + * instead. + */ + tlsConfig?: any + /** + * ReadTimeout is the maximum duration for reading the entire + * request, including the body. A zero or negative value means + * there will be no timeout. + * + * Because ReadTimeout does not let Handlers make per-request + * decisions on each request body's acceptable deadline or + * upload rate, most users will prefer to use + * ReadHeaderTimeout. It is valid to use them both. + */ + readTimeout: time.Duration + /** + * ReadHeaderTimeout is the amount of time allowed to read + * request headers. The connection's read deadline is reset + * after reading the headers and the Handler can decide what + * is considered too slow for the body. If zero, the value of + * ReadTimeout is used. If negative, or if zero and ReadTimeout + * is zero or negative, there is no timeout. + */ + readHeaderTimeout: time.Duration + /** + * WriteTimeout is the maximum duration before timing out + * writes of the response. It is reset whenever a new + * request's header is read. Like ReadTimeout, it does not + * let Handlers make decisions on a per-request basis. + * A zero or negative value means there will be no timeout. + */ + writeTimeout: time.Duration + /** + * IdleTimeout is the maximum amount of time to wait for the + * next request when keep-alives are enabled. If zero, the value + * of ReadTimeout is used. If negative, or if zero and ReadTimeout + * is zero or negative, there is no timeout. + */ + idleTimeout: time.Duration + /** + * MaxHeaderBytes controls the maximum number of bytes the + * server will read parsing the request header's keys and + * values, including the request line. It does not limit the + * size of the request body. + * If zero, DefaultMaxHeaderBytes is used. + */ + maxHeaderBytes: number + /** + * TLSNextProto optionally specifies a function to take over + * ownership of the provided TLS connection when an ALPN + * protocol upgrade has occurred. The map key is the protocol + * name negotiated. The Handler argument should be used to + * handle HTTP requests and will initialize the Request's TLS + * and RemoteAddr if not already set. The connection is + * automatically closed when the function returns. + * If TLSNextProto is not nil, HTTP/2 support is not enabled + * automatically. + */ + tlsNextProto: _TygojaDict + /** + * ConnState specifies an optional callback function that is + * called when a client connection changes state. See the + * ConnState type and associated constants for details. + */ + connState: (_arg0: net.Conn, _arg1: ConnState) => void + /** + * ErrorLog specifies an optional logger for errors accepting + * connections, unexpected behavior from handlers, and + * underlying FileSystem errors. + * If nil, logging is done via the log package's standard logger. + */ + errorLog?: any + /** + * BaseContext optionally specifies a function that returns + * the base context for incoming requests on this server. + * The provided Listener is the specific Listener that's + * about to start accepting requests. + * If BaseContext is nil, the default is context.Background(). + * If non-nil, it must return a non-nil context. + */ + baseContext: (_arg0: net.Listener) => context.Context + /** + * ConnContext optionally specifies a function that modifies + * the context used for a new connection c. The provided ctx + * is derived from the base context and has a ServerContextKey + * value. + */ + connContext: (ctx: context.Context, c: net.Conn) => context.Context + /** + * HTTP2 configures HTTP/2 connections. + * + * This field does not yet have any effect. + * See https://go.dev/issue/67813. + */ + http2?: HTTP2Config + /** + * Protocols is the set of protocols accepted by the server. + * + * If Protocols includes UnencryptedHTTP2, the server will accept + * unencrypted HTTP/2 connections. The server can serve both + * HTTP/1 and unencrypted HTTP/2 on the same address and port. + * + * If Protocols is nil, the default is usually HTTP/1 and HTTP/2. + * If TLSNextProto is non-nil and does not contain an "h2" entry, + * the default is HTTP/1 only. + */ + protocols?: Protocols + } + interface Server { + /** + * Close immediately closes all active net.Listeners and any + * connections in state [StateNew], [StateActive], or [StateIdle]. For a + * graceful shutdown, use [Server.Shutdown]. + * + * Close does not attempt to close (and does not even know about) + * any hijacked connections, such as WebSockets. + * + * Close returns any error returned from closing the [Server]'s + * underlying Listener(s). + */ + close(): void + } + interface Server { + /** + * Shutdown gracefully shuts down the server without interrupting any + * active connections. Shutdown works by first closing all open + * listeners, then closing all idle connections, and then waiting + * indefinitely for connections to return to idle and then shut down. + * If the provided context expires before the shutdown is complete, + * Shutdown returns the context's error, otherwise it returns any + * error returned from closing the [Server]'s underlying Listener(s). + * + * When Shutdown is called, [Serve], [ListenAndServe], and + * [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the + * program doesn't exit and waits instead for Shutdown to return. + * + * Shutdown does not attempt to close nor wait for hijacked + * connections such as WebSockets. The caller of Shutdown should + * separately notify such long-lived connections of shutdown and wait + * for them to close, if desired. See [Server.RegisterOnShutdown] for a way to + * register shutdown notification functions. + * + * Once Shutdown has been called on a server, it may not be reused; + * future calls to methods such as Serve will return ErrServerClosed. + */ + shutdown(ctx: context.Context): void + } + interface Server { + /** + * RegisterOnShutdown registers a function to call on [Server.Shutdown]. + * This can be used to gracefully shutdown connections that have + * undergone ALPN protocol upgrade or that have been hijacked. + * This function should start protocol-specific graceful shutdown, + * but should not wait for shutdown to complete. + */ + registerOnShutdown(f: () => void): void + } + interface Server { + /** + * ListenAndServe listens on the TCP network address s.Addr and then + * calls [Serve] to handle requests on incoming connections. + * Accepted connections are configured to enable TCP keep-alives. + * + * If s.Addr is blank, ":http" is used. + * + * ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close], + * the returned error is [ErrServerClosed]. + */ + listenAndServe(): void + } + interface Server { + /** + * Serve accepts incoming connections on the Listener l, creating a + * new service goroutine for each. The service goroutines read requests and + * then call s.Handler to reply to them. + * + * HTTP/2 support is only enabled if the Listener returns [*tls.Conn] + * connections and they were configured with "h2" in the TLS + * Config.NextProtos. + * + * Serve always returns a non-nil error and closes l. + * After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed]. + */ + serve(l: net.Listener): void + } + interface Server { + /** + * ServeTLS accepts incoming connections on the Listener l, creating a + * new service goroutine for each. The service goroutines perform TLS + * setup and then read requests, calling s.Handler to reply to them. + * + * Files containing a certificate and matching private key for the + * server must be provided if neither the [Server]'s + * TLSConfig.Certificates, TLSConfig.GetCertificate nor + * config.GetConfigForClient are populated. + * If the certificate is signed by a certificate authority, the + * certFile should be the concatenation of the server's certificate, + * any intermediates, and the CA's certificate. + * + * ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the + * returned error is [ErrServerClosed]. + */ + serveTLS(l: net.Listener, certFile: string, keyFile: string): void + } + interface Server { + /** + * SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. + * By default, keep-alives are always enabled. Only very + * resource-constrained environments or servers in the process of + * shutting down should disable them. + */ + setKeepAlivesEnabled(v: boolean): void + } + interface Server { + /** + * ListenAndServeTLS listens on the TCP network address s.Addr and + * then calls [ServeTLS] to handle requests on incoming TLS connections. + * Accepted connections are configured to enable TCP keep-alives. + * + * Filenames containing a certificate and matching private key for the + * server must be provided if neither the [Server]'s TLSConfig.Certificates + * nor TLSConfig.GetCertificate are populated. If the certificate is + * signed by a certificate authority, the certFile should be the + * concatenation of the server's certificate, any intermediates, and + * the CA's certificate. + * + * If s.Addr is blank, ":https" is used. + * + * ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or + * [Server.Close], the returned error is [ErrServerClosed]. + */ + listenAndServeTLS(certFile: string, keyFile: string): void + } +} + +namespace auth { + /** + * Provider defines a common interface for an OAuth2 client. + */ + interface Provider { + [key:string]: any; + /** + * Context returns the context associated with the provider (if any). + */ + context(): context.Context + /** + * SetContext assigns the specified context to the current provider. + */ + setContext(ctx: context.Context): void + /** + * PKCE indicates whether the provider can use the PKCE flow. + */ + pkce(): boolean + /** + * SetPKCE toggles the state whether the provider can use the PKCE flow or not. + */ + setPKCE(enable: boolean): void + /** + * DisplayName usually returns provider name as it is officially written + * and it could be used directly in the UI. + */ + displayName(): string + /** + * SetDisplayName sets the provider's display name. + */ + setDisplayName(displayName: string): void + /** + * Scopes returns the provider access permissions that will be requested. + */ + scopes(): Array + /** + * SetScopes sets the provider access permissions that will be requested later. + */ + setScopes(scopes: Array): void + /** + * ClientId returns the provider client's app ID. + */ + clientId(): string + /** + * SetClientId sets the provider client's ID. + */ + setClientId(clientId: string): void + /** + * ClientSecret returns the provider client's app secret. + */ + clientSecret(): string + /** + * SetClientSecret sets the provider client's app secret. + */ + setClientSecret(secret: string): void + /** + * RedirectURL returns the end address to redirect the user + * going through the OAuth flow. + */ + redirectURL(): string + /** + * SetRedirectURL sets the provider's RedirectURL. + */ + setRedirectURL(url: string): void + /** + * AuthURL returns the provider's authorization service url. + */ + authURL(): string + /** + * SetAuthURL sets the provider's AuthURL. + */ + setAuthURL(url: string): void + /** + * TokenURL returns the provider's token exchange service url. + */ + tokenURL(): string + /** + * SetTokenURL sets the provider's TokenURL. + */ + setTokenURL(url: string): void + /** + * UserInfoURL returns the provider's user info api url. + */ + userInfoURL(): string + /** + * SetUserInfoURL sets the provider's UserInfoURL. + */ + setUserInfoURL(url: string): void + /** + * Extra returns a shallow copy of any custom config data + * that the provider may be need. + */ + extra(): _TygojaDict + /** + * SetExtra updates the provider's custom config data. + */ + setExtra(data: _TygojaDict): void + /** + * Client returns an http client using the provided token. + */ + client(token: oauth2.Token): (any) + /** + * BuildAuthURL returns a URL to the provider's consent page + * that asks for permissions for the required scopes explicitly. + */ + buildAuthURL(state: string, ...opts: oauth2.AuthCodeOption[]): string + /** + * FetchToken converts an authorization code to token. + */ + fetchToken(code: string, ...opts: oauth2.AuthCodeOption[]): (oauth2.Token) + /** + * FetchRawUserInfo requests and marshalizes into `result` the + * the OAuth user api response. + */ + fetchRawUserInfo(token: oauth2.Token): string|Array + /** + * FetchAuthUser is similar to FetchRawUserInfo, but normalizes and + * marshalizes the user api response into a standardized AuthUser struct. + */ + fetchAuthUser(token: oauth2.Token): (AuthUser) + } + /** + * AuthUser defines a standardized OAuth2 user data structure. + */ + interface AuthUser { + expiry: types.DateTime + rawUser: _TygojaDict + id: string + name: string + username: string + email: string + avatarURL: string + accessToken: string + refreshToken: string + /** + * @todo + * deprecated: use AvatarURL instead + * AvatarUrl will be removed after dropping v0.22 support + */ + avatarUrl: string + } + interface AuthUser { + /** + * MarshalJSON implements the [json.Marshaler] interface. + * + * @todo remove after dropping v0.22 support + */ + marshalJSON(): string|Array + } +} + +/** + * Package slog provides structured logging, + * in which log records include a message, + * a severity level, and various other attributes + * expressed as key-value pairs. + * + * It defines a type, [Logger], + * which provides several methods (such as [Logger.Info] and [Logger.Error]) + * for reporting events of interest. + * + * Each Logger is associated with a [Handler]. + * A Logger output method creates a [Record] from the method arguments + * and passes it to the Handler, which decides how to handle it. + * There is a default Logger accessible through top-level functions + * (such as [Info] and [Error]) that call the corresponding Logger methods. + * + * A log record consists of a time, a level, a message, and a set of key-value + * pairs, where the keys are strings and the values may be of any type. + * As an example, + * + * ``` + * slog.Info("hello", "count", 3) + * ``` + * + * creates a record containing the time of the call, + * a level of Info, the message "hello", and a single + * pair with key "count" and value 3. + * + * The [Info] top-level function calls the [Logger.Info] method on the default Logger. + * In addition to [Logger.Info], there are methods for Debug, Warn and Error levels. + * Besides these convenience methods for common levels, + * there is also a [Logger.Log] method which takes the level as an argument. + * Each of these methods has a corresponding top-level function that uses the + * default logger. + * + * The default handler formats the log record's message, time, level, and attributes + * as a string and passes it to the [log] package. + * + * ``` + * 2022/11/08 15:28:26 INFO hello count=3 + * ``` + * + * For more control over the output format, create a logger with a different handler. + * This statement uses [New] to create a new logger with a [TextHandler] + * that writes structured records in text form to standard error: + * + * ``` + * logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) + * ``` + * + * [TextHandler] output is a sequence of key=value pairs, easily and unambiguously + * parsed by machine. This statement: + * + * ``` + * logger.Info("hello", "count", 3) + * ``` + * + * produces this output: + * + * ``` + * time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3 + * ``` + * + * The package also provides [JSONHandler], whose output is line-delimited JSON: + * + * ``` + * logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + * logger.Info("hello", "count", 3) + * ``` + * + * produces this output: + * + * ``` + * {"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3} + * ``` + * + * Both [TextHandler] and [JSONHandler] can be configured with [HandlerOptions]. + * There are options for setting the minimum level (see Levels, below), + * displaying the source file and line of the log call, and + * modifying attributes before they are logged. + * + * Setting a logger as the default with + * + * ``` + * slog.SetDefault(logger) + * ``` + * + * will cause the top-level functions like [Info] to use it. + * [SetDefault] also updates the default logger used by the [log] package, + * so that existing applications that use [log.Printf] and related functions + * will send log records to the logger's handler without needing to be rewritten. + * + * Some attributes are common to many log calls. + * For example, you may wish to include the URL or trace identifier of a server request + * with all log events arising from the request. + * Rather than repeat the attribute with every log call, you can use [Logger.With] + * to construct a new Logger containing the attributes: + * + * ``` + * logger2 := logger.With("url", r.URL) + * ``` + * + * The arguments to With are the same key-value pairs used in [Logger.Info]. + * The result is a new Logger with the same handler as the original, but additional + * attributes that will appear in the output of every call. + * + * # Levels + * + * A [Level] is an integer representing the importance or severity of a log event. + * The higher the level, the more severe the event. + * This package defines constants for the most common levels, + * but any int can be used as a level. + * + * In an application, you may wish to log messages only at a certain level or greater. + * One common configuration is to log messages at Info or higher levels, + * suppressing debug logging until it is needed. + * The built-in handlers can be configured with the minimum level to output by + * setting [HandlerOptions.Level]. + * The program's `main` function typically does this. + * The default value is LevelInfo. + * + * Setting the [HandlerOptions.Level] field to a [Level] value + * fixes the handler's minimum level throughout its lifetime. + * Setting it to a [LevelVar] allows the level to be varied dynamically. + * A LevelVar holds a Level and is safe to read or write from multiple + * goroutines. + * To vary the level dynamically for an entire program, first initialize + * a global LevelVar: + * + * ``` + * var programLevel = new(slog.LevelVar) // Info by default + * ``` + * + * Then use the LevelVar to construct a handler, and make it the default: + * + * ``` + * h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel}) + * slog.SetDefault(slog.New(h)) + * ``` + * + * Now the program can change its logging level with a single statement: + * + * ``` + * programLevel.Set(slog.LevelDebug) + * ``` + * + * # Groups + * + * Attributes can be collected into groups. + * A group has a name that is used to qualify the names of its attributes. + * How this qualification is displayed depends on the handler. + * [TextHandler] separates the group and attribute names with a dot. + * [JSONHandler] treats each group as a separate JSON object, with the group name as the key. + * + * Use [Group] to create a Group attribute from a name and a list of key-value pairs: + * + * ``` + * slog.Group("request", + * "method", r.Method, + * "url", r.URL) + * ``` + * + * TextHandler would display this group as + * + * ``` + * request.method=GET request.url=http://example.com + * ``` + * + * JSONHandler would display it as + * + * ``` + * "request":{"method":"GET","url":"http://example.com"} + * ``` + * + * Use [Logger.WithGroup] to qualify all of a Logger's output + * with a group name. Calling WithGroup on a Logger results in a + * new Logger with the same Handler as the original, but with all + * its attributes qualified by the group name. + * + * This can help prevent duplicate attribute keys in large systems, + * where subsystems might use the same keys. + * Pass each subsystem a different Logger with its own group name so that + * potential duplicates are qualified: + * + * ``` + * logger := slog.Default().With("id", systemID) + * parserLogger := logger.WithGroup("parser") + * parseInput(input, parserLogger) + * ``` + * + * When parseInput logs with parserLogger, its keys will be qualified with "parser", + * so even if it uses the common key "id", the log line will have distinct keys. + * + * # Contexts + * + * Some handlers may wish to include information from the [context.Context] that is + * available at the call site. One example of such information + * is the identifier for the current span when tracing is enabled. + * + * The [Logger.Log] and [Logger.LogAttrs] methods take a context as a first + * argument, as do their corresponding top-level functions. + * + * Although the convenience methods on Logger (Info and so on) and the + * corresponding top-level functions do not take a context, the alternatives ending + * in "Context" do. For example, + * + * ``` + * slog.InfoContext(ctx, "message") + * ``` + * + * It is recommended to pass a context to an output method if one is available. + * + * # Attrs and Values + * + * An [Attr] is a key-value pair. The Logger output methods accept Attrs as well as + * alternating keys and values. The statement + * + * ``` + * slog.Info("hello", slog.Int("count", 3)) + * ``` + * + * behaves the same as + * + * ``` + * slog.Info("hello", "count", 3) + * ``` + * + * There are convenience constructors for [Attr] such as [Int], [String], and [Bool] + * for common types, as well as the function [Any] for constructing Attrs of any + * type. + * + * The value part of an Attr is a type called [Value]. + * Like an [any], a Value can hold any Go value, + * but it can represent typical values, including all numbers and strings, + * without an allocation. + * + * For the most efficient log output, use [Logger.LogAttrs]. + * It is similar to [Logger.Log] but accepts only Attrs, not alternating + * keys and values; this allows it, too, to avoid allocation. + * + * The call + * + * ``` + * logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3)) + * ``` + * + * is the most efficient way to achieve the same output as + * + * ``` + * slog.InfoContext(ctx, "hello", "count", 3) + * ``` + * + * # Customizing a type's logging behavior + * + * If a type implements the [LogValuer] interface, the [Value] returned from its LogValue + * method is used for logging. You can use this to control how values of the type + * appear in logs. For example, you can redact secret information like passwords, + * or gather a struct's fields in a Group. See the examples under [LogValuer] for + * details. + * + * A LogValue method may return a Value that itself implements [LogValuer]. The [Value.Resolve] + * method handles these cases carefully, avoiding infinite loops and unbounded recursion. + * Handler authors and others may wish to use [Value.Resolve] instead of calling LogValue directly. + * + * # Wrapping output methods + * + * The logger functions use reflection over the call stack to find the file name + * and line number of the logging call within the application. This can produce + * incorrect source information for functions that wrap slog. For instance, if you + * define this function in file mylog.go: + * + * ``` + * func Infof(logger *slog.Logger, format string, args ...any) { + * logger.Info(fmt.Sprintf(format, args...)) + * } + * ``` + * + * and you call it like this in main.go: + * + * ``` + * Infof(slog.Default(), "hello, %s", "world") + * ``` + * + * then slog will report the source file as mylog.go, not main.go. + * + * A correct implementation of Infof will obtain the source location + * (pc) and pass it to NewRecord. + * The Infof function in the package-level example called "wrapping" + * demonstrates how to do this. + * + * # Working with Records + * + * Sometimes a Handler will need to modify a Record + * before passing it on to another Handler or backend. + * A Record contains a mixture of simple public fields (e.g. Time, Level, Message) + * and hidden fields that refer to state (such as attributes) indirectly. This + * means that modifying a simple copy of a Record (e.g. by calling + * [Record.Add] or [Record.AddAttrs] to add attributes) + * may have unexpected effects on the original. + * Before modifying a Record, use [Record.Clone] to + * create a copy that shares no state with the original, + * or create a new Record with [NewRecord] + * and build up its Attrs by traversing the old ones with [Record.Attrs]. + * + * # Performance considerations + * + * If profiling your application demonstrates that logging is taking significant time, + * the following suggestions may help. + * + * If many log lines have a common attribute, use [Logger.With] to create a Logger with + * that attribute. The built-in handlers will format that attribute only once, at the + * call to [Logger.With]. The [Handler] interface is designed to allow that optimization, + * and a well-written Handler should take advantage of it. + * + * The arguments to a log call are always evaluated, even if the log event is discarded. + * If possible, defer computation so that it happens only if the value is actually logged. + * For example, consider the call + * + * ``` + * slog.Info("starting request", "url", r.URL.String()) // may compute String unnecessarily + * ``` + * + * The URL.String method will be called even if the logger discards Info-level events. + * Instead, pass the URL directly: + * + * ``` + * slog.Info("starting request", "url", &r.URL) // calls URL.String only if needed + * ``` + * + * The built-in [TextHandler] will call its String method, but only + * if the log event is enabled. + * Avoiding the call to String also preserves the structure of the underlying value. + * For example [JSONHandler] emits the components of the parsed URL as a JSON object. + * If you want to avoid eagerly paying the cost of the String call + * without causing the handler to potentially inspect the structure of the value, + * wrap the value in a fmt.Stringer implementation that hides its Marshal methods. + * + * You can also use the [LogValuer] interface to avoid unnecessary work in disabled log + * calls. Say you need to log some expensive value: + * + * ``` + * slog.Debug("frobbing", "value", computeExpensiveValue(arg)) + * ``` + * + * Even if this line is disabled, computeExpensiveValue will be called. + * To avoid that, define a type implementing LogValuer: + * + * ``` + * type expensive struct { arg int } + * + * func (e expensive) LogValue() slog.Value { + * return slog.AnyValue(computeExpensiveValue(e.arg)) + * } + * ``` + * + * Then use a value of that type in log calls: + * + * ``` + * slog.Debug("frobbing", "value", expensive{arg}) + * ``` + * + * Now computeExpensiveValue will only be called when the line is enabled. + * + * The built-in handlers acquire a lock before calling [io.Writer.Write] + * to ensure that exactly one [Record] is written at a time in its entirety. + * Although each log record has a timestamp, + * the built-in handlers do not use that time to sort the written records. + * User-defined handlers are responsible for their own locking and sorting. + * + * # Writing a handler + * + * For a guide to writing a custom handler, see https://golang.org/s/slog-handler-guide. + */ +namespace slog { + // @ts-ignore + import loginternal = internal + /** + * A Logger records structured information about each call to its + * Log, Debug, Info, Warn, and Error methods. + * For each call, it creates a [Record] and passes it to a [Handler]. + * + * To create a new Logger, call [New] or a Logger method + * that begins "With". + */ + interface Logger { + } + interface Logger { + /** + * Handler returns l's Handler. + */ + handler(): Handler + } + interface Logger { + /** + * With returns a Logger that includes the given attributes + * in each output operation. Arguments are converted to + * attributes as if by [Logger.Log]. + */ + with(...args: any[]): (Logger) + } + interface Logger { + /** + * WithGroup returns a Logger that starts a group, if name is non-empty. + * The keys of all attributes added to the Logger will be qualified by the given + * name. (How that qualification happens depends on the [Handler.WithGroup] + * method of the Logger's Handler.) + * + * If name is empty, WithGroup returns the receiver. + */ + withGroup(name: string): (Logger) + } + interface Logger { + /** + * Enabled reports whether l emits log records at the given context and level. + */ + enabled(ctx: context.Context, level: Level): boolean + } + interface Logger { + /** + * Log emits a log record with the current time and the given level and message. + * The Record's Attrs consist of the Logger's attributes followed by + * the Attrs specified by args. + * + * The attribute arguments are processed as follows: + * ``` + * - If an argument is an Attr, it is used as is. + * - If an argument is a string and this is not the last argument, + * the following argument is treated as the value and the two are combined + * into an Attr. + * - Otherwise, the argument is treated as a value with key "!BADKEY". + * ``` + */ + log(ctx: context.Context, level: Level, msg: string, ...args: any[]): void + } + interface Logger { + /** + * LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs. + */ + logAttrs(ctx: context.Context, level: Level, msg: string, ...attrs: Attr[]): void + } + interface Logger { + /** + * Debug logs at [LevelDebug]. + */ + debug(msg: string, ...args: any[]): void + } + interface Logger { + /** + * DebugContext logs at [LevelDebug] with the given context. + */ + debugContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Info logs at [LevelInfo]. + */ + info(msg: string, ...args: any[]): void + } + interface Logger { + /** + * InfoContext logs at [LevelInfo] with the given context. + */ + infoContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Warn logs at [LevelWarn]. + */ + warn(msg: string, ...args: any[]): void + } + interface Logger { + /** + * WarnContext logs at [LevelWarn] with the given context. + */ + warnContext(ctx: context.Context, msg: string, ...args: any[]): void + } + interface Logger { + /** + * Error logs at [LevelError]. + */ + error(msg: string, ...args: any[]): void + } + interface Logger { + /** + * ErrorContext logs at [LevelError] with the given context. + */ + errorContext(ctx: context.Context, msg: string, ...args: any[]): void + } +} + +/** + * Package sql provides a generic interface around SQL (or SQL-like) + * databases. + * + * The sql package must be used in conjunction with a database driver. + * See https://golang.org/s/sqldrivers for a list of drivers. + * + * Drivers that do not support context cancellation will not return until + * after the query is completed. + * + * For usage examples, see the wiki page at + * https://golang.org/s/sqlwiki. + */ +namespace sql { + /** + * TxOptions holds the transaction options to be used in [DB.BeginTx]. + */ + interface TxOptions { + /** + * Isolation is the transaction isolation level. + * If zero, the driver or database's default level is used. + */ + isolation: IsolationLevel + readOnly: boolean + } + /** + * NullString represents a string that may be null. + * NullString implements the [Scanner] interface so + * it can be used as a scan destination: + * + * ``` + * var s NullString + * err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) + * ... + * if s.Valid { + * // use s.String + * } else { + * // NULL value + * } + * ``` + */ + interface NullString { + string: string + valid: boolean // Valid is true if String is not NULL + } + interface NullString { + /** + * Scan implements the [Scanner] interface. + */ + scan(value: any): void + } + interface NullString { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + /** + * DB is a database handle representing a pool of zero or more + * underlying connections. It's safe for concurrent use by multiple + * goroutines. + * + * The sql package creates and frees connections automatically; it + * also maintains a free pool of idle connections. If the database has + * a concept of per-connection state, such state can be reliably observed + * within a transaction ([Tx]) or connection ([Conn]). Once [DB.Begin] is called, the + * returned [Tx] is bound to a single connection. Once [Tx.Commit] or + * [Tx.Rollback] is called on the transaction, that transaction's + * connection is returned to [DB]'s idle connection pool. The pool size + * can be controlled with [DB.SetMaxIdleConns]. + */ + interface DB { + } + interface DB { + /** + * PingContext verifies a connection to the database is still alive, + * establishing a connection if necessary. + */ + pingContext(ctx: context.Context): void + } + interface DB { + /** + * Ping verifies a connection to the database is still alive, + * establishing a connection if necessary. + * + * Ping uses [context.Background] internally; to specify the context, use + * [DB.PingContext]. + */ + ping(): void + } + interface DB { + /** + * Close closes the database and prevents new queries from starting. + * Close then waits for all queries that have started processing on the server + * to finish. + * + * It is rare to Close a [DB], as the [DB] handle is meant to be + * long-lived and shared between many goroutines. + */ + close(): void + } + interface DB { + /** + * SetMaxIdleConns sets the maximum number of connections in the idle + * connection pool. + * + * If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, + * then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. + * + * If n <= 0, no idle connections are retained. + * + * The default max idle connections is currently 2. This may change in + * a future release. + */ + setMaxIdleConns(n: number): void + } + interface DB { + /** + * SetMaxOpenConns sets the maximum number of open connections to the database. + * + * If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than + * MaxIdleConns, then MaxIdleConns will be reduced to match the new + * MaxOpenConns limit. + * + * If n <= 0, then there is no limit on the number of open connections. + * The default is 0 (unlimited). + */ + setMaxOpenConns(n: number): void + } + interface DB { + /** + * SetConnMaxLifetime sets the maximum amount of time a connection may be reused. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's age. + */ + setConnMaxLifetime(d: time.Duration): void + } + interface DB { + /** + * SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's idle time. + */ + setConnMaxIdleTime(d: time.Duration): void + } + interface DB { + /** + * Stats returns database statistics. + */ + stats(): DBStats + } + interface DB { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface DB { + /** + * Prepare creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [DB.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface DB { + /** + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface DB { + /** + * Exec executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + * + * Exec uses [context.Background] internally; to specify the context, use + * [DB.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface DB { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * Query executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + * + * Query uses [context.Background] internally; to specify the context, use + * [DB.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface DB { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [DB.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + interface DB { + /** + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. + */ + beginTx(ctx: context.Context, opts: TxOptions): (Tx) + } + interface DB { + /** + * Begin starts a transaction. The default isolation level is dependent on + * the driver. + * + * Begin uses [context.Background] internally; to specify the context, use + * [DB.BeginTx]. + */ + begin(): (Tx) + } + interface DB { + /** + * Driver returns the database's underlying driver. + */ + driver(): any + } + interface DB { + /** + * Conn returns a single connection by either opening a new connection + * or returning an existing connection from the connection pool. Conn will + * block until either a connection is returned or ctx is canceled. + * Queries run on the same Conn will be run in the same database session. + * + * Every Conn must be returned to the database pool after use by + * calling [Conn.Close]. + */ + conn(ctx: context.Context): (Conn) + } + /** + * Tx is an in-progress database transaction. + * + * A transaction must end with a call to [Tx.Commit] or [Tx.Rollback]. + * + * After a call to [Tx.Commit] or [Tx.Rollback], all operations on the + * transaction fail with [ErrTxDone]. + * + * The statements prepared for a transaction by calling + * the transaction's [Tx.Prepare] or [Tx.Stmt] methods are closed + * by the call to [Tx.Commit] or [Tx.Rollback]. + */ + interface Tx { + } + interface Tx { + /** + * Commit commits the transaction. + */ + commit(): void + } + interface Tx { + /** + * Rollback aborts the transaction. + */ + rollback(): void + } + interface Tx { + /** + * PrepareContext creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * The provided context will be used for the preparation of the context, not + * for the execution of the returned statement. The returned statement + * will run in the transaction context. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface Tx { + /** + * Prepare creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [Tx.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface Tx { + /** + * StmtContext returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) + * ``` + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + */ + stmtContext(ctx: context.Context, stmt: Stmt): (Stmt) + } + interface Tx { + /** + * Stmt returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) + * ``` + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * Stmt uses [context.Background] internally; to specify the context, use + * [Tx.StmtContext]. + */ + stmt(stmt: Stmt): (Stmt) + } + interface Tx { + /** + * ExecContext executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Tx { + /** + * Exec executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Tx.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface Tx { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * Query executes a query that returns rows, typically a SELECT. + * + * Query uses [context.Background] internally; to specify the context, use + * [Tx.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Tx { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Tx.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + /** + * Stmt is a prepared statement. + * A Stmt is safe for concurrent use by multiple goroutines. + * + * If a Stmt is prepared on a [Tx] or [Conn], it will be bound to a single + * underlying connection forever. If the [Tx] or [Conn] closes, the Stmt will + * become unusable and all operations will return an error. + * If a Stmt is prepared on a [DB], it will remain usable for the lifetime of the + * [DB]. When the Stmt needs to execute on a new underlying connection, it will + * prepare itself on the new connection automatically. + */ + interface Stmt { + } + interface Stmt { + /** + * ExecContext executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + */ + execContext(ctx: context.Context, ...args: any[]): Result + } + interface Stmt { + /** + * Exec executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Stmt.ExecContext]. + */ + exec(...args: any[]): Result + } + interface Stmt { + /** + * QueryContext executes a prepared query statement with the given arguments + * and returns the query results as a [*Rows]. + */ + queryContext(ctx: context.Context, ...args: any[]): (Rows) + } + interface Stmt { + /** + * Query executes a prepared query statement with the given arguments + * and returns the query results as a *Rows. + * + * Query uses [context.Background] internally; to specify the context, use + * [Stmt.QueryContext]. + */ + query(...args: any[]): (Rows) + } + interface Stmt { + /** + * QueryRowContext executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, ...args: any[]): (Row) + } + interface Stmt { + /** + * QueryRow executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * Example usage: + * + * ``` + * var name string + * err := nameByUseridStmt.QueryRow(id).Scan(&name) + * ``` + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Stmt.QueryRowContext]. + */ + queryRow(...args: any[]): (Row) + } + interface Stmt { + /** + * Close closes the statement. + */ + close(): void + } + /** + * Rows is the result of a query. Its cursor starts before the first row + * of the result set. Use [Rows.Next] to advance from row to row. + */ + interface Rows { + } + interface Rows { + /** + * Next prepares the next result row for reading with the [Rows.Scan] method. It + * returns true on success, or false if there is no next result row or an error + * happened while preparing it. [Rows.Err] should be consulted to distinguish between + * the two cases. + * + * Every call to [Rows.Scan], even the first one, must be preceded by a call to [Rows.Next]. + */ + next(): boolean + } + interface Rows { + /** + * NextResultSet prepares the next result set for reading. It reports whether + * there is further result sets, or false if there is no further result set + * or if there is an error advancing to it. The [Rows.Err] method should be consulted + * to distinguish between the two cases. + * + * After calling NextResultSet, the [Rows.Next] method should always be called before + * scanning. If there are further result sets they may not have rows in the result + * set. + */ + nextResultSet(): boolean + } + interface Rows { + /** + * Err returns the error, if any, that was encountered during iteration. + * Err may be called after an explicit or implicit [Rows.Close]. + */ + err(): void + } + interface Rows { + /** + * Columns returns the column names. + * Columns returns an error if the rows are closed. + */ + columns(): Array + } + interface Rows { + /** + * ColumnTypes returns column information such as column type, length, + * and nullable. Some information may not be available from some drivers. + */ + columnTypes(): Array<(ColumnType | undefined)> + } + interface Rows { + /** + * Scan copies the columns in the current row into the values pointed + * at by dest. The number of values in dest must be the same as the + * number of columns in [Rows]. + * + * Scan converts columns read from the database into the following + * common Go types and special types provided by the sql package: + * + * ``` + * *string + * *[]byte + * *int, *int8, *int16, *int32, *int64 + * *uint, *uint8, *uint16, *uint32, *uint64 + * *bool + * *float32, *float64 + * *interface{} + * *RawBytes + * *Rows (cursor value) + * any type implementing Scanner (see Scanner docs) + * ``` + * + * In the most simple case, if the type of the value from the source + * column is an integer, bool or string type T and dest is of type *T, + * Scan simply assigns the value through the pointer. + * + * Scan also converts between string and numeric types, as long as no + * information would be lost. While Scan stringifies all numbers + * scanned from numeric database columns into *string, scans into + * numeric types are checked for overflow. For example, a float64 with + * value 300 or a string with value "300" can scan into a uint16, but + * not into a uint8, though float64(255) or "255" can scan into a + * uint8. One exception is that scans of some float64 numbers to + * strings may lose information when stringifying. In general, scan + * floating point columns into *float64. + * + * If a dest argument has type *[]byte, Scan saves in that argument a + * copy of the corresponding data. The copy is owned by the caller and + * can be modified and held indefinitely. The copy can be avoided by + * using an argument of type [*RawBytes] instead; see the documentation + * for [RawBytes] for restrictions on its use. + * + * If an argument has type *interface{}, Scan copies the value + * provided by the underlying driver without conversion. When scanning + * from a source value of type []byte to *interface{}, a copy of the + * slice is made and the caller owns the result. + * + * Source values of type [time.Time] may be scanned into values of type + * *time.Time, *interface{}, *string, or *[]byte. When converting to + * the latter two, [time.RFC3339Nano] is used. + * + * Source values of type bool may be scanned into types *bool, + * *interface{}, *string, *[]byte, or [*RawBytes]. + * + * For scanning into *bool, the source may be true, false, 1, 0, or + * string inputs parseable by [strconv.ParseBool]. + * + * Scan can also convert a cursor returned from a query, such as + * "select cursor(select * from my_table) from dual", into a + * [*Rows] value that can itself be scanned from. The parent + * select query will close any cursor [*Rows] if the parent [*Rows] is closed. + * + * If any of the first arguments implementing [Scanner] returns an error, + * that error will be wrapped in the returned error. + */ + scan(...dest: any[]): void + } + interface Rows { + /** + * Close closes the [Rows], preventing further enumeration. If [Rows.Next] is called + * and returns false and there are no further result sets, + * the [Rows] are closed automatically and it will suffice to check the + * result of [Rows.Err]. Close is idempotent and does not affect the result of [Rows.Err]. + */ + close(): void + } + /** + * A Result summarizes an executed SQL command. + */ + interface Result { + [key:string]: any; + /** + * LastInsertId returns the integer generated by the database + * in response to a command. Typically this will be from an + * "auto increment" column when inserting a new row. Not all + * databases support this feature, and the syntax of such + * statements varies. + */ + lastInsertId(): number + /** + * RowsAffected returns the number of rows affected by an + * update, insert, or delete. Not every database or database + * driver may support this. + */ + rowsAffected(): number + } +} + +/** + * Package blob defines a lightweight abstration for interacting with + * various storage services (local filesystem, S3, etc.). + * + * NB! + * For compatibility with earlier PocketBase versions and to prevent + * unnecessary breaking changes, this package is based and implemented + * as a minimal, stripped down version of the previously used gocloud.dev/blob. + * While there is no promise that it won't diverge in the future to accommodate + * better some PocketBase specific use cases, currently it copies and + * tries to follow as close as possible the same implementations, + * conventions and rules for the key escaping/unescaping, blob read/write + * interfaces and struct options as gocloud.dev/blob, therefore the + * credits goes to the original Go Cloud Development Kit Authors. + */ +namespace blob { + /** + * ListObject represents a single blob returned from List. + */ + interface ListObject { + /** + * Key is the key for this blob. + */ + key: string + /** + * ModTime is the time the blob was last modified. + */ + modTime: time.Time + /** + * Size is the size of the blob's content in bytes. + */ + size: number + /** + * MD5 is an MD5 hash of the blob contents or nil if not available. + */ + md5: string|Array + /** + * IsDir indicates that this result represents a "directory" in the + * hierarchical namespace, ending in ListOptions.Delimiter. Key can be + * passed as ListOptions.Prefix to list items in the "directory". + * Fields other than Key and IsDir will not be set if IsDir is true. + */ + isDir: boolean + } + /** + * Attributes contains attributes about a blob. + */ + interface Attributes { + /** + * CacheControl specifies caching attributes that services may use + * when serving the blob. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + */ + cacheControl: string + /** + * ContentDisposition specifies whether the blob content is expected to be + * displayed inline or as an attachment. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + */ + contentDisposition: string + /** + * ContentEncoding specifies the encoding used for the blob's content, if any. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + */ + contentEncoding: string + /** + * ContentLanguage specifies the language used in the blob's content, if any. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + */ + contentLanguage: string + /** + * ContentType is the MIME type of the blob. It will not be empty. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + */ + contentType: string + /** + * Metadata holds key/value pairs associated with the blob. + * Keys are guaranteed to be in lowercase, even if the backend service + * has case-sensitive keys (although note that Metadata written via + * this package will always be lowercased). If there are duplicate + * case-insensitive keys (e.g., "foo" and "FOO"), only one value + * will be kept, and it is undefined which one. + */ + metadata: _TygojaDict + /** + * CreateTime is the time the blob was created, if available. If not available, + * CreateTime will be the zero time. + */ + createTime: time.Time + /** + * ModTime is the time the blob was last modified. + */ + modTime: time.Time + /** + * Size is the size of the blob's content in bytes. + */ + size: number + /** + * MD5 is an MD5 hash of the blob contents or nil if not available. + */ + md5: string|Array + /** + * ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag. + */ + eTag: string + } + /** + * Reader reads bytes from a blob. + * It implements io.ReadSeekCloser, and must be closed after reads are finished. + */ + interface Reader { + } + interface Reader { + /** + * Read implements io.Reader (https://golang.org/pkg/io/#Reader). + */ + read(p: string|Array): number + } + interface Reader { + /** + * Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker). + */ + seek(offset: number, whence: number): number + } + interface Reader { + /** + * Close implements io.Closer (https://golang.org/pkg/io/#Closer). + */ + close(): void + } + interface Reader { + /** + * ContentType returns the MIME type of the blob. + */ + contentType(): string + } + interface Reader { + /** + * ModTime returns the time the blob was last modified. + */ + modTime(): time.Time + } + interface Reader { + /** + * Size returns the size of the blob content in bytes. + */ + size(): number + } + interface Reader { + /** + * WriteTo reads from r and writes to w until there's no more data or + * an error occurs. + * The return value is the number of bytes written to w. + * + * It implements the io.WriterTo interface. + */ + writeTo(w: io.Writer): number + } +} + +namespace exec { + /** + * Cmd represents an external command being prepared or run. + * + * A Cmd cannot be reused after calling its [Cmd.Run], [Cmd.Output] or [Cmd.CombinedOutput] + * methods. + */ + interface Cmd { + /** + * Path is the path of the command to run. + * + * This is the only field that must be set to a non-zero + * value. If Path is relative, it is evaluated relative + * to Dir. + */ + path: string + /** + * Args holds command line arguments, including the command as Args[0]. + * If the Args field is empty or nil, Run uses {Path}. + * + * In typical use, both Path and Args are set by calling Command. + */ + args: Array + /** + * Env specifies the environment of the process. + * Each entry is of the form "key=value". + * If Env is nil, the new process uses the current process's + * environment. + * If Env contains duplicate environment keys, only the last + * value in the slice for each duplicate key is used. + * As a special case on Windows, SYSTEMROOT is always added if + * missing and not explicitly set to the empty string. + * + * See also the Dir field, which may set PWD in the environment. + */ + env: Array + /** + * Dir specifies the working directory of the command. + * If Dir is the empty string, Run runs the command in the + * calling process's current directory. + * + * On Unix systems, the value of Dir also determines the + * child process's PWD environment variable if not otherwise + * specified. A Unix process represents its working directory + * not by name but as an implicit reference to a node in the + * file tree. So, if the child process obtains its working + * directory by calling a function such as C's getcwd, which + * computes the canonical name by walking up the file tree, it + * will not recover the original value of Dir if that value + * was an alias involving symbolic links. However, if the + * child process calls Go's [os.Getwd] or GNU C's + * get_current_dir_name, and the value of PWD is an alias for + * the current directory, those functions will return the + * value of PWD, which matches the value of Dir. + */ + dir: string + /** + * Stdin specifies the process's standard input. + * + * If Stdin is nil, the process reads from the null device (os.DevNull). + * + * If Stdin is an *os.File, the process's standard input is connected + * directly to that file. + * + * Otherwise, during the execution of the command a separate + * goroutine reads from Stdin and delivers that data to the command + * over a pipe. In this case, Wait does not complete until the goroutine + * stops copying, either because it has reached the end of Stdin + * (EOF or a read error), or because writing to the pipe returned an error, + * or because a nonzero WaitDelay was set and expired. + */ + stdin: io.Reader + /** + * Stdout and Stderr specify the process's standard output and error. + * + * If either is nil, Run connects the corresponding file descriptor + * to the null device (os.DevNull). + * + * If either is an *os.File, the corresponding output from the process + * is connected directly to that file. + * + * Otherwise, during the execution of the command a separate goroutine + * reads from the process over a pipe and delivers that data to the + * corresponding Writer. In this case, Wait does not complete until the + * goroutine reaches EOF or encounters an error or a nonzero WaitDelay + * expires. + * + * If Stdout and Stderr are the same writer, and have a type that can + * be compared with ==, at most one goroutine at a time will call Write. + */ + stdout: io.Writer + stderr: io.Writer + /** + * ExtraFiles specifies additional open files to be inherited by the + * new process. It does not include standard input, standard output, or + * standard error. If non-nil, entry i becomes file descriptor 3+i. + * + * ExtraFiles is not supported on Windows. + */ + extraFiles: Array<(os.File | undefined)> + /** + * SysProcAttr holds optional, operating system-specific attributes. + * Run passes it to os.StartProcess as the os.ProcAttr's Sys field. + */ + sysProcAttr?: syscall.SysProcAttr + /** + * Process is the underlying process, once started. + */ + process?: os.Process + /** + * ProcessState contains information about an exited process. + * If the process was started successfully, Wait or Run will + * populate its ProcessState when the command completes. + */ + processState?: os.ProcessState + err: Error // LookPath error, if any. + /** + * If Cancel is non-nil, the command must have been created with + * CommandContext and Cancel will be called when the command's + * Context is done. By default, CommandContext sets Cancel to + * call the Kill method on the command's Process. + * + * Typically a custom Cancel will send a signal to the command's + * Process, but it may instead take other actions to initiate cancellation, + * such as closing a stdin or stdout pipe or sending a shutdown request on a + * network socket. + * + * If the command exits with a success status after Cancel is + * called, and Cancel does not return an error equivalent to + * os.ErrProcessDone, then Wait and similar methods will return a non-nil + * error: either an error wrapping the one returned by Cancel, + * or the error from the Context. + * (If the command exits with a non-success status, or Cancel + * returns an error that wraps os.ErrProcessDone, Wait and similar methods + * continue to return the command's usual exit status.) + * + * If Cancel is set to nil, nothing will happen immediately when the command's + * Context is done, but a nonzero WaitDelay will still take effect. That may + * be useful, for example, to work around deadlocks in commands that do not + * support shutdown signals but are expected to always finish quickly. + * + * Cancel will not be called if Start returns a non-nil error. + */ + cancel: () => void + /** + * If WaitDelay is non-zero, it bounds the time spent waiting on two sources + * of unexpected delay in Wait: a child process that fails to exit after the + * associated Context is canceled, and a child process that exits but leaves + * its I/O pipes unclosed. + * + * The WaitDelay timer starts when either the associated Context is done or a + * call to Wait observes that the child process has exited, whichever occurs + * first. When the delay has elapsed, the command shuts down the child process + * and/or its I/O pipes. + * + * If the child process has failed to exit — perhaps because it ignored or + * failed to receive a shutdown signal from a Cancel function, or because no + * Cancel function was set — then it will be terminated using os.Process.Kill. + * + * Then, if the I/O pipes communicating with the child process are still open, + * those pipes are closed in order to unblock any goroutines currently blocked + * on Read or Write calls. + * + * If pipes are closed due to WaitDelay, no Cancel call has occurred, + * and the command has otherwise exited with a successful status, Wait and + * similar methods will return ErrWaitDelay instead of nil. + * + * If WaitDelay is zero (the default), I/O pipes will be read until EOF, + * which might not occur until orphaned subprocesses of the command have + * also closed their descriptors for the pipes. + */ + waitDelay: time.Duration + } + interface Cmd { + /** + * String returns a human-readable description of c. + * It is intended only for debugging. + * In particular, it is not suitable for use as input to a shell. + * The output of String may vary across Go releases. + */ + string(): string + } + interface Cmd { + /** + * Run starts the specified command and waits for it to complete. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command starts but does not complete successfully, the error is of + * type [*ExitError]. Other error types may be returned for other situations. + * + * If the calling goroutine has locked the operating system thread + * with [runtime.LockOSThread] and modified any inheritable OS-level + * thread state (for example, Linux or Plan 9 name spaces), the new + * process will inherit the caller's thread state. + */ + run(): void + } + interface Cmd { + /** + * Start starts the specified command but does not wait for it to complete. + * + * If Start returns successfully, the c.Process field will be set. + * + * After a successful call to Start the [Cmd.Wait] method must be called in + * order to release associated system resources. + */ + start(): void + } + interface Cmd { + /** + * Wait waits for the command to exit and waits for any copying to + * stdin or copying from stdout or stderr to complete. + * + * The command must have been started by [Cmd.Start]. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command fails to run or doesn't complete successfully, the + * error is of type [*ExitError]. Other error types may be + * returned for I/O problems. + * + * If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits + * for the respective I/O loop copying to or from the process to complete. + * + * Wait releases any resources associated with the [Cmd]. + */ + wait(): void + } + interface Cmd { + /** + * Output runs the command and returns its standard output. + * Any returned error will usually be of type [*ExitError]. + * If c.Stderr was nil and the returned error is of type + * [*ExitError], Output populates the Stderr field of the + * returned error. + */ + output(): string|Array + } + interface Cmd { + /** + * CombinedOutput runs the command and returns its combined standard + * output and standard error. + */ + combinedOutput(): string|Array + } + interface Cmd { + /** + * StdinPipe returns a pipe that will be connected to the command's + * standard input when the command starts. + * The pipe will be closed automatically after [Cmd.Wait] sees the command exit. + * A caller need only call Close to force the pipe to close sooner. + * For example, if the command being run will not exit until standard input + * is closed, the caller must close the pipe. + */ + stdinPipe(): io.WriteCloser + } + interface Cmd { + /** + * StdoutPipe returns a pipe that will be connected to the command's + * standard output when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe. + * See the example for idiomatic usage. + */ + stdoutPipe(): io.ReadCloser + } + interface Cmd { + /** + * StderrPipe returns a pipe that will be connected to the command's + * standard error when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe. + * See the StdoutPipe example for idiomatic usage. + */ + stderrPipe(): io.ReadCloser + } + interface Cmd { + /** + * Environ returns a copy of the environment in which the command would be run + * as it is currently configured. + */ + environ(): Array + } +} + +namespace store { + /** + * Store defines a concurrent safe in memory key-value data store. + */ + interface Store { + } + interface Store { + /** + * Reset clears the store and replaces the store data with a + * shallow copy of the provided newData. + */ + reset(newData: _TygojaDict): void + } + interface Store { + /** + * Length returns the current number of elements in the store. + */ + length(): number + } + interface Store { + /** + * RemoveAll removes all the existing store entries. + */ + removeAll(): void + } + interface Store { + /** + * Remove removes a single entry from the store. + * + * Remove does nothing if key doesn't exist in the store. + */ + remove(key: K): void + } + interface Store { + /** + * Has checks if element with the specified key exist or not. + */ + has(key: K): boolean + } + interface Store { + /** + * Get returns a single element value from the store. + * + * If key is not set, the zero T value is returned. + */ + get(key: K): T + } + interface Store { + /** + * GetOk is similar to Get but returns also a boolean indicating whether the key exists or not. + */ + getOk(key: K): [T, boolean] + } + interface Store { + /** + * GetAll returns a shallow copy of the current store data. + */ + getAll(): _TygojaDict + } + interface Store { + /** + * Values returns a slice with all of the current store values. + */ + values(): Array + } + interface Store { + /** + * Set sets (or overwrite if already exists) a new value for key. + */ + set(key: K, value: T): void + } + interface Store { + /** + * SetFunc sets (or overwrite if already exists) a new value resolved + * from the function callback for the provided key. + * + * The function callback receives as argument the old store element value (if exists). + * If there is no old store element, the argument will be the T zero value. + * + * Example: + * + * ``` + * s := store.New[string, int](nil) + * s.SetFunc("count", func(old int) int { + * return old + 1 + * }) + * ``` + */ + setFunc(key: K, fn: (old: T) => T): void + } + interface Store { + /** + * GetOrSet retrieves a single existing value for the provided key + * or stores a new one if it doesn't exist. + */ + getOrSet(key: K, setFunc: () => T): T + } + interface Store { + /** + * SetIfLessThanLimit sets (or overwrite if already exist) a new value for key. + * + * This method is similar to Set() but **it will skip adding new elements** + * to the store if the store length has reached the specified limit. + * false is returned if maxAllowedElements limit is reached. + */ + setIfLessThanLimit(key: K, value: T, maxAllowedElements: number): boolean + } + interface Store { + /** + * UnmarshalJSON implements [json.Unmarshaler] and imports the + * provided JSON data into the store. + * + * The store entries that match with the ones from the data will be overwritten with the new value. + */ + unmarshalJSON(data: string|Array): void + } + interface Store { + /** + * MarshalJSON implements [json.Marshaler] and export the current + * store data into valid JSON. + */ + marshalJSON(): string|Array + } +} + +namespace subscriptions { + /** + * Broker defines a struct for managing subscriptions clients. + */ + interface Broker { + } + interface Broker { + /** + * Clients returns a shallow copy of all registered clients indexed + * with their connection id. + */ + clients(): _TygojaDict + } + interface Broker { + /** + * ChunkedClients splits the current clients into a chunked slice. + */ + chunkedClients(chunkSize: number): Array> + } + interface Broker { + /** + * TotalClients returns the total number of registered clients. + */ + totalClients(): number + } + interface Broker { + /** + * ClientById finds a registered client by its id. + * + * Returns non-nil error when client with clientId is not registered. + */ + clientById(clientId: string): Client + } + interface Broker { + /** + * Register adds a new client to the broker instance. + */ + register(client: Client): void + } + interface Broker { + /** + * Unregister removes a single client by its id and marks it as discarded. + * + * If client with clientId doesn't exist, this method does nothing. + */ + unregister(clientId: string): void + } + /** + * Client is an interface for a generic subscription client. + */ + interface Client { + [key:string]: any; + /** + * Id Returns the unique id of the client. + */ + id(): string + /** + * Channel returns the client's communication channel. + * + * NB! The channel shouldn't be used after calling Discard(). + */ + channel(): undefined + /** + * Subscriptions returns a shallow copy of the client subscriptions matching the prefixes. + * If no prefix is specified, returns all subscriptions. + */ + subscriptions(...prefixes: string[]): _TygojaDict + /** + * Subscribe subscribes the client to the provided subscriptions list. + * + * Each subscription can also have "options" (json serialized SubscriptionOptions) as query parameter. + * + * Example: + * + * ``` + * Subscribe( + * "subscriptionA", + * `subscriptionB?options={"query":{"a":1},"headers":{"x_token":"abc"}}`, + * ) + * ``` + */ + subscribe(...subs: string[]): void + /** + * Unsubscribe unsubscribes the client from the provided subscriptions list. + */ + unsubscribe(...subs: string[]): void + /** + * HasSubscription checks if the client is subscribed to `sub`. + */ + hasSubscription(sub: string): boolean + /** + * Set stores any value to the client's context. + */ + set(key: string, value: any): void + /** + * Unset removes a single value from the client's context. + */ + unset(key: string): void + /** + * Get retrieves the key value from the client's context. + */ + get(key: string): any + /** + * Discard marks the client as "discarded" (and closes its channel), + * meaning that it shouldn't be used anymore for sending new messages. + * + * It is safe to call Discard() multiple times. + */ + discard(): void + /** + * IsDiscarded indicates whether the client has been "discarded" + * and should no longer be used. + */ + isDiscarded(): boolean + /** + * Send sends the specified message to the client's channel (if not discarded). + */ + send(m: Message): void + } + /** + * Message defines a client's channel data. + */ + interface Message { + name: string + data: string|Array + } + interface Message { + /** + * WriteSSE writes the current message in a SSE format into the provided writer. + * + * For example, writing to a router.Event: + * + * ``` + * m := Message{Name: "users/create", Data: []byte{...}} + * m.WriteSSE(e.Response, "yourEventId") + * e.Flush() + * ``` + */ + writeSSE(w: io.Writer, eventId: string): void + } +} + +namespace hook { + /** + * Event implements [Resolver] and it is intended to be used as a base + * Hook event that you can embed in your custom typed event structs. + * + * Example: + * + * ``` + * type CustomEvent struct { + * hook.Event + * + * SomeField int + * } + * ``` + */ + interface Event { + } + interface Event { + /** + * Next calls the next hook handler. + */ + next(): void + } + /** + * Handler defines a single Hook handler. + * Multiple handlers can share the same id. + * If Id is not explicitly set it will be autogenerated by Hook.Add and Hook.AddHandler. + */ + interface Handler { + /** + * Func defines the handler function to execute. + * + * Note that users need to call e.Next() in order to proceed with + * the execution of the hook chain. + */ + func: (_arg0: T) => void + /** + * Id is the unique identifier of the handler. + * + * It could be used later to remove the handler from a hook via [Hook.Remove]. + * + * If missing, an autogenerated value will be assigned when adding + * the handler to a hook. + */ + id: string + /** + * Priority allows changing the default exec priority of the handler within a hook. + * + * If 0, the handler will be executed in the same order it was registered. + */ + priority: number + } + /** + * Hook defines a generic concurrent safe structure for managing event hooks. + * + * When using custom event it must embed the base [hook.Event]. + * + * Example: + * + * ``` + * type CustomEvent struct { + * hook.Event + * SomeField int + * } + * + * h := Hook[*CustomEvent]{} + * + * h.BindFunc(func(e *CustomEvent) error { + * println(e.SomeField) + * + * return e.Next() + * }) + * + * h.Trigger(&CustomEvent{ SomeField: 123 }) + * ``` + */ + interface Hook { + } + interface Hook { + /** + * Bind registers the provided handler to the current hooks queue. + * + * If handler.Id is empty it is updated with autogenerated value. + * + * If a handler from the current hook list has Id matching handler.Id + * then the old handler is replaced with the new one. + */ + bind(handler: Handler): string + } + interface Hook { + /** + * BindFunc is similar to Bind but registers a new handler from just the provided function. + * + * The registered handler is added with a default 0 priority and the id will be autogenerated. + * + * If you want to register a handler with custom priority or id use the [Hook.Bind] method. + */ + bindFunc(fn: (e: T) => void): string + } + interface Hook { + /** + * Unbind removes one or many hook handler by their id. + */ + unbind(...idsToRemove: string[]): void + } + interface Hook { + /** + * UnbindAll removes all registered handlers. + */ + unbindAll(): void + } + interface Hook { + /** + * Length returns to total number of registered hook handlers. + */ + length(): number + } + interface Hook { + /** + * Trigger executes all registered hook handlers one by one + * with the specified event as an argument. + * + * Optionally, this method allows also to register additional one off + * handler funcs that will be temporary appended to the handlers queue. + * + * NB! Each hook handler must call event.Next() in order the hook chain to proceed. + */ + trigger(event: T, ...oneOffHandlerFuncs: ((_arg0: T) => void)[]): void + } + /** + * TaggedHook defines a proxy hook which register handlers that are triggered only + * if the TaggedHook.tags are empty or includes at least one of the event data tag(s). + */ + type _skAiFuY = mainHook + interface TaggedHook extends _skAiFuY { + } + interface TaggedHook { + /** + * CanTriggerOn checks if the current TaggedHook can be triggered with + * the provided event data tags. + * + * It returns always true if the hook doens't have any tags. + */ + canTriggerOn(tagsToCheck: Array): boolean + } + interface TaggedHook { + /** + * Bind registers the provided handler to the current hooks queue. + * + * It is similar to [Hook.Bind] with the difference that the handler + * function is invoked only if the event data tags satisfy h.CanTriggerOn. + */ + bind(handler: Handler): string + } + interface TaggedHook { + /** + * BindFunc registers a new handler with the specified function. + * + * It is similar to [Hook.Bind] with the difference that the handler + * function is invoked only if the event data tags satisfy h.CanTriggerOn. + */ + bindFunc(fn: (e: T) => void): string + } +} + +namespace mailer { + /** + * Message defines a generic email message struct. + */ + interface Message { + from: { address: string; name?: string; } + to: Array<{ address: string; name?: string; }> + bcc: Array<{ address: string; name?: string; }> + cc: Array<{ address: string; name?: string; }> + subject: string + html: string + text: string + headers: _TygojaDict + attachments: _TygojaDict + inlineAttachments: _TygojaDict + } + /** + * Mailer defines a base mail client interface. + */ + interface Mailer { + [key:string]: any; + /** + * Send sends an email with the provided Message. + */ + send(message: Message): void + } +} + +/** + * Package cron implements a crontab-like service to execute and schedule + * repeative tasks/jobs. + * + * Example: + * + * ``` + * c := cron.New() + * c.MustAdd("dailyReport", "0 0 * * *", func() { ... }) + * c.Start() + * ``` + */ +namespace cron { + /** + * Cron is a crontab-like struct for tasks/jobs scheduling. + */ + interface Cron { + } + interface Cron { + /** + * SetInterval changes the current cron tick interval + * (it usually should be >= 1 minute). + */ + setInterval(d: time.Duration): void + } + interface Cron { + /** + * SetTimezone changes the current cron tick timezone. + */ + setTimezone(l: time.Location): void + } + interface Cron { + /** + * MustAdd is similar to Add() but panic on failure. + */ + mustAdd(jobId: string, cronExpr: string, run: () => void): void + } + interface Cron { + /** + * Add registers a single cron job. + * + * If there is already a job with the provided id, then the old job + * will be replaced with the new one. + * + * cronExpr is a regular cron expression, eg. "0 *\/3 * * *" (aka. at minute 0 past every 3rd hour). + * Check cron.NewSchedule() for the supported tokens. + */ + add(jobId: string, cronExpr: string, fn: () => void): void + } + interface Cron { + /** + * Remove removes a single cron job by its id. + */ + remove(jobId: string): void + } + interface Cron { + /** + * RemoveAll removes all registered cron jobs. + */ + removeAll(): void + } + interface Cron { + /** + * Total returns the current total number of registered cron jobs. + */ + total(): number + } + interface Cron { + /** + * Jobs returns a shallow copy of the currently registered cron jobs. + */ + jobs(): Array<(Job | undefined)> + } + interface Cron { + /** + * Stop stops the current cron ticker (if not already). + * + * You can resume the ticker by calling Start(). + */ + stop(): void + } + interface Cron { + /** + * Start starts the cron ticker. + * + * Calling Start() on already started cron will restart the ticker. + */ + start(): void + } + interface Cron { + /** + * HasStarted checks whether the current Cron ticker has been started. + */ + hasStarted(): boolean + } +} + +namespace search { + /** + * Result defines the returned search result structure. + */ + interface Result { + items: any + page: number + perPage: number + totalItems: number + totalPages: number + } + /** + * ResolverResult defines a single FieldResolver.Resolve() successfully parsed result. + */ + interface ResolverResult { + /** + * Identifier is the plain SQL identifier/column that will be used + * in the final db expression as left or right operand. + */ + identifier: string + /** + * NoCoalesce instructs to not use COALESCE or NULL fallbacks + * when building the identifier expression. + */ + noCoalesce: boolean + /** + * Params is a map with db placeholder->value pairs that will be added + * to the query when building both resolved operands/sides in a single expression. + */ + params: dbx.Params + /** + * MultiMatchSubQuery is an optional sub query expression that will be added + * in addition to the combined ResolverResult expression during build. + */ + multiMatchSubQuery: dbx.Expression + /** + * AfterBuild is an optional function that will be called after building + * and combining the result of both resolved operands/sides in a single expression. + */ + afterBuild: (expr: dbx.Expression) => dbx.Expression + } +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation + /** + * ApiError defines the struct for a basic api error response. + */ + interface ApiError { + data: _TygojaDict + message: string + status: number + } + interface ApiError { + /** + * Error makes it compatible with the `error` interface. + */ + error(): string + } + interface ApiError { + /** + * RawData returns the unformatted error data (could be an internal error, text, etc.) + */ + rawData(): any + } + interface ApiError { + /** + * Is reports whether the current ApiError wraps the target. + */ + is(target: Error): boolean + } + /** + * Event specifies based Route handler event that is usually intended + * to be embedded as part of a custom event struct. + * + * NB! It is expected that the Response and Request fields are always set. + */ + type _sOKkoQL = hook.Event + interface Event extends _sOKkoQL { + response: http.ResponseWriter + request?: http.Request + } + interface Event { + /** + * Written reports whether the current response has already been written. + * + * This method always returns false if e.ResponseWritter doesn't implement the WriteTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + written(): boolean + } + interface Event { + /** + * Status reports the status code of the current response. + * + * This method always returns 0 if e.Response doesn't implement the StatusTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + status(): number + } + interface Event { + /** + * Flush flushes buffered data to the current response. + * + * Returns [http.ErrNotSupported] if e.Response doesn't implement the [http.Flusher] interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + flush(): void + } + interface Event { + /** + * IsTLS reports whether the connection on which the request was received is TLS. + */ + isTLS(): boolean + } + interface Event { + /** + * SetCookie is an alias for [http.SetCookie]. + * + * SetCookie adds a Set-Cookie header to the current response's headers. + * The provided cookie must have a valid Name. + * Invalid cookies may be silently dropped. + */ + setCookie(cookie: http.Cookie): void + } + interface Event { + /** + * RemoteIP returns the IP address of the client that sent the request. + * + * IPv6 addresses are returned expanded. + * For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001". + * + * Note that if you are behind reverse proxy(ies), this method returns + * the IP of the last connecting proxy. + */ + remoteIP(): string + } + interface Event { + /** + * FindUploadedFiles extracts all form files of "key" from a http request + * and returns a slice with filesystem.File instances (if any). + */ + findUploadedFiles(key: string): Array<(filesystem.File | undefined)> + } + interface Event { + /** + * Get retrieves single value from the current event data store. + */ + get(key: string): any + } + interface Event { + /** + * GetAll returns a copy of the current event data store. + */ + getAll(): _TygojaDict + } + interface Event { + /** + * Set saves single value into the current event data store. + */ + set(key: string, value: any): void + } + interface Event { + /** + * SetAll saves all items from m into the current event data store. + */ + setAll(m: _TygojaDict): void + } + interface Event { + /** + * String writes a plain string response. + */ + string(status: number, data: string): void + } + interface Event { + /** + * HTML writes an HTML response. + */ + html(status: number, data: string): void + } + interface Event { + /** + * JSON writes a JSON response. + * + * It also provides a generic response data fields picker if the "fields" query parameter is set. + * For example, if you are requesting `?fields=a,b` for `e.JSON(200, map[string]int{ "a":1, "b":2, "c":3 })`, + * it should result in a JSON response like: `{"a":1, "b": 2}`. + */ + json(status: number, data: any): void + } + interface Event { + /** + * XML writes an XML response. + * It automatically prepends the generic [xml.Header] string to the response. + */ + xml(status: number, data: any): void + } + interface Event { + /** + * Stream streams the specified reader into the response. + */ + stream(status: number, contentType: string, reader: io.Reader): void + } + interface Event { + /** + * Blob writes a blob (bytes slice) response. + */ + blob(status: number, contentType: string, b: string|Array): void + } + interface Event { + /** + * FileFS serves the specified filename from fsys. + * + * It is similar to [echo.FileFS] for consistency with earlier versions. + */ + fileFS(fsys: fs.FS, filename: string): void + } + interface Event { + /** + * NoContent writes a response with no body (ex. 204). + */ + noContent(status: number): void + } + interface Event { + /** + * Redirect writes a redirect response to the specified url. + * The status code must be in between 300 – 399 range. + */ + redirect(status: number, url: string): void + } + interface Event { + error(status: number, message: string, errData: any): (ApiError) + } + interface Event { + badRequestError(message: string, errData: any): (ApiError) + } + interface Event { + notFoundError(message: string, errData: any): (ApiError) + } + interface Event { + forbiddenError(message: string, errData: any): (ApiError) + } + interface Event { + unauthorizedError(message: string, errData: any): (ApiError) + } + interface Event { + tooManyRequestsError(message: string, errData: any): (ApiError) + } + interface Event { + internalServerError(message: string, errData: any): (ApiError) + } + interface Event { + /** + * BindBody unmarshal the request body into the provided dst. + * + * dst must be either a struct pointer or map[string]any. + * + * The rules how the body will be scanned depends on the request Content-Type. + * + * Currently the following Content-Types are supported: + * ``` + * - application/json + * - text/xml, application/xml + * - multipart/form-data, application/x-www-form-urlencoded + * ``` + * + * Respectively the following struct tags are supported (again, which one will be used depends on the Content-Type): + * ``` + * - "json" (json body)- uses the builtin Go json package for unmarshaling. + * - "xml" (xml body) - uses the builtin Go xml package for unmarshaling. + * - "form" (form data) - utilizes the custom [router.UnmarshalRequestData] method. + * ``` + * + * NB! When dst is a struct make sure that it doesn't have public fields + * that shouldn't be bindable and it is advisible such fields to be unexported + * or have a separate struct just for the binding. For example: + * + * ``` + * data := struct{ + * somethingPrivate string + * + * Title string `json:"title" form:"title"` + * Total int `json:"total" form:"total"` + * } + * err := e.BindBody(&data) + * ``` + */ + bindBody(dst: any): void + } + /** + * Router defines a thin wrapper around the standard Go [http.ServeMux] by + * adding support for routing sub-groups, middlewares and other common utils. + * + * Example: + * + * ``` + * r := NewRouter[*MyEvent](eventFactory) + * + * // middlewares + * r.BindFunc(m1, m2) + * + * // routes + * r.GET("/test", handler1) + * + * // sub-routers/groups + * api := r.Group("/api") + * api.GET("/admins", handler2) + * + * // generate a http.ServeMux instance based on the router configurations + * mux, _ := r.BuildMux() + * + * http.ListenAndServe("localhost:8090", mux) + * ``` + */ + type _stgEiRI = RouterGroup + interface Router extends _stgEiRI { + } + interface Router { + /** + * BuildMux constructs a new mux [http.Handler] instance from the current router configurations. + */ + buildMux(): http.Handler + } +} + +/** + * Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. + * In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. + */ +namespace cobra { + interface Command { + /** + * GenBashCompletion generates bash completion file and writes to the passed writer. + */ + genBashCompletion(w: io.Writer): void + } + interface Command { + /** + * GenBashCompletionFile generates bash completion file. + */ + genBashCompletionFile(filename: string): void + } + interface Command { + /** + * GenBashCompletionFileV2 generates Bash completion version 2. + */ + genBashCompletionFileV2(filename: string, includeDesc: boolean): void + } + interface Command { + /** + * GenBashCompletionV2 generates Bash completion file version 2 + * and writes it to the passed writer. + */ + genBashCompletionV2(w: io.Writer, includeDesc: boolean): void + } + // @ts-ignore + import flag = pflag + /** + * Command is just that, a command for your application. + * E.g. 'go run ...' - 'run' is the command. Cobra requires + * you to define the usage and description as part of your command + * definition to ensure usability. + */ + interface Command { + /** + * Use is the one-line usage message. + * Recommended syntax is as follows: + * ``` + * [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required. + * ... indicates that you can specify multiple values for the previous argument. + * | indicates mutually exclusive information. You can use the argument to the left of the separator or the + * argument to the right of the separator. You cannot use both arguments in a single use of the command. + * { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are + * optional, they are enclosed in brackets ([ ]). + * ``` + * Example: add [-F file | -D dir]... [-f format] profile + */ + use: string + /** + * Aliases is an array of aliases that can be used instead of the first word in Use. + */ + aliases: Array + /** + * SuggestFor is an array of command names for which this command will be suggested - + * similar to aliases but only suggests. + */ + suggestFor: Array + /** + * Short is the short description shown in the 'help' output. + */ + short: string + /** + * The group id under which this subcommand is grouped in the 'help' output of its parent. + */ + groupID: string + /** + * Long is the long message shown in the 'help ' output. + */ + long: string + /** + * Example is examples of how to use the command. + */ + example: string + /** + * ValidArgs is list of all valid non-flag arguments that are accepted in shell completions + */ + validArgs: Array + /** + * ValidArgsFunction is an optional function that provides valid non-flag arguments for shell completion. + * It is a dynamic version of using ValidArgs. + * Only one of ValidArgs and ValidArgsFunction can be used for a command. + */ + validArgsFunction: CompletionFunc + /** + * Expected arguments + */ + args: PositionalArgs + /** + * ArgAliases is List of aliases for ValidArgs. + * These are not suggested to the user in the shell completion, + * but accepted if entered manually. + */ + argAliases: Array + /** + * BashCompletionFunction is custom bash functions used by the legacy bash autocompletion generator. + * For portability with other shells, it is recommended to instead use ValidArgsFunction + */ + bashCompletionFunction: string + /** + * Deprecated defines, if this command is deprecated and should print this string when used. + */ + deprecated: string + /** + * Annotations are key/value pairs that can be used by applications to identify or + * group commands or set special options. + */ + annotations: _TygojaDict + /** + * Version defines the version for this command. If this value is non-empty and the command does not + * define a "version" flag, a "version" boolean flag will be added to the command and, if specified, + * will print content of the "Version" variable. A shorthand "v" flag will also be added if the + * command does not define one. + */ + version: string + /** + * The *Run functions are executed in the following order: + * ``` + * * PersistentPreRun() + * * PreRun() + * * Run() + * * PostRun() + * * PersistentPostRun() + * ``` + * All functions get the same args, the arguments after the command name. + * The *PreRun and *PostRun functions will only be executed if the Run function of the current + * command has been declared. + * + * PersistentPreRun: children of this command will inherit and execute. + */ + persistentPreRun: (cmd: Command, args: Array) => void + /** + * PersistentPreRunE: PersistentPreRun but returns an error. + */ + persistentPreRunE: (cmd: Command, args: Array) => void + /** + * PreRun: children of this command will not inherit. + */ + preRun: (cmd: Command, args: Array) => void + /** + * PreRunE: PreRun but returns an error. + */ + preRunE: (cmd: Command, args: Array) => void + /** + * Run: Typically the actual work function. Most commands will only implement this. + */ + run: (cmd: Command, args: Array) => void + /** + * RunE: Run but returns an error. + */ + runE: (cmd: Command, args: Array) => void + /** + * PostRun: run after the Run command. + */ + postRun: (cmd: Command, args: Array) => void + /** + * PostRunE: PostRun but returns an error. + */ + postRunE: (cmd: Command, args: Array) => void + /** + * PersistentPostRun: children of this command will inherit and execute after PostRun. + */ + persistentPostRun: (cmd: Command, args: Array) => void + /** + * PersistentPostRunE: PersistentPostRun but returns an error. + */ + persistentPostRunE: (cmd: Command, args: Array) => void + /** + * FParseErrWhitelist flag parse errors to be ignored + */ + fParseErrWhitelist: FParseErrWhitelist + /** + * CompletionOptions is a set of options to control the handling of shell completion + */ + completionOptions: CompletionOptions + /** + * TraverseChildren parses flags on all parents before executing child command. + */ + traverseChildren: boolean + /** + * Hidden defines, if this command is hidden and should NOT show up in the list of available commands. + */ + hidden: boolean + /** + * SilenceErrors is an option to quiet errors down stream. + */ + silenceErrors: boolean + /** + * SilenceUsage is an option to silence usage when an error occurs. + */ + silenceUsage: boolean + /** + * DisableFlagParsing disables the flag parsing. + * If this is true all flags will be passed to the command as arguments. + */ + disableFlagParsing: boolean + /** + * DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...") + * will be printed by generating docs for this command. + */ + disableAutoGenTag: boolean + /** + * DisableFlagsInUseLine will disable the addition of [flags] to the usage + * line of a command when printing help or generating docs + */ + disableFlagsInUseLine: boolean + /** + * DisableSuggestions disables the suggestions based on Levenshtein distance + * that go along with 'unknown command' messages. + */ + disableSuggestions: boolean + /** + * SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions. + * Must be > 0. + */ + suggestionsMinimumDistance: number + } + interface Command { + /** + * Context returns underlying command context. If command was executed + * with ExecuteContext or the context was set with SetContext, the + * previously set context will be returned. Otherwise, nil is returned. + * + * Notice that a call to Execute and ExecuteC will replace a nil context of + * a command with a context.Background, so a background context will be + * returned by Context after one of these functions has been called. + */ + context(): context.Context + } + interface Command { + /** + * SetContext sets context for the command. This context will be overwritten by + * Command.ExecuteContext or Command.ExecuteContextC. + */ + setContext(ctx: context.Context): void + } + interface Command { + /** + * SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden + * particularly useful when testing. + */ + setArgs(a: Array): void + } + interface Command { + /** + * SetOutput sets the destination for usage and error messages. + * If output is nil, os.Stderr is used. + * + * Deprecated: Use SetOut and/or SetErr instead + */ + setOutput(output: io.Writer): void + } + interface Command { + /** + * SetOut sets the destination for usage messages. + * If newOut is nil, os.Stdout is used. + */ + setOut(newOut: io.Writer): void + } + interface Command { + /** + * SetErr sets the destination for error messages. + * If newErr is nil, os.Stderr is used. + */ + setErr(newErr: io.Writer): void + } + interface Command { + /** + * SetIn sets the source for input data + * If newIn is nil, os.Stdin is used. + */ + setIn(newIn: io.Reader): void + } + interface Command { + /** + * SetUsageFunc sets usage function. Usage can be defined by application. + */ + setUsageFunc(f: (_arg0: Command) => void): void + } + interface Command { + /** + * SetUsageTemplate sets usage template. Can be defined by Application. + */ + setUsageTemplate(s: string): void + } + interface Command { + /** + * SetFlagErrorFunc sets a function to generate an error when flag parsing + * fails. + */ + setFlagErrorFunc(f: (_arg0: Command, _arg1: Error) => void): void + } + interface Command { + /** + * SetHelpFunc sets help function. Can be defined by Application. + */ + setHelpFunc(f: (_arg0: Command, _arg1: Array) => void): void + } + interface Command { + /** + * SetHelpCommand sets help command. + */ + setHelpCommand(cmd: Command): void + } + interface Command { + /** + * SetHelpCommandGroupID sets the group id of the help command. + */ + setHelpCommandGroupID(groupID: string): void + } + interface Command { + /** + * SetCompletionCommandGroupID sets the group id of the completion command. + */ + setCompletionCommandGroupID(groupID: string): void + } + interface Command { + /** + * SetHelpTemplate sets help template to be used. Application can use it to set custom template. + */ + setHelpTemplate(s: string): void + } + interface Command { + /** + * SetVersionTemplate sets version template to be used. Application can use it to set custom template. + */ + setVersionTemplate(s: string): void + } + interface Command { + /** + * SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix. + */ + setErrPrefix(s: string): void + } + interface Command { + /** + * SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. + * The user should not have a cyclic dependency on commands. + */ + setGlobalNormalizationFunc(n: (f: any, name: string) => any): void + } + interface Command { + /** + * OutOrStdout returns output to stdout. + */ + outOrStdout(): io.Writer + } + interface Command { + /** + * OutOrStderr returns output to stderr + */ + outOrStderr(): io.Writer + } + interface Command { + /** + * ErrOrStderr returns output to stderr + */ + errOrStderr(): io.Writer + } + interface Command { + /** + * InOrStdin returns input to stdin + */ + inOrStdin(): io.Reader + } + interface Command { + /** + * UsageFunc returns either the function set by SetUsageFunc for this command + * or a parent, or it returns a default usage function. + */ + usageFunc(): (_arg0: Command) => void + } + interface Command { + /** + * Usage puts out the usage for the command. + * Used when a user provides invalid input. + * Can be defined by user by overriding UsageFunc. + */ + usage(): void + } + interface Command { + /** + * HelpFunc returns either the function set by SetHelpFunc for this command + * or a parent, or it returns a function with default help behavior. + */ + helpFunc(): (_arg0: Command, _arg1: Array) => void + } + interface Command { + /** + * Help puts out the help for the command. + * Used when a user calls help [command]. + * Can be defined by user by overriding HelpFunc. + */ + help(): void + } + interface Command { + /** + * UsageString returns usage string. + */ + usageString(): string + } + interface Command { + /** + * FlagErrorFunc returns either the function set by SetFlagErrorFunc for this + * command or a parent, or it returns a function which returns the original + * error. + */ + flagErrorFunc(): (_arg0: Command, _arg1: Error) => void + } + interface Command { + /** + * UsagePadding return padding for the usage. + */ + usagePadding(): number + } + interface Command { + /** + * CommandPathPadding return padding for the command path. + */ + commandPathPadding(): number + } + interface Command { + /** + * NamePadding returns padding for the name. + */ + namePadding(): number + } + interface Command { + /** + * UsageTemplate returns usage template for the command. + * This function is kept for backwards-compatibility reasons. + */ + usageTemplate(): string + } + interface Command { + /** + * HelpTemplate return help template for the command. + * This function is kept for backwards-compatibility reasons. + */ + helpTemplate(): string + } + interface Command { + /** + * VersionTemplate return version template for the command. + * This function is kept for backwards-compatibility reasons. + */ + versionTemplate(): string + } + interface Command { + /** + * ErrPrefix return error message prefix for the command + */ + errPrefix(): string + } + interface Command { + /** + * Find the target command given the args and command tree + * Meant to be run on the highest node. Only searches down. + */ + find(args: Array): [(Command), Array] + } + interface Command { + /** + * Traverse the command tree to find the command, and parse args for + * each parent. + */ + traverse(args: Array): [(Command), Array] + } + interface Command { + /** + * SuggestionsFor provides suggestions for the typedName. + */ + suggestionsFor(typedName: string): Array + } + interface Command { + /** + * VisitParents visits all parents of the command and invokes fn on each parent. + */ + visitParents(fn: (_arg0: Command) => void): void + } + interface Command { + /** + * Root finds root command. + */ + root(): (Command) + } + interface Command { + /** + * ArgsLenAtDash will return the length of c.Flags().Args at the moment + * when a -- was found during args parsing. + */ + argsLenAtDash(): number + } + interface Command { + /** + * ExecuteContext is the same as Execute(), but sets the ctx on the command. + * Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs + * functions. + */ + executeContext(ctx: context.Context): void + } + interface Command { + /** + * Execute uses the args (os.Args[1:] by default) + * and run through the command tree finding appropriate matches + * for commands and then corresponding flags. + */ + execute(): void + } + interface Command { + /** + * ExecuteContextC is the same as ExecuteC(), but sets the ctx on the command. + * Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs + * functions. + */ + executeContextC(ctx: context.Context): (Command) + } + interface Command { + /** + * ExecuteC executes the command. + */ + executeC(): (Command) + } + interface Command { + validateArgs(args: Array): void + } + interface Command { + /** + * ValidateRequiredFlags validates all required flags are present and returns an error otherwise + */ + validateRequiredFlags(): void + } + interface Command { + /** + * InitDefaultHelpFlag adds default help flag to c. + * It is called automatically by executing the c or by calling help and usage. + * If c already has help flag, it will do nothing. + */ + initDefaultHelpFlag(): void + } + interface Command { + /** + * InitDefaultVersionFlag adds default version flag to c. + * It is called automatically by executing the c. + * If c already has a version flag, it will do nothing. + * If c.Version is empty, it will do nothing. + */ + initDefaultVersionFlag(): void + } + interface Command { + /** + * InitDefaultHelpCmd adds default help command to c. + * It is called automatically by executing the c or by calling help and usage. + * If c already has help command or c has no subcommands, it will do nothing. + */ + initDefaultHelpCmd(): void + } + interface Command { + /** + * ResetCommands delete parent, subcommand and help command from c. + */ + resetCommands(): void + } + interface Command { + /** + * Commands returns a sorted slice of child commands. + */ + commands(): Array<(Command | undefined)> + } + interface Command { + /** + * AddCommand adds one or more commands to this parent command. + */ + addCommand(...cmds: (Command | undefined)[]): void + } + interface Command { + /** + * Groups returns a slice of child command groups. + */ + groups(): Array<(Group | undefined)> + } + interface Command { + /** + * AllChildCommandsHaveGroup returns if all subcommands are assigned to a group + */ + allChildCommandsHaveGroup(): boolean + } + interface Command { + /** + * ContainsGroup return if groupID exists in the list of command groups. + */ + containsGroup(groupID: string): boolean + } + interface Command { + /** + * AddGroup adds one or more command groups to this parent command. + */ + addGroup(...groups: (Group | undefined)[]): void + } + interface Command { + /** + * RemoveCommand removes one or more commands from a parent command. + */ + removeCommand(...cmds: (Command | undefined)[]): void + } + interface Command { + /** + * Print is a convenience method to Print to the defined output, fallback to Stderr if not set. + */ + print(...i: { + }[]): void + } + interface Command { + /** + * Println is a convenience method to Println to the defined output, fallback to Stderr if not set. + */ + println(...i: { + }[]): void + } + interface Command { + /** + * Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set. + */ + printf(format: string, ...i: { + }[]): void + } + interface Command { + /** + * PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set. + */ + printErr(...i: { + }[]): void + } + interface Command { + /** + * PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set. + */ + printErrln(...i: { + }[]): void + } + interface Command { + /** + * PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set. + */ + printErrf(format: string, ...i: { + }[]): void + } + interface Command { + /** + * CommandPath returns the full path to this command. + */ + commandPath(): string + } + interface Command { + /** + * DisplayName returns the name to display in help text. Returns command Name() + * If CommandDisplayNameAnnoation is not set + */ + displayName(): string + } + interface Command { + /** + * UseLine puts out the full usage for a given command (including parents). + */ + useLine(): string + } + interface Command { + /** + * DebugFlags used to determine which flags have been assigned to which commands + * and which persist. + */ + debugFlags(): void + } + interface Command { + /** + * Name returns the command's name: the first word in the use line. + */ + name(): string + } + interface Command { + /** + * HasAlias determines if a given string is an alias of the command. + */ + hasAlias(s: string): boolean + } + interface Command { + /** + * CalledAs returns the command name or alias that was used to invoke + * this command or an empty string if the command has not been called. + */ + calledAs(): string + } + interface Command { + /** + * NameAndAliases returns a list of the command name and all aliases + */ + nameAndAliases(): string + } + interface Command { + /** + * HasExample determines if the command has example. + */ + hasExample(): boolean + } + interface Command { + /** + * Runnable determines if the command is itself runnable. + */ + runnable(): boolean + } + interface Command { + /** + * HasSubCommands determines if the command has children commands. + */ + hasSubCommands(): boolean + } + interface Command { + /** + * IsAvailableCommand determines if a command is available as a non-help command + * (this includes all non deprecated/hidden commands). + */ + isAvailableCommand(): boolean + } + interface Command { + /** + * IsAdditionalHelpTopicCommand determines if a command is an additional + * help topic command; additional help topic command is determined by the + * fact that it is NOT runnable/hidden/deprecated, and has no sub commands that + * are runnable/hidden/deprecated. + * Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924. + */ + isAdditionalHelpTopicCommand(): boolean + } + interface Command { + /** + * HasHelpSubCommands determines if a command has any available 'help' sub commands + * that need to be shown in the usage/help default template under 'additional help + * topics'. + */ + hasHelpSubCommands(): boolean + } + interface Command { + /** + * HasAvailableSubCommands determines if a command has available sub commands that + * need to be shown in the usage/help default template under 'available commands'. + */ + hasAvailableSubCommands(): boolean + } + interface Command { + /** + * HasParent determines if the command is a child command. + */ + hasParent(): boolean + } + interface Command { + /** + * GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist. + */ + globalNormalizationFunc(): (f: any, name: string) => any + } + interface Command { + /** + * Flags returns the complete FlagSet that applies + * to this command (local and persistent declared here and by all parents). + */ + flags(): (any) + } + interface Command { + /** + * LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands. + * This function does not modify the flags of the current command, it's purpose is to return the current state. + */ + localNonPersistentFlags(): (any) + } + interface Command { + /** + * LocalFlags returns the local FlagSet specifically set in the current command. + * This function does not modify the flags of the current command, it's purpose is to return the current state. + */ + localFlags(): (any) + } + interface Command { + /** + * InheritedFlags returns all flags which were inherited from parent commands. + * This function does not modify the flags of the current command, it's purpose is to return the current state. + */ + inheritedFlags(): (any) + } + interface Command { + /** + * NonInheritedFlags returns all flags which were not inherited from parent commands. + * This function does not modify the flags of the current command, it's purpose is to return the current state. + */ + nonInheritedFlags(): (any) + } + interface Command { + /** + * PersistentFlags returns the persistent FlagSet specifically set in the current command. + */ + persistentFlags(): (any) + } + interface Command { + /** + * ResetFlags deletes all flags from command. + */ + resetFlags(): void + } + interface Command { + /** + * HasFlags checks if the command contains any flags (local plus persistent from the entire structure). + */ + hasFlags(): boolean + } + interface Command { + /** + * HasPersistentFlags checks if the command contains persistent flags. + */ + hasPersistentFlags(): boolean + } + interface Command { + /** + * HasLocalFlags checks if the command has flags specifically declared locally. + */ + hasLocalFlags(): boolean + } + interface Command { + /** + * HasInheritedFlags checks if the command has flags inherited from its parent command. + */ + hasInheritedFlags(): boolean + } + interface Command { + /** + * HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire + * structure) which are not hidden or deprecated. + */ + hasAvailableFlags(): boolean + } + interface Command { + /** + * HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated. + */ + hasAvailablePersistentFlags(): boolean + } + interface Command { + /** + * HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden + * or deprecated. + */ + hasAvailableLocalFlags(): boolean + } + interface Command { + /** + * HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are + * not hidden or deprecated. + */ + hasAvailableInheritedFlags(): boolean + } + interface Command { + /** + * Flag climbs up the command tree looking for matching flag. + */ + flag(name: string): (any) + } + interface Command { + /** + * ParseFlags parses persistent flag tree and local flags. + */ + parseFlags(args: Array): void + } + interface Command { + /** + * Parent returns a commands parent command. + */ + parent(): (Command) + } + interface Command { + /** + * RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag. + * + * You can use pre-defined completion functions such as [FixedCompletions] or [NoFileCompletions], + * or you can define your own. + */ + registerFlagCompletionFunc(flagName: string, f: CompletionFunc): void + } + interface Command { + /** + * GetFlagCompletionFunc returns the completion function for the given flag of the command, if available. + */ + getFlagCompletionFunc(flagName: string): [CompletionFunc, boolean] + } + interface Command { + /** + * InitDefaultCompletionCmd adds a default 'completion' command to c. + * This function will do nothing if any of the following is true: + * 1- the feature has been explicitly disabled by the program, + * 2- c has no subcommands (to avoid creating one), + * 3- c already has a 'completion' command provided by the program. + */ + initDefaultCompletionCmd(...args: string[]): void + } + interface Command { + /** + * GenFishCompletion generates fish completion file and writes to the passed writer. + */ + genFishCompletion(w: io.Writer, includeDesc: boolean): void + } + interface Command { + /** + * GenFishCompletionFile generates fish completion file. + */ + genFishCompletionFile(filename: string, includeDesc: boolean): void + } + interface Command { + /** + * MarkFlagsRequiredTogether marks the given flags with annotations so that Cobra errors + * if the command is invoked with a subset (but not all) of the given flags. + */ + markFlagsRequiredTogether(...flagNames: string[]): void + } + interface Command { + /** + * MarkFlagsOneRequired marks the given flags with annotations so that Cobra errors + * if the command is invoked without at least one flag from the given set of flags. + */ + markFlagsOneRequired(...flagNames: string[]): void + } + interface Command { + /** + * MarkFlagsMutuallyExclusive marks the given flags with annotations so that Cobra errors + * if the command is invoked with more than one flag from the given set of flags. + */ + markFlagsMutuallyExclusive(...flagNames: string[]): void + } + interface Command { + /** + * ValidateFlagGroups validates the mutuallyExclusive/oneRequired/requiredAsGroup logic and returns the + * first error encountered. + */ + validateFlagGroups(): void + } + interface Command { + /** + * GenPowerShellCompletionFile generates powershell completion file without descriptions. + */ + genPowerShellCompletionFile(filename: string): void + } + interface Command { + /** + * GenPowerShellCompletion generates powershell completion file without descriptions + * and writes it to the passed writer. + */ + genPowerShellCompletion(w: io.Writer): void + } + interface Command { + /** + * GenPowerShellCompletionFileWithDesc generates powershell completion file with descriptions. + */ + genPowerShellCompletionFileWithDesc(filename: string): void + } + interface Command { + /** + * GenPowerShellCompletionWithDesc generates powershell completion file with descriptions + * and writes it to the passed writer. + */ + genPowerShellCompletionWithDesc(w: io.Writer): void + } + interface Command { + /** + * MarkFlagRequired instructs the various shell completion implementations to + * prioritize the named flag when performing completion, + * and causes your command to report an error if invoked without the flag. + */ + markFlagRequired(name: string): void + } + interface Command { + /** + * MarkPersistentFlagRequired instructs the various shell completion implementations to + * prioritize the named persistent flag when performing completion, + * and causes your command to report an error if invoked without the flag. + */ + markPersistentFlagRequired(name: string): void + } + interface Command { + /** + * MarkFlagFilename instructs the various shell completion implementations to + * limit completions for the named flag to the specified file extensions. + */ + markFlagFilename(name: string, ...extensions: string[]): void + } + interface Command { + /** + * MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists. + * The bash completion script will call the bash function f for the flag. + * + * This will only work for bash completion. + * It is recommended to instead use c.RegisterFlagCompletionFunc(...) which allows + * to register a Go function which will work across all shells. + */ + markFlagCustom(name: string, f: string): void + } + interface Command { + /** + * MarkPersistentFlagFilename instructs the various shell completion + * implementations to limit completions for the named persistent flag to the + * specified file extensions. + */ + markPersistentFlagFilename(name: string, ...extensions: string[]): void + } + interface Command { + /** + * MarkFlagDirname instructs the various shell completion implementations to + * limit completions for the named flag to directory names. + */ + markFlagDirname(name: string): void + } + interface Command { + /** + * MarkPersistentFlagDirname instructs the various shell completion + * implementations to limit completions for the named persistent flag to + * directory names. + */ + markPersistentFlagDirname(name: string): void + } + interface Command { + /** + * GenZshCompletionFile generates zsh completion file including descriptions. + */ + genZshCompletionFile(filename: string): void + } + interface Command { + /** + * GenZshCompletion generates zsh completion file including descriptions + * and writes it to the passed writer. + */ + genZshCompletion(w: io.Writer): void + } + interface Command { + /** + * GenZshCompletionFileNoDesc generates zsh completion file without descriptions. + */ + genZshCompletionFileNoDesc(filename: string): void + } + interface Command { + /** + * GenZshCompletionNoDesc generates zsh completion file without descriptions + * and writes it to the passed writer. + */ + genZshCompletionNoDesc(w: io.Writer): void + } + interface Command { + /** + * MarkZshCompPositionalArgumentFile only worked for zsh and its behavior was + * not consistent with Bash completion. It has therefore been disabled. + * Instead, when no other completion is specified, file completion is done by + * default for every argument. One can disable file completion on a per-argument + * basis by using ValidArgsFunction and ShellCompDirectiveNoFileComp. + * To achieve file extension filtering, one can use ValidArgsFunction and + * ShellCompDirectiveFilterFileExt. + * + * Deprecated + */ + markZshCompPositionalArgumentFile(argPosition: number, ...patterns: string[]): void + } + interface Command { + /** + * MarkZshCompPositionalArgumentWords only worked for zsh. It has therefore + * been disabled. + * To achieve the same behavior across all shells, one can use + * ValidArgs (for the first argument only) or ValidArgsFunction for + * any argument (can include the first one also). + * + * Deprecated + */ + markZshCompPositionalArgumentWords(argPosition: number, ...words: string[]): void + } +} + +namespace sync { + // @ts-ignore + import isync = sync + /** + * A Locker represents an object that can be locked and unlocked. + */ + interface Locker { + [key:string]: any; + lock(): void + unlock(): void + } +} + +namespace io { + /** + * WriteCloser is the interface that groups the basic Write and Close methods. + */ + interface WriteCloser { + [key:string]: any; + } +} + +namespace bufio { + /** + * Reader implements buffering for an io.Reader object. + * A new Reader is created by calling [NewReader] or [NewReaderSize]; + * alternatively the zero value of a Reader may be used after calling [Reset] + * on it. + */ + interface Reader { + } + interface Reader { + /** + * Size returns the size of the underlying buffer in bytes. + */ + size(): number + } + interface Reader { + /** + * Reset discards any buffered data, resets all state, and switches + * the buffered reader to read from r. + * Calling Reset on the zero value of [Reader] initializes the internal buffer + * to the default size. + * Calling b.Reset(b) (that is, resetting a [Reader] to itself) does nothing. + */ + reset(r: io.Reader): void + } + interface Reader { + /** + * Peek returns the next n bytes without advancing the reader. The bytes stop + * being valid at the next read call. If necessary, Peek will read more bytes + * into the buffer in order to make n bytes available. If Peek returns fewer + * than n bytes, it also returns an error explaining why the read is short. + * The error is [ErrBufferFull] if n is larger than b's buffer size. + * + * Calling Peek prevents a [Reader.UnreadByte] or [Reader.UnreadRune] call from succeeding + * until the next read operation. + */ + peek(n: number): string|Array + } + interface Reader { + /** + * Discard skips the next n bytes, returning the number of bytes discarded. + * + * If Discard skips fewer than n bytes, it also returns an error. + * If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without + * reading from the underlying io.Reader. + */ + discard(n: number): number + } + interface Reader { + /** + * Read reads data into p. + * It returns the number of bytes read into p. + * The bytes are taken from at most one Read on the underlying [Reader], + * hence n may be less than len(p). + * To read exactly len(p) bytes, use io.ReadFull(b, p). + * If the underlying [Reader] can return a non-zero count with io.EOF, + * then this Read method can do so as well; see the [io.Reader] docs. + */ + read(p: string|Array): number + } + interface Reader { + /** + * ReadByte reads and returns a single byte. + * If no byte is available, returns an error. + */ + readByte(): number + } + interface Reader { + /** + * UnreadByte unreads the last byte. Only the most recently read byte can be unread. + * + * UnreadByte returns an error if the most recent method called on the + * [Reader] was not a read operation. Notably, [Reader.Peek], [Reader.Discard], and [Reader.WriteTo] are not + * considered read operations. + */ + unreadByte(): void + } + interface Reader { + /** + * ReadRune reads a single UTF-8 encoded Unicode character and returns the + * rune and its size in bytes. If the encoded rune is invalid, it consumes one byte + * and returns unicode.ReplacementChar (U+FFFD) with a size of 1. + */ + readRune(): [number, number] + } + interface Reader { + /** + * UnreadRune unreads the last rune. If the most recent method called on + * the [Reader] was not a [Reader.ReadRune], [Reader.UnreadRune] returns an error. (In this + * regard it is stricter than [Reader.UnreadByte], which will unread the last byte + * from any read operation.) + */ + unreadRune(): void + } + interface Reader { + /** + * Buffered returns the number of bytes that can be read from the current buffer. + */ + buffered(): number + } + interface Reader { + /** + * ReadSlice reads until the first occurrence of delim in the input, + * returning a slice pointing at the bytes in the buffer. + * The bytes stop being valid at the next read. + * If ReadSlice encounters an error before finding a delimiter, + * it returns all the data in the buffer and the error itself (often io.EOF). + * ReadSlice fails with error [ErrBufferFull] if the buffer fills without a delim. + * Because the data returned from ReadSlice will be overwritten + * by the next I/O operation, most clients should use + * [Reader.ReadBytes] or ReadString instead. + * ReadSlice returns err != nil if and only if line does not end in delim. + */ + readSlice(delim: number): string|Array + } + interface Reader { + /** + * ReadLine is a low-level line-reading primitive. Most callers should use + * [Reader.ReadBytes]('\n') or [Reader.ReadString]('\n') instead or use a [Scanner]. + * + * ReadLine tries to return a single line, not including the end-of-line bytes. + * If the line was too long for the buffer then isPrefix is set and the + * beginning of the line is returned. The rest of the line will be returned + * from future calls. isPrefix will be false when returning the last fragment + * of the line. The returned buffer is only valid until the next call to + * ReadLine. ReadLine either returns a non-nil line or it returns an error, + * never both. + * + * The text returned from ReadLine does not include the line end ("\r\n" or "\n"). + * No indication or error is given if the input ends without a final line end. + * Calling [Reader.UnreadByte] after ReadLine will always unread the last byte read + * (possibly a character belonging to the line end) even if that byte is not + * part of the line returned by ReadLine. + */ + readLine(): [string|Array, boolean] + } + interface Reader { + /** + * ReadBytes reads until the first occurrence of delim in the input, + * returning a slice containing the data up to and including the delimiter. + * If ReadBytes encounters an error before finding a delimiter, + * it returns the data read before the error and the error itself (often io.EOF). + * ReadBytes returns err != nil if and only if the returned data does not end in + * delim. + * For simple uses, a Scanner may be more convenient. + */ + readBytes(delim: number): string|Array + } + interface Reader { + /** + * ReadString reads until the first occurrence of delim in the input, + * returning a string containing the data up to and including the delimiter. + * If ReadString encounters an error before finding a delimiter, + * it returns the data read before the error and the error itself (often io.EOF). + * ReadString returns err != nil if and only if the returned data does not end in + * delim. + * For simple uses, a Scanner may be more convenient. + */ + readString(delim: number): string + } + interface Reader { + /** + * WriteTo implements io.WriterTo. + * This may make multiple calls to the [Reader.Read] method of the underlying [Reader]. + * If the underlying reader supports the [Reader.WriteTo] method, + * this calls the underlying [Reader.WriteTo] without buffering. + */ + writeTo(w: io.Writer): number + } + /** + * Writer implements buffering for an [io.Writer] object. + * If an error occurs writing to a [Writer], no more data will be + * accepted and all subsequent writes, and [Writer.Flush], will return the error. + * After all data has been written, the client should call the + * [Writer.Flush] method to guarantee all data has been forwarded to + * the underlying [io.Writer]. + */ + interface Writer { + } + interface Writer { + /** + * Size returns the size of the underlying buffer in bytes. + */ + size(): number + } + interface Writer { + /** + * Reset discards any unflushed buffered data, clears any error, and + * resets b to write its output to w. + * Calling Reset on the zero value of [Writer] initializes the internal buffer + * to the default size. + * Calling w.Reset(w) (that is, resetting a [Writer] to itself) does nothing. + */ + reset(w: io.Writer): void + } + interface Writer { + /** + * Flush writes any buffered data to the underlying [io.Writer]. + */ + flush(): void + } + interface Writer { + /** + * Available returns how many bytes are unused in the buffer. + */ + available(): number + } + interface Writer { + /** + * AvailableBuffer returns an empty buffer with b.Available() capacity. + * This buffer is intended to be appended to and + * passed to an immediately succeeding [Writer.Write] call. + * The buffer is only valid until the next write operation on b. + */ + availableBuffer(): string|Array + } + interface Writer { + /** + * Buffered returns the number of bytes that have been written into the current buffer. + */ + buffered(): number + } + interface Writer { + /** + * Write writes the contents of p into the buffer. + * It returns the number of bytes written. + * If nn < len(p), it also returns an error explaining + * why the write is short. + */ + write(p: string|Array): number + } + interface Writer { + /** + * WriteByte writes a single byte. + */ + writeByte(c: number): void + } + interface Writer { + /** + * WriteRune writes a single Unicode code point, returning + * the number of bytes written and any error. + */ + writeRune(r: number): number + } + interface Writer { + /** + * WriteString writes a string. + * It returns the number of bytes written. + * If the count is less than len(s), it also returns an error explaining + * why the write is short. + */ + writeString(s: string): number + } + interface Writer { + /** + * ReadFrom implements [io.ReaderFrom]. If the underlying writer + * supports the ReadFrom method, this calls the underlying ReadFrom. + * If there is buffered data and an underlying ReadFrom, this fills + * the buffer and writes it before calling ReadFrom. + */ + readFrom(r: io.Reader): number + } +} + +namespace syscall { + // @ts-ignore + import errpkg = errors + /** + * SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux. + * See user_namespaces(7). + * + * Note that User Namespaces are not available on a number of popular Linux + * versions (due to security issues), or are available but subject to AppArmor + * restrictions like in Ubuntu 24.04. + */ + interface SysProcIDMap { + containerID: number // Container ID. + hostID: number // Host ID. + size: number // Size. + } + // @ts-ignore + import errorspkg = errors + /** + * Credential holds user and group identities to be assumed + * by a child process started by [StartProcess]. + */ + interface Credential { + uid: number // User ID. + gid: number // Group ID. + groups: Array // Supplementary group IDs. + noSetGroups: boolean // If true, don't set supplementary groups + } + // @ts-ignore + import runtimesyscall = syscall + /** + * A Signal is a number describing a process signal. + * It implements the [os.Signal] interface. + */ + interface Signal extends Number{} + interface Signal { + signal(): void + } + interface Signal { + string(): string + } +} + +namespace time { + /** + * A Month specifies a month of the year (January = 1, ...). + */ + interface Month extends Number{} + interface Month { + /** + * String returns the English name of the month ("January", "February", ...). + */ + string(): string + } + /** + * A Weekday specifies a day of the week (Sunday = 0, ...). + */ + interface Weekday extends Number{} + interface Weekday { + /** + * String returns the English name of the day ("Sunday", "Monday", ...). + */ + string(): string + } + /** + * A Location maps time instants to the zone in use at that time. + * Typically, the Location represents the collection of time offsets + * in use in a geographical area. For many Locations the time offset varies + * depending on whether daylight savings time is in use at the time instant. + * + * Location is used to provide a time zone in a printed Time value and for + * calculations involving intervals that may cross daylight savings time + * boundaries. + */ + interface Location { + } + interface Location { + /** + * String returns a descriptive name for the time zone information, + * corresponding to the name argument to [LoadLocation] or [FixedZone]. + */ + string(): string + } +} + +namespace fs { +} + +namespace context { +} + +namespace net { + /** + * Addr represents a network end point address. + * + * The two methods [Addr.Network] and [Addr.String] conventionally return strings + * that can be passed as the arguments to [Dial], but the exact form + * and meaning of the strings is up to the implementation. + */ + interface Addr { + [key:string]: any; + network(): string // name of the network (for example, "tcp", "udp") + string(): string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") + } +} + +/** + * Package textproto implements generic support for text-based request/response + * protocols in the style of HTTP, NNTP, and SMTP. + * + * The package provides: + * + * [Error], which represents a numeric error response from + * a server. + * + * [Pipeline], to manage pipelined requests and responses + * in a client. + * + * [Reader], to read numeric response code lines, + * key: value headers, lines wrapped with leading spaces + * on continuation lines, and whole text blocks ending + * with a dot on a line by itself. + * + * [Writer], to write dot-encoded text blocks. + * + * [Conn], a convenient packaging of [Reader], [Writer], and [Pipeline] for use + * with a single network connection. + */ +namespace textproto { + /** + * A MIMEHeader represents a MIME-style header mapping + * keys to sets of values. + */ + interface MIMEHeader extends _TygojaDict{} + interface MIMEHeader { + /** + * Add adds the key, value pair to the header. + * It appends to any existing values associated with key. + */ + add(key: string, value: string): void + } + interface MIMEHeader { + /** + * Set sets the header entries associated with key to + * the single element value. It replaces any existing + * values associated with key. + */ + set(key: string, value: string): void + } + interface MIMEHeader { + /** + * Get gets the first value associated with the given key. + * It is case insensitive; [CanonicalMIMEHeaderKey] is used + * to canonicalize the provided key. + * If there are no values associated with the key, Get returns "". + * To use non-canonical keys, access the map directly. + */ + get(key: string): string + } + interface MIMEHeader { + /** + * Values returns all values associated with the given key. + * It is case insensitive; [CanonicalMIMEHeaderKey] is + * used to canonicalize the provided key. To use non-canonical + * keys, access the map directly. + * The returned slice is not a copy. + */ + values(key: string): Array + } + interface MIMEHeader { + /** + * Del deletes the values associated with key. + */ + del(key: string): void + } +} + +namespace multipart { + interface Reader { + /** + * ReadForm parses an entire multipart message whose parts have + * a Content-Disposition of "form-data". + * It stores up to maxMemory bytes + 10MB (reserved for non-file parts) + * in memory. File parts which can't be stored in memory will be stored on + * disk in temporary files. + * It returns [ErrMessageTooLarge] if all non-file parts can't be stored in + * memory. + */ + readForm(maxMemory: number): (Form) + } + /** + * Form is a parsed multipart form. + * Its File parts are stored either in memory or on disk, + * and are accessible via the [*FileHeader]'s Open method. + * Its Value parts are stored as strings. + * Both are keyed by field name. + */ + interface Form { + value: _TygojaDict + file: _TygojaDict + } + interface Form { + /** + * RemoveAll removes any temporary files associated with a [Form]. + */ + removeAll(): void + } + /** + * File is an interface to access the file part of a multipart message. + * Its contents may be either stored in memory or on disk. + * If stored on disk, the File's underlying concrete type will be an *os.File. + */ + interface File { + [key:string]: any; + } + /** + * Reader is an iterator over parts in a MIME multipart body. + * Reader's underlying parser consumes its input as needed. Seeking + * isn't supported. + */ + interface Reader { + } + interface Reader { + /** + * NextPart returns the next part in the multipart or an error. + * When there are no more parts, the error [io.EOF] is returned. + * + * As a special case, if the "Content-Transfer-Encoding" header + * has a value of "quoted-printable", that header is instead + * hidden and the body is transparently decoded during Read calls. + */ + nextPart(): (Part) + } + interface Reader { + /** + * NextRawPart returns the next part in the multipart or an error. + * When there are no more parts, the error [io.EOF] is returned. + * + * Unlike [Reader.NextPart], it does not have special handling for + * "Content-Transfer-Encoding: quoted-printable". + */ + nextRawPart(): (Part) + } +} + +namespace store { +} + +/** + * Package url parses URLs and implements query escaping. + */ +namespace url { + /** + * A URL represents a parsed URL (technically, a URI reference). + * + * The general form represented is: + * + * ``` + * [scheme:][//[userinfo@]host][/]path[?query][#fragment] + * ``` + * + * URLs that do not start with a slash after the scheme are interpreted as: + * + * ``` + * scheme:opaque[?query][#fragment] + * ``` + * + * The Host field contains the host and port subcomponents of the URL. + * When the port is present, it is separated from the host with a colon. + * When the host is an IPv6 address, it must be enclosed in square brackets: + * "[fe80::1]:80". The [net.JoinHostPort] function combines a host and port + * into a string suitable for the Host field, adding square brackets to + * the host when necessary. + * + * Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. + * A consequence is that it is impossible to tell which slashes in the Path were + * slashes in the raw URL and which were %2f. This distinction is rarely important, + * but when it is, the code should use the [URL.EscapedPath] method, which preserves + * the original encoding of Path. + * + * The RawPath field is an optional field which is only set when the default + * encoding of Path is different from the escaped path. See the EscapedPath method + * for more details. + * + * URL's String method uses the EscapedPath method to obtain the path. + */ + interface URL { + scheme: string + opaque: string // encoded opaque data + user?: Userinfo // username and password information + host: string // host or host:port (see Hostname and Port methods) + path: string // path (relative paths may omit leading slash) + rawPath: string // encoded path hint (see EscapedPath method) + omitHost: boolean // do not emit empty host (authority) + forceQuery: boolean // append a query ('?') even if RawQuery is empty + rawQuery: string // encoded query values, without '?' + fragment: string // fragment for references, without '#' + rawFragment: string // encoded fragment hint (see EscapedFragment method) + } + interface URL { + /** + * EscapedPath returns the escaped form of u.Path. + * In general there are multiple possible escaped forms of any path. + * EscapedPath returns u.RawPath when it is a valid escaping of u.Path. + * Otherwise EscapedPath ignores u.RawPath and computes an escaped + * form on its own. + * The [URL.String] and [URL.RequestURI] methods use EscapedPath to construct + * their results. + * In general, code should call EscapedPath instead of + * reading u.RawPath directly. + */ + escapedPath(): string + } + interface URL { + /** + * EscapedFragment returns the escaped form of u.Fragment. + * In general there are multiple possible escaped forms of any fragment. + * EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. + * Otherwise EscapedFragment ignores u.RawFragment and computes an escaped + * form on its own. + * The [URL.String] method uses EscapedFragment to construct its result. + * In general, code should call EscapedFragment instead of + * reading u.RawFragment directly. + */ + escapedFragment(): string + } + interface URL { + /** + * String reassembles the [URL] into a valid URL string. + * The general form of the result is one of: + * + * ``` + * scheme:opaque?query#fragment + * scheme://userinfo@host/path?query#fragment + * ``` + * + * If u.Opaque is non-empty, String uses the first form; + * otherwise it uses the second form. + * Any non-ASCII characters in host are escaped. + * To obtain the path, String uses u.EscapedPath(). + * + * In the second form, the following rules apply: + * ``` + * - if u.Scheme is empty, scheme: is omitted. + * - if u.User is nil, userinfo@ is omitted. + * - if u.Host is empty, host/ is omitted. + * - if u.Scheme and u.Host are empty and u.User is nil, + * the entire scheme://userinfo@host/ is omitted. + * - if u.Host is non-empty and u.Path begins with a /, + * the form host/path does not add its own /. + * - if u.RawQuery is empty, ?query is omitted. + * - if u.Fragment is empty, #fragment is omitted. + * ``` + */ + string(): string + } + interface URL { + /** + * Redacted is like [URL.String] but replaces any password with "xxxxx". + * Only the password in u.User is redacted. + */ + redacted(): string + } + /** + * Values maps a string key to a list of values. + * It is typically used for query parameters and form values. + * Unlike in the http.Header map, the keys in a Values map + * are case-sensitive. + */ + interface Values extends _TygojaDict{} + interface Values { + /** + * Get gets the first value associated with the given key. + * If there are no values associated with the key, Get returns + * the empty string. To access multiple values, use the map + * directly. + */ + get(key: string): string + } + interface Values { + /** + * Set sets the key to value. It replaces any existing + * values. + */ + set(key: string, value: string): void + } + interface Values { + /** + * Add adds the value to key. It appends to any existing + * values associated with key. + */ + add(key: string, value: string): void + } + interface Values { + /** + * Del deletes the values associated with key. + */ + del(key: string): void + } + interface Values { + /** + * Has checks whether a given key is set. + */ + has(key: string): boolean + } + interface Values { + /** + * Encode encodes the values into “URL encoded” form + * ("bar=baz&foo=quux") sorted by key. + */ + encode(): string + } + interface URL { + /** + * IsAbs reports whether the [URL] is absolute. + * Absolute means that it has a non-empty scheme. + */ + isAbs(): boolean + } + interface URL { + /** + * Parse parses a [URL] in the context of the receiver. The provided URL + * may be relative or absolute. Parse returns nil, err on parse + * failure, otherwise its return value is the same as [URL.ResolveReference]. + */ + parse(ref: string): (URL) + } + interface URL { + /** + * ResolveReference resolves a URI reference to an absolute URI from + * an absolute base URI u, per RFC 3986 Section 5.2. The URI reference + * may be relative or absolute. ResolveReference always returns a new + * [URL] instance, even if the returned URL is identical to either the + * base or reference. If ref is an absolute URL, then ResolveReference + * ignores base and returns a copy of ref. + */ + resolveReference(ref: URL): (URL) + } + interface URL { + /** + * Query parses RawQuery and returns the corresponding values. + * It silently discards malformed value pairs. + * To check errors use [ParseQuery]. + */ + query(): Values + } + interface URL { + /** + * RequestURI returns the encoded path?query or opaque?query + * string that would be used in an HTTP request for u. + */ + requestURI(): string + } + interface URL { + /** + * Hostname returns u.Host, stripping any valid port number if present. + * + * If the result is enclosed in square brackets, as literal IPv6 addresses are, + * the square brackets are removed from the result. + */ + hostname(): string + } + interface URL { + /** + * Port returns the port part of u.Host, without the leading colon. + * + * If u.Host doesn't contain a valid numeric port, Port returns an empty string. + */ + port(): string + } + interface URL { + marshalBinary(): string|Array + } + interface URL { + appendBinary(b: string|Array): string|Array + } + interface URL { + unmarshalBinary(text: string|Array): void + } + interface URL { + /** + * JoinPath returns a new [URL] with the provided path elements joined to + * any existing path and the resulting path cleaned of any ./ or ../ elements. + * Any sequences of multiple / characters will be reduced to a single /. + */ + joinPath(...elem: string[]): (URL) + } +} + +namespace jwt { + /** + * NumericDate represents a JSON numeric date value, as referenced at + * https://datatracker.ietf.org/doc/html/rfc7519#section-2. + */ + type _sirPdFg = time.Time + interface NumericDate extends _sirPdFg { + } + interface NumericDate { + /** + * MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch + * represented in NumericDate to a byte array, using the precision specified in TimePrecision. + */ + marshalJSON(): string|Array + } + interface NumericDate { + /** + * UnmarshalJSON is an implementation of the json.RawMessage interface and + * deserializes a [NumericDate] from a JSON representation, i.e. a + * [json.Number]. This number represents an UNIX epoch with either integer or + * non-integer seconds. + */ + unmarshalJSON(b: string|Array): void + } + /** + * ClaimStrings is basically just a slice of strings, but it can be either + * serialized from a string array or just a string. This type is necessary, + * since the "aud" claim can either be a single string or an array. + */ + interface ClaimStrings extends Array{} + interface ClaimStrings { + unmarshalJSON(data: string|Array): void + } + interface ClaimStrings { + marshalJSON(): string|Array + } +} + +namespace hook { + /** + * wrapped local Hook embedded struct to limit the public API surface. + */ + type _sBOLBAI = Hook + interface mainHook extends _sBOLBAI { + } +} + +namespace sql { + /** + * IsolationLevel is the transaction isolation level used in [TxOptions]. + */ + interface IsolationLevel extends Number{} + interface IsolationLevel { + /** + * String returns the name of the transaction isolation level. + */ + string(): string + } + /** + * DBStats contains database statistics. + */ + interface DBStats { + maxOpenConnections: number // Maximum number of open connections to the database. + /** + * Pool Status + */ + openConnections: number // The number of established connections both in use and idle. + inUse: number // The number of connections currently in use. + idle: number // The number of idle connections. + /** + * Counters + */ + waitCount: number // The total number of connections waited for. + waitDuration: time.Duration // The total time blocked waiting for a new connection. + maxIdleClosed: number // The total number of connections closed due to SetMaxIdleConns. + maxIdleTimeClosed: number // The total number of connections closed due to SetConnMaxIdleTime. + maxLifetimeClosed: number // The total number of connections closed due to SetConnMaxLifetime. + } + /** + * Conn represents a single database connection rather than a pool of database + * connections. Prefer running queries from [DB] unless there is a specific + * need for a continuous single database connection. + * + * A Conn must call [Conn.Close] to return the connection to the database pool + * and may do so concurrently with a running query. + * + * After a call to [Conn.Close], all operations on the + * connection fail with [ErrConnDone]. + */ + interface Conn { + } + interface Conn { + /** + * PingContext verifies the connection to the database is still alive. + */ + pingContext(ctx: context.Context): void + } + interface Conn { + /** + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Conn { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Conn { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * the [*Row.Scan] method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Conn { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface Conn { + /** + * Raw executes f exposing the underlying driver connection for the + * duration of f. The driverConn must not be used outside of f. + * + * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable + * until [Conn.Close] is called. + */ + raw(f: (driverConn: any) => void): void + } + interface Conn { + /** + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. + */ + beginTx(ctx: context.Context, opts: TxOptions): (Tx) + } + interface Conn { + /** + * Close returns the connection to the connection pool. + * All operations after a Close will return with [ErrConnDone]. + * Close is safe to call concurrently with other operations and will + * block until all other operations finish. It may be useful to first + * cancel any used context and then call close directly after. + */ + close(): void + } + /** + * ColumnType contains the name and type of a column. + */ + interface ColumnType { + } + interface ColumnType { + /** + * Name returns the name or alias of the column. + */ + name(): string + } + interface ColumnType { + /** + * Length returns the column type length for variable length column types such + * as text and binary field types. If the type length is unbounded the value will + * be [math.MaxInt64] (any database limits will still apply). + * If the column type is not variable length, such as an int, or if not supported + * by the driver ok is false. + */ + length(): [number, boolean] + } + interface ColumnType { + /** + * DecimalSize returns the scale and precision of a decimal type. + * If not applicable or if not supported ok is false. + */ + decimalSize(): [number, number, boolean] + } + interface ColumnType { + /** + * ScanType returns a Go type suitable for scanning into using [Rows.Scan]. + * If a driver does not support this property ScanType will return + * the type of an empty interface. + */ + scanType(): any + } + interface ColumnType { + /** + * Nullable reports whether the column may be null. + * If a driver does not support this property ok will be false. + */ + nullable(): [boolean, boolean] + } + interface ColumnType { + /** + * DatabaseTypeName returns the database system name of the column type. If an empty + * string is returned, then the driver type name is not supported. + * Consult your driver documentation for a list of driver data types. [ColumnType.Length] specifiers + * are not included. + * Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", + * "INT", and "BIGINT". + */ + databaseTypeName(): string + } + /** + * Row is the result of calling [DB.QueryRow] to select a single row. + */ + interface Row { + } + interface Row { + /** + * Scan copies the columns from the matched row into the values + * pointed at by dest. See the documentation on [Rows.Scan] for details. + * If more than one row matches the query, + * Scan uses the first row and discards the rest. If no row matches + * the query, Scan returns [ErrNoRows]. + */ + scan(...dest: any[]): void + } + interface Row { + /** + * Err provides a way for wrapping packages to check for + * query errors without calling [Row.Scan]. + * Err returns the error, if any, that was encountered while running the query. + * If this error is not nil, this error will also be returned from [Row.Scan]. + */ + err(): void + } +} + +namespace http { + /** + * A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an + * HTTP response or the Cookie header of an HTTP request. + * + * See https://tools.ietf.org/html/rfc6265 for details. + */ + interface Cookie { + name: string + value: string + quoted: boolean // indicates whether the Value was originally quoted + path: string // optional + domain: string // optional + expires: time.Time // optional + rawExpires: string // for reading cookies only + /** + * MaxAge=0 means no 'Max-Age' attribute specified. + * MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' + * MaxAge>0 means Max-Age attribute present and given in seconds + */ + maxAge: number + secure: boolean + httpOnly: boolean + sameSite: SameSite + partitioned: boolean + raw: string + unparsed: Array // Raw text of unparsed attribute-value pairs + } + interface Cookie { + /** + * String returns the serialization of the cookie for use in a [Cookie] + * header (if only Name and Value are set) or a Set-Cookie response + * header (if other fields are set). + * If c is nil or c.Name is invalid, the empty string is returned. + */ + string(): string + } + interface Cookie { + /** + * Valid reports whether the cookie is valid. + */ + valid(): void + } + // @ts-ignore + import mathrand = rand + /** + * A Header represents the key-value pairs in an HTTP header. + * + * The keys should be in canonical form, as returned by + * [CanonicalHeaderKey]. + */ + interface Header extends _TygojaDict{} + interface Header { + /** + * Add adds the key, value pair to the header. + * It appends to any existing values associated with key. + * The key is case insensitive; it is canonicalized by + * [CanonicalHeaderKey]. + */ + add(key: string, value: string): void + } + interface Header { + /** + * Set sets the header entries associated with key to the + * single element value. It replaces any existing values + * associated with key. The key is case insensitive; it is + * canonicalized by [textproto.CanonicalMIMEHeaderKey]. + * To use non-canonical keys, assign to the map directly. + */ + set(key: string, value: string): void + } + interface Header { + /** + * Get gets the first value associated with the given key. If + * there are no values associated with the key, Get returns "". + * It is case insensitive; [textproto.CanonicalMIMEHeaderKey] is + * used to canonicalize the provided key. Get assumes that all + * keys are stored in canonical form. To use non-canonical keys, + * access the map directly. + */ + get(key: string): string + } + interface Header { + /** + * Values returns all values associated with the given key. + * It is case insensitive; [textproto.CanonicalMIMEHeaderKey] is + * used to canonicalize the provided key. To use non-canonical + * keys, access the map directly. + * The returned slice is not a copy. + */ + values(key: string): Array + } + interface Header { + /** + * Del deletes the values associated with key. + * The key is case insensitive; it is canonicalized by + * [CanonicalHeaderKey]. + */ + del(key: string): void + } + interface Header { + /** + * Write writes a header in wire format. + */ + write(w: io.Writer): void + } + interface Header { + /** + * Clone returns a copy of h or nil if h is nil. + */ + clone(): Header + } + interface Header { + /** + * WriteSubset writes a header in wire format. + * If exclude is not nil, keys where exclude[key] == true are not written. + * Keys are not canonicalized before checking the exclude map. + */ + writeSubset(w: io.Writer, exclude: _TygojaDict): void + } + /** + * Protocols is a set of HTTP protocols. + * The zero value is an empty set of protocols. + * + * The supported protocols are: + * + * ``` + * - HTTP1 is the HTTP/1.0 and HTTP/1.1 protocols. + * HTTP1 is supported on both unsecured TCP and secured TLS connections. + * + * - HTTP2 is the HTTP/2 protcol over a TLS connection. + * + * - UnencryptedHTTP2 is the HTTP/2 protocol over an unsecured TCP connection. + * ``` + */ + interface Protocols { + } + interface Protocols { + /** + * HTTP1 reports whether p includes HTTP/1. + */ + http1(): boolean + } + interface Protocols { + /** + * SetHTTP1 adds or removes HTTP/1 from p. + */ + setHTTP1(ok: boolean): void + } + interface Protocols { + /** + * HTTP2 reports whether p includes HTTP/2. + */ + http2(): boolean + } + interface Protocols { + /** + * SetHTTP2 adds or removes HTTP/2 from p. + */ + setHTTP2(ok: boolean): void + } + interface Protocols { + /** + * UnencryptedHTTP2 reports whether p includes unencrypted HTTP/2. + */ + unencryptedHTTP2(): boolean + } + interface Protocols { + /** + * SetUnencryptedHTTP2 adds or removes unencrypted HTTP/2 from p. + */ + setUnencryptedHTTP2(ok: boolean): void + } + interface Protocols { + string(): string + } + /** + * HTTP2Config defines HTTP/2 configuration parameters common to + * both [Transport] and [Server]. + */ + interface HTTP2Config { + /** + * MaxConcurrentStreams optionally specifies the number of + * concurrent streams that a peer may have open at a time. + * If zero, MaxConcurrentStreams defaults to at least 100. + */ + maxConcurrentStreams: number + /** + * MaxDecoderHeaderTableSize optionally specifies an upper limit for the + * size of the header compression table used for decoding headers sent + * by the peer. + * A valid value is less than 4MiB. + * If zero or invalid, a default value is used. + */ + maxDecoderHeaderTableSize: number + /** + * MaxEncoderHeaderTableSize optionally specifies an upper limit for the + * header compression table used for sending headers to the peer. + * A valid value is less than 4MiB. + * If zero or invalid, a default value is used. + */ + maxEncoderHeaderTableSize: number + /** + * MaxReadFrameSize optionally specifies the largest frame + * this endpoint is willing to read. + * A valid value is between 16KiB and 16MiB, inclusive. + * If zero or invalid, a default value is used. + */ + maxReadFrameSize: number + /** + * MaxReceiveBufferPerConnection is the maximum size of the + * flow control window for data received on a connection. + * A valid value is at least 64KiB and less than 4MiB. + * If invalid, a default value is used. + */ + maxReceiveBufferPerConnection: number + /** + * MaxReceiveBufferPerStream is the maximum size of + * the flow control window for data received on a stream (request). + * A valid value is less than 4MiB. + * If zero or invalid, a default value is used. + */ + maxReceiveBufferPerStream: number + /** + * SendPingTimeout is the timeout after which a health check using a ping + * frame will be carried out if no frame is received on a connection. + * If zero, no health check is performed. + */ + sendPingTimeout: time.Duration + /** + * PingTimeout is the timeout after which a connection will be closed + * if a response to a ping is not received. + * If zero, a default of 15 seconds is used. + */ + pingTimeout: time.Duration + /** + * WriteByteTimeout is the timeout after which a connection will be + * closed if no data can be written to it. The timeout begins when data is + * available to write, and is extended whenever any bytes are written. + */ + writeByteTimeout: time.Duration + /** + * PermitProhibitedCipherSuites, if true, permits the use of + * cipher suites prohibited by the HTTP/2 spec. + */ + permitProhibitedCipherSuites: boolean + /** + * CountError, if non-nil, is called on HTTP/2 errors. + * It is intended to increment a metric for monitoring. + * The errType contains only lowercase letters, digits, and underscores + * (a-z, 0-9, _). + */ + countError: (errType: string) => void + } + // @ts-ignore + import urlpkg = url + /** + * Response represents the response from an HTTP request. + * + * The [Client] and [Transport] return Responses from servers once + * the response headers have been received. The response body + * is streamed on demand as the Body field is read. + */ + interface Response { + status: string // e.g. "200 OK" + statusCode: number // e.g. 200 + proto: string // e.g. "HTTP/1.0" + protoMajor: number // e.g. 1 + protoMinor: number // e.g. 0 + /** + * Header maps header keys to values. If the response had multiple + * headers with the same key, they may be concatenated, with comma + * delimiters. (RFC 7230, section 3.2.2 requires that multiple headers + * be semantically equivalent to a comma-delimited sequence.) When + * Header values are duplicated by other fields in this struct (e.g., + * ContentLength, TransferEncoding, Trailer), the field values are + * authoritative. + * + * Keys in the map are canonicalized (see CanonicalHeaderKey). + */ + header: Header + /** + * Body represents the response body. + * + * The response body is streamed on demand as the Body field + * is read. If the network connection fails or the server + * terminates the response, Body.Read calls return an error. + * + * The http Client and Transport guarantee that Body is always + * non-nil, even on responses without a body or responses with + * a zero-length body. It is the caller's responsibility to + * close Body. The default HTTP client's Transport may not + * reuse HTTP/1.x "keep-alive" TCP connections if the Body is + * not read to completion and closed. + * + * The Body is automatically dechunked if the server replied + * with a "chunked" Transfer-Encoding. + * + * As of Go 1.12, the Body will also implement io.Writer + * on a successful "101 Switching Protocols" response, + * as used by WebSockets and HTTP/2's "h2c" mode. + */ + body: io.ReadCloser + /** + * ContentLength records the length of the associated content. The + * value -1 indicates that the length is unknown. Unless Request.Method + * is "HEAD", values >= 0 indicate that the given number of bytes may + * be read from Body. + */ + contentLength: number + /** + * Contains transfer encodings from outer-most to inner-most. Value is + * nil, means that "identity" encoding is used. + */ + transferEncoding: Array + /** + * Close records whether the header directed that the connection be + * closed after reading Body. The value is advice for clients: neither + * ReadResponse nor Response.Write ever closes a connection. + */ + close: boolean + /** + * Uncompressed reports whether the response was sent compressed but + * was decompressed by the http package. When true, reading from + * Body yields the uncompressed content instead of the compressed + * content actually set from the server, ContentLength is set to -1, + * and the "Content-Length" and "Content-Encoding" fields are deleted + * from the responseHeader. To get the original response from + * the server, set Transport.DisableCompression to true. + */ + uncompressed: boolean + /** + * Trailer maps trailer keys to values in the same + * format as Header. + * + * The Trailer initially contains only nil values, one for + * each key specified in the server's "Trailer" header + * value. Those values are not added to Header. + * + * Trailer must not be accessed concurrently with Read calls + * on the Body. + * + * After Body.Read has returned io.EOF, Trailer will contain + * any trailer values sent by the server. + */ + trailer: Header + /** + * Request is the request that was sent to obtain this Response. + * Request's Body is nil (having already been consumed). + * This is only populated for Client requests. + */ + request?: Request + /** + * TLS contains information about the TLS connection on which the + * response was received. It is nil for unencrypted responses. + * The pointer is shared between responses and should not be + * modified. + */ + tls?: any + } + interface Response { + /** + * Cookies parses and returns the cookies set in the Set-Cookie headers. + */ + cookies(): Array<(Cookie | undefined)> + } + interface Response { + /** + * Location returns the URL of the response's "Location" header, + * if present. Relative redirects are resolved relative to + * [Response.Request]. [ErrNoLocation] is returned if no + * Location header is present. + */ + location(): (url.URL) + } + interface Response { + /** + * ProtoAtLeast reports whether the HTTP protocol used + * in the response is at least major.minor. + */ + protoAtLeast(major: number, minor: number): boolean + } + interface Response { + /** + * Write writes r to w in the HTTP/1.x server response format, + * including the status line, headers, body, and optional trailer. + * + * This method consults the following fields of the response r: + * + * ``` + * StatusCode + * ProtoMajor + * ProtoMinor + * Request.Method + * TransferEncoding + * Trailer + * Body + * ContentLength + * Header, values for non-canonical keys will have unpredictable behavior + * ``` + * + * The Response Body is closed after it is sent. + */ + write(w: io.Writer): void + } + /** + * A ConnState represents the state of a client connection to a server. + * It's used by the optional [Server.ConnState] hook. + */ + interface ConnState extends Number{} + interface ConnState { + string(): string + } +} + +namespace types { +} + +namespace search { +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation + /** + * RouterGroup represents a collection of routes and other sub groups + * that share common pattern prefix and middlewares. + */ + interface RouterGroup { + prefix: string + middlewares: Array<(hook.Handler | undefined)> + } + interface RouterGroup { + /** + * Group creates and register a new child Group into the current one + * with the specified prefix. + * + * The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]") + * and will be concatenated recursively into the final route path, meaning that + * only the root level group could have HOST as part of the prefix. + * + * Returns the newly created group to allow chaining and registering + * sub-routes and group specific middlewares. + */ + group(prefix: string): (RouterGroup) + } + interface RouterGroup { + /** + * BindFunc registers one or multiple middleware functions to the current group. + * + * The registered middleware functions are "anonymous" and with default priority, + * aka. executes in the order they were registered. + * + * If you need to specify a named middleware (ex. so that it can be removed) + * or middleware with custom exec prirority, use [RouterGroup.Bind] method. + */ + bindFunc(...middlewareFuncs: ((e: T) => void)[]): (RouterGroup) + } + interface RouterGroup { + /** + * Bind registers one or multiple middleware handlers to the current group. + */ + bind(...middlewares: (hook.Handler | undefined)[]): (RouterGroup) + } + interface RouterGroup { + /** + * Unbind removes one or more middlewares with the specified id(s) + * from the current group and its children (if any). + * + * Anonymous middlewares are not removable, aka. this method does nothing + * if the middleware id is an empty string. + */ + unbind(...middlewareIds: string[]): (RouterGroup) + } + interface RouterGroup { + /** + * Route registers a single route into the current group. + * + * Note that the final route path will be the concatenation of all parent groups prefixes + the route path. + * The path follows the standard Go net/http ServeMux format ("[HOST]/[PATH]"), + * meaning that only a top level group route could have HOST as part of the prefix. + * + * Returns the newly created route to allow attaching route-only middlewares. + */ + route(method: string, path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * Any is a shorthand for [RouterGroup.AddRoute] with "" as route method (aka. matches any method). + */ + any(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * GET is a shorthand for [RouterGroup.AddRoute] with GET as route method. + */ + get(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * SEARCH is a shorthand for [RouterGroup.AddRoute] with SEARCH as route method. + */ + search(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * POST is a shorthand for [RouterGroup.AddRoute] with POST as route method. + */ + post(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * DELETE is a shorthand for [RouterGroup.AddRoute] with DELETE as route method. + */ + delete(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * PATCH is a shorthand for [RouterGroup.AddRoute] with PATCH as route method. + */ + patch(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * PUT is a shorthand for [RouterGroup.AddRoute] with PUT as route method. + */ + put(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * HEAD is a shorthand for [RouterGroup.AddRoute] with HEAD as route method. + */ + head(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * OPTIONS is a shorthand for [RouterGroup.AddRoute] with OPTIONS as route method. + */ + options(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * HasRoute checks whether the specified route pattern (method + path) + * is registered in the current group or its children. + * + * This could be useful to conditionally register and checks for routes + * in order prevent panic on duplicated routes. + * + * Note that routes with anonymous and named wildcard placeholder are treated as equal, + * aka. "GET /abc/" is considered the same as "GET /abc/{something...}". + */ + hasRoute(method: string, path: string): boolean + } +} + +namespace cobra { + interface PositionalArgs {(cmd: Command, args: Array): void } + // @ts-ignore + import flag = pflag + /** + * FParseErrWhitelist configures Flag parse errors to be ignored + */ + interface FParseErrWhitelist extends _TygojaAny{} + /** + * Group Structure to manage groups for commands + */ + interface Group { + id: string + title: string + } + /** + * CompletionOptions are the options to control shell completion + */ + interface CompletionOptions { + /** + * DisableDefaultCmd prevents Cobra from creating a default 'completion' command + */ + disableDefaultCmd: boolean + /** + * DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag + * for shells that support completion descriptions + */ + disableNoDescFlag: boolean + /** + * DisableDescriptions turns off all completion descriptions for shells + * that support them + */ + disableDescriptions: boolean + /** + * HiddenDefaultCmd makes the default 'completion' command hidden + */ + hiddenDefaultCmd: boolean + /** + * DefaultShellCompDirective sets the ShellCompDirective that is returned + * if no special directive can be determined + */ + defaultShellCompDirective?: ShellCompDirective + } + interface CompletionOptions { + setDefaultShellCompDirective(directive: ShellCompDirective): void + } + /** + * Completion is a string that can be used for completions + * + * two formats are supported: + * ``` + * - the completion choice + * - the completion choice with a textual description (separated by a TAB). + * ``` + * + * [CompletionWithDesc] can be used to create a completion string with a textual description. + * + * Note: Go type alias is used to provide a more descriptive name in the documentation, but any string can be used. + */ + interface Completion extends String{} + /** + * CompletionFunc is a function that provides completion results. + */ + interface CompletionFunc {(cmd: Command, args: Array, toComplete: string): [Array, ShellCompDirective] } +} + +/** + * Package oauth2 provides support for making + * OAuth2 authorized and authenticated HTTP requests, + * as specified in RFC 6749. + * It can additionally grant authorization with Bearer JWT. + */ +namespace oauth2 { + /** + * An AuthCodeOption is passed to Config.AuthCodeURL. + */ + interface AuthCodeOption { + [key:string]: any; + } + /** + * Token represents the credentials used to authorize + * the requests to access protected resources on the OAuth 2.0 + * provider's backend. + * + * Most users of this package should not access fields of Token + * directly. They're exported mostly for use by related packages + * implementing derivative OAuth2 flows. + */ + interface Token { + /** + * AccessToken is the token that authorizes and authenticates + * the requests. + */ + accessToken: string + /** + * TokenType is the type of token. + * The Type method returns either this or "Bearer", the default. + */ + tokenType: string + /** + * RefreshToken is a token that's used by the application + * (as opposed to the user) to refresh the access token + * if it expires. + */ + refreshToken: string + /** + * Expiry is the optional expiration time of the access token. + * + * If zero, [TokenSource] implementations will reuse the same + * token forever and RefreshToken or equivalent + * mechanisms for that TokenSource will not be used. + */ + expiry: time.Time + /** + * ExpiresIn is the OAuth2 wire format "expires_in" field, + * which specifies how many seconds later the token expires, + * relative to an unknown time base approximately around "now". + * It is the application's responsibility to populate + * `Expiry` from `ExpiresIn` when required. + */ + expiresIn: number + } + interface Token { + /** + * Type returns t.TokenType if non-empty, else "Bearer". + */ + type(): string + } + interface Token { + /** + * SetAuthHeader sets the Authorization header to r using the access + * token in t. + * + * This method is unnecessary when using [Transport] or an HTTP Client + * returned by this package. + */ + setAuthHeader(r: http.Request): void + } + interface Token { + /** + * WithExtra returns a new [Token] that's a clone of t, but using the + * provided raw extra map. This is only intended for use by packages + * implementing derivative OAuth2 flows. + */ + withExtra(extra: any): (Token) + } + interface Token { + /** + * Extra returns an extra field. + * Extra fields are key-value pairs returned by the server as a + * part of the token retrieval response. + */ + extra(key: string): any + } + interface Token { + /** + * Valid reports whether t is non-nil, has an AccessToken, and is not expired. + */ + valid(): boolean + } +} + +namespace subscriptions { +} + +namespace cron { + /** + * Job defines a single registered cron job. + */ + interface Job { + } + interface Job { + /** + * Id returns the cron job id. + */ + id(): string + } + interface Job { + /** + * Expression returns the plain cron job schedule expression. + */ + expression(): string + } + interface Job { + /** + * Run runs the cron job function. + */ + run(): void + } + interface Job { + /** + * MarshalJSON implements [json.Marshaler] and export the current + * jobs data into valid JSON. + */ + marshalJSON(): string|Array + } +} + +namespace slog { + /** + * An Attr is a key-value pair. + */ + interface Attr { + key: string + value: Value + } + interface Attr { + /** + * Equal reports whether a and b have equal keys and values. + */ + equal(b: Attr): boolean + } + interface Attr { + string(): string + } + /** + * A Handler handles log records produced by a Logger. + * + * A typical handler may print log records to standard error, + * or write them to a file or database, or perhaps augment them + * with additional attributes and pass them on to another handler. + * + * Any of the Handler's methods may be called concurrently with itself + * or with other methods. It is the responsibility of the Handler to + * manage this concurrency. + * + * Users of the slog package should not invoke Handler methods directly. + * They should use the methods of [Logger] instead. + */ + interface Handler { + [key:string]: any; + /** + * Enabled reports whether the handler handles records at the given level. + * The handler ignores records whose level is lower. + * It is called early, before any arguments are processed, + * to save effort if the log event should be discarded. + * If called from a Logger method, the first argument is the context + * passed to that method, or context.Background() if nil was passed + * or the method does not take a context. + * The context is passed so Enabled can use its values + * to make a decision. + */ + enabled(_arg0: context.Context, _arg1: Level): boolean + /** + * Handle handles the Record. + * It will only be called when Enabled returns true. + * The Context argument is as for Enabled. + * It is present solely to provide Handlers access to the context's values. + * Canceling the context should not affect record processing. + * (Among other things, log messages may be necessary to debug a + * cancellation-related problem.) + * + * Handle methods that produce output should observe the following rules: + * ``` + * - If r.Time is the zero time, ignore the time. + * - If r.PC is zero, ignore it. + * - Attr's values should be resolved. + * - If an Attr's key and value are both the zero value, ignore the Attr. + * This can be tested with attr.Equal(Attr{}). + * - If a group's key is empty, inline the group's Attrs. + * - If a group has no Attrs (even if it has a non-empty key), + * ignore it. + * ``` + */ + handle(_arg0: context.Context, _arg1: Record): void + /** + * WithAttrs returns a new Handler whose attributes consist of + * both the receiver's attributes and the arguments. + * The Handler owns the slice: it may retain, modify or discard it. + */ + withAttrs(attrs: Array): Handler + /** + * WithGroup returns a new Handler with the given group appended to + * the receiver's existing groups. + * The keys of all subsequent attributes, whether added by With or in a + * Record, should be qualified by the sequence of group names. + * + * How this qualification happens is up to the Handler, so long as + * this Handler's attribute keys differ from those of another Handler + * with a different sequence of group names. + * + * A Handler should treat WithGroup as starting a Group of Attrs that ends + * at the end of the log event. That is, + * + * ``` + * logger.WithGroup("s").LogAttrs(ctx, level, msg, slog.Int("a", 1), slog.Int("b", 2)) + * ``` + * + * should behave like + * + * ``` + * logger.LogAttrs(ctx, level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2))) + * ``` + * + * If the name is empty, WithGroup returns the receiver. + */ + withGroup(name: string): Handler + } + /** + * A Level is the importance or severity of a log event. + * The higher the level, the more important or severe the event. + */ + interface Level extends Number{} + interface Level { + /** + * String returns a name for the level. + * If the level has a name, then that name + * in uppercase is returned. + * If the level is between named values, then + * an integer is appended to the uppercased name. + * Examples: + * + * ``` + * LevelWarn.String() => "WARN" + * (LevelInfo+2).String() => "INFO+2" + * ``` + */ + string(): string + } + interface Level { + /** + * MarshalJSON implements [encoding/json.Marshaler] + * by quoting the output of [Level.String]. + */ + marshalJSON(): string|Array + } + interface Level { + /** + * UnmarshalJSON implements [encoding/json.Unmarshaler] + * It accepts any string produced by [Level.MarshalJSON], + * ignoring case. + * It also accepts numeric offsets that would result in a different string on + * output. For example, "Error-8" would marshal as "INFO". + */ + unmarshalJSON(data: string|Array): void + } + interface Level { + /** + * AppendText implements [encoding.TextAppender] + * by calling [Level.String]. + */ + appendText(b: string|Array): string|Array + } + interface Level { + /** + * MarshalText implements [encoding.TextMarshaler] + * by calling [Level.AppendText]. + */ + marshalText(): string|Array + } + interface Level { + /** + * UnmarshalText implements [encoding.TextUnmarshaler]. + * It accepts any string produced by [Level.MarshalText], + * ignoring case. + * It also accepts numeric offsets that would result in a different string on + * output. For example, "Error-8" would marshal as "INFO". + */ + unmarshalText(data: string|Array): void + } + interface Level { + /** + * Level returns the receiver. + * It implements [Leveler]. + */ + level(): Level + } + // @ts-ignore + import loginternal = internal +} + +namespace slog { + // @ts-ignore + import loginternal = internal + /** + * A Record holds information about a log event. + * Copies of a Record share state. + * Do not modify a Record after handing out a copy to it. + * Call [NewRecord] to create a new Record. + * Use [Record.Clone] to create a copy with no shared state. + */ + interface Record { + /** + * The time at which the output method (Log, Info, etc.) was called. + */ + time: time.Time + /** + * The log message. + */ + message: string + /** + * The level of the event. + */ + level: Level + /** + * The program counter at the time the record was constructed, as determined + * by runtime.Callers. If zero, no program counter is available. + * + * The only valid use for this value is as an argument to + * [runtime.CallersFrames]. In particular, it must not be passed to + * [runtime.FuncForPC]. + */ + pc: number + } + interface Record { + /** + * Clone returns a copy of the record with no shared state. + * The original record and the clone can both be modified + * without interfering with each other. + */ + clone(): Record + } + interface Record { + /** + * NumAttrs returns the number of attributes in the [Record]. + */ + numAttrs(): number + } + interface Record { + /** + * Attrs calls f on each Attr in the [Record]. + * Iteration stops if f returns false. + */ + attrs(f: (_arg0: Attr) => boolean): void + } + interface Record { + /** + * AddAttrs appends the given Attrs to the [Record]'s list of Attrs. + * It omits empty groups. + */ + addAttrs(...attrs: Attr[]): void + } + interface Record { + /** + * Add converts the args to Attrs as described in [Logger.Log], + * then appends the Attrs to the [Record]'s list of Attrs. + * It omits empty groups. + */ + add(...args: any[]): void + } + /** + * A Value can represent any Go value, but unlike type any, + * it can represent most small values without an allocation. + * The zero Value corresponds to nil. + */ + interface Value { + } + interface Value { + /** + * Kind returns v's Kind. + */ + kind(): Kind + } + interface Value { + /** + * Any returns v's value as an any. + */ + any(): any + } + interface Value { + /** + * String returns Value's value as a string, formatted like [fmt.Sprint]. Unlike + * the methods Int64, Float64, and so on, which panic if v is of the + * wrong kind, String never panics. + */ + string(): string + } + interface Value { + /** + * Int64 returns v's value as an int64. It panics + * if v is not a signed integer. + */ + int64(): number + } + interface Value { + /** + * Uint64 returns v's value as a uint64. It panics + * if v is not an unsigned integer. + */ + uint64(): number + } + interface Value { + /** + * Bool returns v's value as a bool. It panics + * if v is not a bool. + */ + bool(): boolean + } + interface Value { + /** + * Duration returns v's value as a [time.Duration]. It panics + * if v is not a time.Duration. + */ + duration(): time.Duration + } + interface Value { + /** + * Float64 returns v's value as a float64. It panics + * if v is not a float64. + */ + float64(): number + } + interface Value { + /** + * Time returns v's value as a [time.Time]. It panics + * if v is not a time.Time. + */ + time(): time.Time + } + interface Value { + /** + * LogValuer returns v's value as a LogValuer. It panics + * if v is not a LogValuer. + */ + logValuer(): LogValuer + } + interface Value { + /** + * Group returns v's value as a []Attr. + * It panics if v's [Kind] is not [KindGroup]. + */ + group(): Array + } + interface Value { + /** + * Equal reports whether v and w represent the same Go value. + */ + equal(w: Value): boolean + } + interface Value { + /** + * Resolve repeatedly calls LogValue on v while it implements [LogValuer], + * and returns the result. + * If v resolves to a group, the group's attributes' values are not recursively + * resolved. + * If the number of LogValue calls exceeds a threshold, a Value containing an + * error is returned. + * Resolve's return value is guaranteed not to be of Kind [KindLogValuer]. + */ + resolve(): Value + } +} + +namespace multipart { + /** + * A Part represents a single part in a multipart body. + */ + interface Part { + /** + * The headers of the body, if any, with the keys canonicalized + * in the same fashion that the Go http.Request headers are. + * For example, "foo-bar" changes case to "Foo-Bar" + */ + header: textproto.MIMEHeader + } + interface Part { + /** + * FormName returns the name parameter if p has a Content-Disposition + * of type "form-data". Otherwise it returns the empty string. + */ + formName(): string + } + interface Part { + /** + * FileName returns the filename parameter of the [Part]'s Content-Disposition + * header. If not empty, the filename is passed through filepath.Base (which is + * platform dependent) before being returned. + */ + fileName(): string + } + interface Part { + /** + * Read reads the body of a part, after its headers and before the + * next part (if any) begins. + */ + read(d: string|Array): number + } + interface Part { + close(): void + } +} + +namespace url { + /** + * The Userinfo type is an immutable encapsulation of username and + * password details for a [URL]. An existing Userinfo value is guaranteed + * to have a username set (potentially empty, as allowed by RFC 2396), + * and optionally a password. + */ + interface Userinfo { + } + interface Userinfo { + /** + * Username returns the username. + */ + username(): string + } + interface Userinfo { + /** + * Password returns the password in case it is set, and whether it is set. + */ + password(): [string, boolean] + } + interface Userinfo { + /** + * String returns the encoded userinfo information in the standard form + * of "username[:password]". + */ + string(): string + } +} + +namespace http { + /** + * SameSite allows a server to define a cookie attribute making it impossible for + * the browser to send this cookie along with cross-site requests. The main + * goal is to mitigate the risk of cross-origin information leakage, and provide + * some protection against cross-site request forgery attacks. + * + * See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details. + */ + interface SameSite extends Number{} + // @ts-ignore + import mathrand = rand + // @ts-ignore + import urlpkg = url +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation + interface Route { + action: (e: T) => void + method: string + path: string + middlewares: Array<(hook.Handler | undefined)> + } + interface Route { + /** + * BindFunc registers one or multiple middleware functions to the current route. + * + * The registered middleware functions are "anonymous" and with default priority, + * aka. executes in the order they were registered. + * + * If you need to specify a named middleware (ex. so that it can be removed) + * or middleware with custom exec prirority, use the [Route.Bind] method. + */ + bindFunc(...middlewareFuncs: ((e: T) => void)[]): (Route) + } + interface Route { + /** + * Bind registers one or multiple middleware handlers to the current route. + */ + bind(...middlewares: (hook.Handler | undefined)[]): (Route) + } + interface Route { + /** + * Unbind removes one or more middlewares with the specified id(s) from the current route. + * + * It also adds the removed middleware ids to an exclude list so that they could be skipped from + * the execution chain in case the middleware is registered in a parent group. + * + * Anonymous middlewares are considered non-removable, aka. this method + * does nothing if the middleware id is an empty string. + */ + unbind(...middlewareIds: string[]): (Route) + } +} + +namespace cobra { + // @ts-ignore + import flag = pflag + /** + * ShellCompDirective is a bit map representing the different behaviors the shell + * can be instructed to have once completions have been provided. + */ + interface ShellCompDirective extends Number{} +} + +namespace oauth2 { +} + +namespace slog { + // @ts-ignore + import loginternal = internal + /** + * Kind is the kind of a [Value]. + */ + interface Kind extends Number{} + interface Kind { + string(): string + } + /** + * A LogValuer is any Go value that can convert itself into a Value for logging. + * + * This mechanism may be used to defer expensive operations until they are + * needed, or to expand a single value into a sequence of components. + */ + interface LogValuer { + [key:string]: any; + logValue(): Value + } +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation +} diff --git a/pb_migrations/1760628828_created_file.js b/pb_migrations/1760628828_created_file.js new file mode 100644 index 0000000..018aa3b --- /dev/null +++ b/pb_migrations/1760628828_created_file.js @@ -0,0 +1,77 @@ +/// +migrate((app) => { + const collection = new Collection({ + "createRule": null, + "deleteRule": null, + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "hidden": false, + "id": "file3309110367", + "maxSelect": 99, + "maxSize": 0, + "mimeTypes": [ + "image/jpeg", + "image/png", + "image/svg+xml", + "image/gif", + "image/webp" + ], + "name": "image", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "id": "pbc_2878493088", + "indexes": [], + "listRule": null, + "name": "file", + "system": false, + "type": "base", + "updateRule": null, + "viewRule": null + }); + + return app.save(collection); +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088"); + + return app.delete(collection); +}) diff --git a/pb_migrations/1760628854_updated_file.js b/pb_migrations/1760628854_updated_file.js new file mode 100644 index 0000000..0835c5e --- /dev/null +++ b/pb_migrations/1760628854_updated_file.js @@ -0,0 +1,35 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // add field + collection.fields.addAt(2, new Field({ + "hidden": false, + "id": "file2359244304", + "maxSelect": 99, + "maxSize": 0, + "mimeTypes": [ + "application/pdf", + "application/msword", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + ], + "name": "file", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // remove field + collection.fields.removeById("file2359244304") + + return app.save(collection) +}) diff --git a/pb_migrations/1760628872_updated_file.js b/pb_migrations/1760628872_updated_file.js new file mode 100644 index 0000000..446d552 --- /dev/null +++ b/pb_migrations/1760628872_updated_file.js @@ -0,0 +1,34 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // add field + collection.fields.addAt(3, new Field({ + "hidden": false, + "id": "file2093472300", + "maxSelect": 99, + "maxSize": 0, + "mimeTypes": [ + "video/mp4", + "video/x-ms-wmv", + "video/quicktime", + "video/3gpp" + ], + "name": "video", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // remove field + collection.fields.removeById("file2093472300") + + return app.save(collection) +}) diff --git a/pb_migrations/1760628913_updated_file.js b/pb_migrations/1760628913_updated_file.js new file mode 100644 index 0000000..3b6a792 --- /dev/null +++ b/pb_migrations/1760628913_updated_file.js @@ -0,0 +1,26 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // update collection data + unmarshal({ + "createRule": "", + "listRule": "", + "updateRule": "", + "viewRule": "" + }, collection) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_2878493088") + + // update collection data + unmarshal({ + "createRule": null, + "listRule": null, + "updateRule": null, + "viewRule": null + }, collection) + + return app.save(collection) +}) diff --git a/pb_migrations/1760628950_created_city.js b/pb_migrations/1760628950_created_city.js new file mode 100644 index 0000000..5a52c1e --- /dev/null +++ b/pb_migrations/1760628950_created_city.js @@ -0,0 +1,71 @@ +/// +migrate((app) => { + const collection = new Collection({ + "createRule": null, + "deleteRule": null, + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text2655826506", + "max": 0, + "min": 0, + "name": "cityName", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "id": "pbc_173434244", + "indexes": [], + "listRule": null, + "name": "city", + "system": false, + "type": "base", + "updateRule": null, + "viewRule": null + }); + + return app.save(collection); +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244"); + + return app.delete(collection); +}) diff --git a/pb_migrations/1760629025_updated_users.js b/pb_migrations/1760629025_updated_users.js new file mode 100644 index 0000000..e2d4d53 --- /dev/null +++ b/pb_migrations/1760629025_updated_users.js @@ -0,0 +1,29 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("_pb_users_auth_") + + // add field + collection.fields.addAt(8, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text31680599", + "max": 0, + "min": 0, + "name": "openid", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("_pb_users_auth_") + + // remove field + collection.fields.removeById("text31680599") + + return app.save(collection) +}) diff --git a/pb_migrations/1760629178_updated_city.js b/pb_migrations/1760629178_updated_city.js new file mode 100644 index 0000000..7d2a19c --- /dev/null +++ b/pb_migrations/1760629178_updated_city.js @@ -0,0 +1,29 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // add field + collection.fields.addAt(2, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text3078290644", + "max": 0, + "min": 0, + "name": "cityCode", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // remove field + collection.fields.removeById("text3078290644") + + return app.save(collection) +}) diff --git a/pb_migrations/1760629200_updated_city.js b/pb_migrations/1760629200_updated_city.js new file mode 100644 index 0000000..0f1eb9d --- /dev/null +++ b/pb_migrations/1760629200_updated_city.js @@ -0,0 +1,24 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // add field + collection.fields.addAt(3, new Field({ + "hidden": false, + "id": "geoPoint1542800728", + "name": "field", + "presentable": false, + "required": false, + "system": false, + "type": "geoPoint" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // remove field + collection.fields.removeById("geoPoint1542800728") + + return app.save(collection) +}) diff --git a/pb_migrations/1760629212_updated_city.js b/pb_migrations/1760629212_updated_city.js new file mode 100644 index 0000000..b393aba --- /dev/null +++ b/pb_migrations/1760629212_updated_city.js @@ -0,0 +1,32 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // update field + collection.fields.addAt(3, new Field({ + "hidden": false, + "id": "geoPoint1542800728", + "name": "geo", + "presentable": false, + "required": false, + "system": false, + "type": "geoPoint" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // update field + collection.fields.addAt(3, new Field({ + "hidden": false, + "id": "geoPoint1542800728", + "name": "field", + "presentable": false, + "required": false, + "system": false, + "type": "geoPoint" + })) + + return app.save(collection) +}) diff --git a/pb_migrations/1760629707_updated_city.js b/pb_migrations/1760629707_updated_city.js new file mode 100644 index 0000000..004bbeb --- /dev/null +++ b/pb_migrations/1760629707_updated_city.js @@ -0,0 +1,29 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // add field + collection.fields.addAt(4, new Field({ + "hidden": false, + "id": "file3760176746", + "maxSelect": 99, + "maxSize": 0, + "mimeTypes": [], + "name": "images", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_173434244") + + // remove field + collection.fields.removeById("file3760176746") + + return app.save(collection) +}) diff --git a/pocketbase b/pocketbase old mode 100644 new mode 100755