@x47base/pocketbase-addon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.dockerignore +9 -0
  2. package/Dockerfile +26 -0
  3. package/FEATURES.md +32 -0
  4. package/LICENSE.md +17 -0
  5. package/MIGRATION.md +49 -0
  6. package/NOTICE.md +5 -0
  7. package/README.md +26 -0
  8. package/adapter.go +31 -0
  9. package/admin/register.go +60 -0
  10. package/admin/register_test.go +37 -0
  11. package/backups/backup_encryption_test.go +82 -0
  12. package/backups/encryption.go +138 -0
  13. package/backups/integration_test.go +51 -0
  14. package/backups/register.go +120 -0
  15. package/backups/restore.go +119 -0
  16. package/backups/s3_test.go +52 -0
  17. package/backups/swap.go +53 -0
  18. package/backups/swap_test.go +75 -0
  19. package/backups/upload.go +52 -0
  20. package/bin/pocketbase-extension.mjs +25 -0
  21. package/cmd/edge/main.go +123 -0
  22. package/cmd/import-fork/main.go +37 -0
  23. package/cmd/loadtest/main.go +61 -0
  24. package/cmd/loadtest/sandbox.go +73 -0
  25. package/cmd/loadtest/sandbox_test.go +20 -0
  26. package/cmd/pocketbase/main.go +78 -0
  27. package/deploy/README.md +148 -0
  28. package/deploy/app/hooks/README.md +2 -0
  29. package/deploy/app/migrations/1789000000_notes.js +16 -0
  30. package/deploy/app/public/README.md +2 -0
  31. package/deploy/compose.secrets.yaml +8 -0
  32. package/deploy/compose.yaml +68 -0
  33. package/deploy/edge.json +13 -0
  34. package/edge/gateway.go +295 -0
  35. package/edge/gateway_test.go +296 -0
  36. package/edge/openapi.json +1 -0
  37. package/edge/policy.go +150 -0
  38. package/features/collection_singleton.go +13 -0
  39. package/features/collection_singleton_test.go +46 -0
  40. package/features/dimensions_test.go +65 -0
  41. package/features/duplicate.go +178 -0
  42. package/features/duplicate_test.go +128 -0
  43. package/features/field_color.go +46 -0
  44. package/features/field_date_only.go +39 -0
  45. package/features/field_json_schema.go +92 -0
  46. package/features/field_scalar_extensions_test.go +66 -0
  47. package/features/files.go +36 -0
  48. package/features/filter_has_any_test.go +81 -0
  49. package/features/generate_test.go +72 -0
  50. package/features/has_any_visibility_test.go +62 -0
  51. package/features/json.go +50 -0
  52. package/features/membership.go +64 -0
  53. package/features/register.go +45 -0
  54. package/features/schema_test.go +58 -0
  55. package/features/ui/main.js +133 -0
  56. package/features/ui/settings.js +31 -0
  57. package/go.mod +54 -0
  58. package/go.sum +159 -0
  59. package/internal/archive/create.go +91 -0
  60. package/internal/archive/create_test.go +125 -0
  61. package/internal/archive/extract.go +99 -0
  62. package/internal/archive/extract_test.go +88 -0
  63. package/jsvm/binds.go +1273 -0
  64. package/jsvm/binds_app_reset_test.go +314 -0
  65. package/jsvm/binds_test.go +1870 -0
  66. package/jsvm/form_data.go +149 -0
  67. package/jsvm/form_data_test.go +225 -0
  68. package/jsvm/internal/types/generated/embed.go +6 -0
  69. package/jsvm/internal/types/generated/types.d.ts +24820 -0
  70. package/jsvm/internal/types/types.go +1408 -0
  71. package/jsvm/jsvm.go +587 -0
  72. package/jsvm/mapper.go +67 -0
  73. package/jsvm/mapper_test.go +42 -0
  74. package/jsvm/pool.go +73 -0
  75. package/jsvm/program_source_test.go +24 -0
  76. package/loadtest/loadtest.go +202 -0
  77. package/loadtest/loadtest_test.go +84 -0
  78. package/localization/README.md +23 -0
  79. package/localization/catalogue.json +483 -0
  80. package/localization/localization.go +94 -0
  81. package/localization/localization_test.go +21 -0
  82. package/mail/register.go +80 -0
  83. package/mail/register_test.go +49 -0
  84. package/mail/resolve.go +91 -0
  85. package/migration/import.go +96 -0
  86. package/migration/import_test.go +58 -0
  87. package/otp/otp.go +56 -0
  88. package/otp/otp_test.go +56 -0
  89. package/package.json +51 -0
  90. package/scripts/check-edge.py +42 -0
  91. package/scripts/check.sh +11 -0
  92. package/scripts/sync-jsvm-types.sh +10 -0
  93. package/security/README.md +94 -0
  94. package/security/assurance_test.go +149 -0
  95. package/security/compatibility_test.go +128 -0
  96. package/security/config.go +78 -0
  97. package/security/dashboard_test.go +103 -0
  98. package/security/management.go +169 -0
  99. package/security/openapi.json +508 -0
  100. package/security/review.go +34 -0
  101. package/security/security.go +503 -0
  102. package/security/security_test.go +146 -0
  103. package/security/state.go +116 -0
  104. package/security/ui/dashboard.css +4 -0
  105. package/security/ui/dashboard.js +83 -0
  106. package/security/ui/main.js +15 -0
  107. package/security/ui/model.js +32 -0
  108. package/security/ui/model.test.mjs +25 -0
  109. package/security/ui/registration.test.mjs +10 -0
  110. package/settings/env_test.go +41 -0
  111. package/settings/openapi.json +193 -0
  112. package/settings/settings.go +155 -0
  113. package/settings/settings_test.go +31 -0
  114. package/watcher/watcher.go +192 -0
  115. package/watcher/watcher_test.go +200 -0
  116. package/web/static.go +99 -0
  117. package/web/static_test.go +48 -0
@@ -0,0 +1,1408 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "log"
6
+ "os"
7
+ "path/filepath"
8
+ "reflect"
9
+ "runtime"
10
+ "strings"
11
+ "time"
12
+
13
+ "github.com/pocketbase/pocketbase/core"
14
+ "github.com/spink-dev/pocketbase-extension/jsvm"
15
+ "github.com/pocketbase/pocketbase/tools/list"
16
+ "github.com/pocketbase/tygoja"
17
+ )
18
+
19
+ const heading = `
20
+ // -------------------------------------------------------------------
21
+ // cronBinds
22
+ // -------------------------------------------------------------------
23
+
24
+ /**
25
+ * CronAdd registers a new cron job.
26
+ *
27
+ * If a cron job with the specified name already exist, it will be
28
+ * replaced with the new one.
29
+ *
30
+ * Example:
31
+ *
32
+ * ` + "```" + `js
33
+ * // prints "Hello world!" on every 30 minutes
34
+ * cronAdd("hello", "*\/30 * * * *", () => {
35
+ * console.log("Hello world!")
36
+ * })
37
+ * ` + "```" + `
38
+ *
39
+ * _Note that this method is available only in pb_hooks context._
40
+ *
41
+ * @group PocketBase
42
+ */
43
+ declare function cronAdd(
44
+ jobId: string,
45
+ cronExpr: string,
46
+ handler: () => void,
47
+ ): void;
48
+
49
+ /**
50
+ * CronRemove removes a single registered cron job by its name.
51
+ *
52
+ * Example:
53
+ *
54
+ * ` + "```" + `js
55
+ * cronRemove("hello")
56
+ * ` + "```" + `
57
+ *
58
+ * _Note that this method is available only in pb_hooks context._
59
+ *
60
+ * @group PocketBase
61
+ */
62
+ declare function cronRemove(jobId: string): void;
63
+
64
+ // -------------------------------------------------------------------
65
+ // routerBinds
66
+ // -------------------------------------------------------------------
67
+
68
+ /**
69
+ * RouterAdd registers a new route definition.
70
+ *
71
+ * Example:
72
+ *
73
+ * ` + "```" + `js
74
+ * routerAdd("GET", "/hello", (e) => {
75
+ * return e.json(200, {"message": "Hello!"})
76
+ * }, $apis.requireAuth())
77
+ * ` + "```" + `
78
+ *
79
+ * _Note that this method is available only in pb_hooks context._
80
+ *
81
+ * @group PocketBase
82
+ */
83
+ declare function routerAdd(
84
+ method: string,
85
+ path: string,
86
+ handler: (e: core.RequestEvent) => void,
87
+ ...middlewares: Array<string|((e: core.RequestEvent) => void)|Middleware>,
88
+ ): void;
89
+
90
+ /**
91
+ * RouterUse registers one or more global middlewares that are executed
92
+ * along the handler middlewares after a matching route is found.
93
+ *
94
+ * Example:
95
+ *
96
+ * ` + "```" + `js
97
+ * routerUse((e) => {
98
+ * console.log(e.request.url.path)
99
+ * return e.next()
100
+ * })
101
+ * ` + "```" + `
102
+ *
103
+ * _Note that this method is available only in pb_hooks context._
104
+ *
105
+ * @group PocketBase
106
+ */
107
+ declare function routerUse(...middlewares: Array<string|((e: core.RequestEvent) => void)|Middleware>): void;
108
+
109
+ // -------------------------------------------------------------------
110
+ // baseBinds
111
+ // -------------------------------------------------------------------
112
+
113
+ /**
114
+ * Global helper variable that contains the absolute path to the app pb_hooks directory.
115
+ *
116
+ * @group PocketBase
117
+ */
118
+ declare var __hooks: string
119
+
120
+ // Utility type to exclude the on* hook methods from a type
121
+ // (hooks are separately generated as global methods).
122
+ //
123
+ // See https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as
124
+ type excludeHooks<Type> = {
125
+ [Property in keyof Type as Exclude<Property, ` + "`on${string}`" + `|'cron'>]: Type[Property]
126
+ };
127
+
128
+ // core.App without the on* hook methods
129
+ type CoreApp = excludeHooks<ORIGINAL_CORE_APP>
130
+
131
+ // pocketbase.PocketBase without the on* hook methods
132
+ interface PocketBase extends excludeHooks<ORIGINAL_POCKETBASE>{}
133
+
134
+ /**
135
+ * ` + "`$app`" + ` is the current running PocketBase instance that is globally
136
+ * available in each .pb.js file.
137
+ *
138
+ * _Note that this variable is available only in pb_hooks context._
139
+ *
140
+ * @namespace
141
+ * @group PocketBase
142
+ */
143
+ declare var $app: PocketBase
144
+
145
+ /**
146
+ * ` + "`$template`" + ` is a global helper to load and cache HTML templates on the fly.
147
+ *
148
+ * The templates uses the standard Go [html/template](https://pkg.go.dev/html/template)
149
+ * and [text/template](https://pkg.go.dev/text/template) package syntax.
150
+ *
151
+ * Example:
152
+ *
153
+ * ` + "```" + `js
154
+ * const html = $template.loadFiles(
155
+ * "views/layout.html",
156
+ * "views/content.html",
157
+ * ).render({"name": "John"})
158
+ * ` + "```" + `
159
+ *
160
+ * @namespace
161
+ * @group PocketBase
162
+ */
163
+ declare var $template: template.Registry
164
+
165
+ /**
166
+ * This method is superseded by toString.
167
+ *
168
+ * @deprecated
169
+ * @group PocketBase
170
+ */
171
+ declare function readerToString(reader: any, maxBytes?: number): string;
172
+
173
+ /**
174
+ * toString stringifies the specified value.
175
+ *
176
+ * Support optional second maxBytes argument to limit the max read bytes
177
+ * when the value is a io.Reader (default to 32MB).
178
+ *
179
+ * Types that don't have explicit string representation are json serialized.
180
+ *
181
+ * Example:
182
+ *
183
+ * ` + "```" + `js
184
+ * // io.Reader
185
+ * const ex1 = toString(e.request.body)
186
+ *
187
+ * // slice of bytes
188
+ * const ex2 = toString([104 101 108 108 111]) // "hello"
189
+ *
190
+ * // null
191
+ * const ex3 = toString(null) // ""
192
+ * ` + "```" + `
193
+ *
194
+ * @group PocketBase
195
+ */
196
+ declare function toString(val: any, maxBytes?: number): string;
197
+
198
+ /**
199
+ * toBytes converts the specified value into a bytes slice.
200
+ *
201
+ * Support optional second maxBytes argument to limit the max read bytes
202
+ * when the value is a io.Reader (default to 32MB).
203
+ *
204
+ * Types that don't have Go slice representation (bool, objects, etc.)
205
+ * are serialized to UTF8 string and its bytes slice is returned.
206
+ *
207
+ * Example:
208
+ *
209
+ * ` + "```" + `js
210
+ * // io.Reader
211
+ * const ex1 = toBytes(e.request.body)
212
+ *
213
+ * // string
214
+ * const ex2 = toBytes("hello") // [104 101 108 108 111]
215
+ *
216
+ * // object (the same as the string '{"test":1}')
217
+ * const ex3 = toBytes({"test":1}) // [123 34 116 101 115 116 34 58 49 125]
218
+ *
219
+ * // null
220
+ * const ex4 = toBytes(null) // []
221
+ * ` + "```" + `
222
+ *
223
+ * @group PocketBase
224
+ */
225
+ declare function toBytes(val: any, maxBytes?: number): Array<number>;
226
+
227
+ /**
228
+ * sleep pauses the current goroutine for at least the specified user duration (in ms).
229
+ * A zero or negative duration returns immediately.
230
+ *
231
+ * Example:
232
+ *
233
+ * ` + "```" + `js
234
+ * sleep(250) // sleeps for 250ms
235
+ * ` + "```" + `
236
+ *
237
+ * @group PocketBase
238
+ */
239
+ declare function sleep(milliseconds: number): void;
240
+
241
+ /**
242
+ * arrayOf creates a placeholder array of the specified models.
243
+ * Usually used to populate DB result into an array of models.
244
+ *
245
+ * Example:
246
+ *
247
+ * ` + "```" + `js
248
+ * const records = arrayOf(new Record)
249
+ *
250
+ * $app.recordQuery("articles").limit(10).all(records)
251
+ * ` + "```" + `
252
+ *
253
+ * @group PocketBase
254
+ */
255
+ declare function arrayOf<T>(model: T): Array<T>;
256
+
257
+ /**
258
+ * unmarshal clones and merges the data argument on top of dst.
259
+ *
260
+ * This method is rarely used directly by the users and it is most
261
+ * commonly used in the autogenerated migrations.
262
+ *
263
+ * To an extent it is similar to the JS native ` + "`" + `Object.assign` + "`" + `
264
+ * but the arguments are reversed and it invokes the Go standard
265
+ * ` + "`" + `json.Marshal/Unmarshal` + "`" + ` methods under the hood.
266
+ *
267
+ * The data argument could be anything serializable, usually a plain object (map).
268
+ * The dst argument could be any pointer value, usually a model instance.
269
+ *
270
+ * Example:
271
+ *
272
+ * ` + "```" + `js
273
+ * unmarshal({ authAlert: { enabled: true } }, collection)
274
+ * ` + "```" + `
275
+ *
276
+ * @group PocketBase
277
+ */
278
+ declare function unmarshal(data: any, dst: any): void;
279
+
280
+ /**
281
+ * DynamicModel creates a new dynamic model with fields from the provided data shape.
282
+ *
283
+ * Caveats:
284
+ * - In order to use 0 as double/float initialization number you have to negate it (` + "`-0`" + `).
285
+ * - You need to use lowerCamelCase when accessing the model fields (e.g. ` + "`model.roles`" + ` and not ` + "`model.Roles`" + ` even if in the model shape and in the DB table the column is capitalized).
286
+ * - Objects are loaded into types.JSONMap, meaning that they need to be accessed with ` + "`get(key)`" + ` (e.g. ` + "`model.meta.get('something')`" + `).
287
+ * - For describing nullable types you can use the ` + "`null*()`" + ` helpers - ` + "`nullString()`" + `, ` + "`nullInt()`" + `, ` + "`nullFloat()`" + `, ` + "`nullBool()`" + `, ` + "`nullArray()`" + `, ` + "`nullObject()`" + `.
288
+ *
289
+ * Example:
290
+ *
291
+ * ` + "```" + `js
292
+ * const model = new DynamicModel({
293
+ * name: "" // or nullString() if nullable
294
+ * age: 0, // or nullInt() if nullable
295
+ * totalSpent: -0, // or nullFloat() if nullable
296
+ * active: false, // or nullBool() if nullable
297
+ * Roles: [], // or nullArray() if nullable; maps to "Roles" in the DB/JSON but the prop would be accessible via "model.roles"
298
+ * meta: {}, // or nullObject() if nullable
299
+ * })
300
+ * ` + "```" + `
301
+ *
302
+ * @group PocketBase
303
+ */
304
+ declare class DynamicModel {
305
+ [key: string]: any;
306
+ constructor(shape?: { [key:string]: any })
307
+ }
308
+
309
+ /**
310
+ * nullString creates an empty Go string pointer usually used for
311
+ * describing a **nullable** ` + "`DynamicModel`" + ` string value.
312
+ *
313
+ * @group PocketBase
314
+ */
315
+ declare function nullString(): string;
316
+
317
+ /**
318
+ * nullInt creates an empty Go int64 pointer usually used for
319
+ * describing a **nullable** ` + "`DynamicModel`" + ` int value.
320
+ *
321
+ * @group PocketBase
322
+ */
323
+ declare function nullInt(): number;
324
+
325
+ /**
326
+ * nullFloat creates an empty Go float64 pointer usually used for
327
+ * describing a **nullable** ` + "`DynamicModel`" + ` float value.
328
+ *
329
+ * @group PocketBase
330
+ */
331
+ declare function nullFloat(): number;
332
+
333
+ /**
334
+ * nullBool creates an empty Go bool pointer usually used for
335
+ * describing a **nullable** ` + "`DynamicModel`" + ` bool value.
336
+ *
337
+ * @group PocketBase
338
+ */
339
+ declare function nullBool(): boolean;
340
+
341
+ /**
342
+ * nullArray creates an empty Go types.JSONArray pointer usually used for
343
+ * describing a **nullable** ` + "`DynamicModel`" + ` JSON array value.
344
+ *
345
+ * @group PocketBase
346
+ */
347
+ declare function nullArray(): Array<any>;
348
+
349
+ /**
350
+ * nullObject creates an empty Go types.JSONMap pointer usually used for
351
+ * describing a **nullable** ` + "`DynamicModel`" + ` JSON object value.
352
+ *
353
+ * @group PocketBase
354
+ */
355
+ declare function nullObject(): { get(key:string):any; set(key:string,value:any):void };
356
+
357
+ interface Context extends context.Context{} // merge
358
+ /**
359
+ * Context creates a new empty Go context.Context.
360
+ *
361
+ * This is usually used as part of some Go transitive bindings.
362
+ *
363
+ * Example:
364
+ *
365
+ * ` + "```" + `js
366
+ * const blank = new Context()
367
+ *
368
+ * // with single key-value pair
369
+ * const base = new Context(null, "a", 123)
370
+ * console.log(base.value("a")) // 123
371
+ *
372
+ * // extend with additional key-value pair
373
+ * const sub = new Context(base, "b", 456)
374
+ * console.log(sub.value("a")) // 123
375
+ * console.log(sub.value("b")) // 456
376
+ * ` + "```" + `
377
+ *
378
+ * @group PocketBase
379
+ */
380
+ declare class Context implements context.Context {
381
+ constructor(parentCtx?: Context, key?: any, value?: any)
382
+ }
383
+
384
+ /**
385
+ * Record model class.
386
+ *
387
+ * ` + "```" + `js
388
+ * const collection = $app.findCollectionByNameOrId("article")
389
+ *
390
+ * const record = new Record(collection, {
391
+ * title: "Lorem ipsum"
392
+ * })
393
+ *
394
+ * // or set field values after the initialization
395
+ * record.set("description", "...")
396
+ * ` + "```" + `
397
+ *
398
+ * @group PocketBase
399
+ */
400
+ declare const Record: {
401
+ new(collection?: core.Collection, data?: { [key:string]: any }): core.Record
402
+
403
+ // note: declare as "newable" const due to conflict with the Record TS utility type
404
+ }
405
+
406
+ interface Collection extends core.Collection{
407
+ type: "base" | "view" | "auth"
408
+ } // merge
409
+ /**
410
+ * Collection model class.
411
+ *
412
+ * ` + "```" + `js
413
+ * const collection = new Collection({
414
+ * type: "base",
415
+ * name: "article",
416
+ * listRule: "@request.auth.id != '' || status = 'public'",
417
+ * viewRule: "@request.auth.id != '' || status = 'public'",
418
+ * deleteRule: "@request.auth.id != ''",
419
+ * fields: [
420
+ * {
421
+ * name: "title",
422
+ * type: "text",
423
+ * required: true,
424
+ * min: 6,
425
+ * max: 100,
426
+ * },
427
+ * {
428
+ * name: "description",
429
+ * type: "text",
430
+ * },
431
+ * ]
432
+ * })
433
+ * ` + "```" + `
434
+ *
435
+ * @group PocketBase
436
+ */
437
+ declare class Collection implements core.Collection {
438
+ constructor(data?: Partial<Collection>)
439
+ }
440
+
441
+ interface FieldsList extends core.FieldsList{} // merge
442
+ /**
443
+ * FieldsList model class, usually used to define the Collection.fields.
444
+ *
445
+ * @group PocketBase
446
+ */
447
+ declare class FieldsList implements core.FieldsList {
448
+ constructor(data?: Partial<core.FieldsList>)
449
+ }
450
+
451
+ interface Field extends core.Field{} // merge
452
+ /**
453
+ * Field model class, usually used as part of the FieldsList model.
454
+ *
455
+ * @group PocketBase
456
+ */
457
+ declare class Field implements core.Field {
458
+ constructor(data?: Partial<core.Field>)
459
+ }
460
+
461
+ interface NumberField extends core.NumberField{} // merge
462
+ /**
463
+ * {@inheritDoc core.NumberField}
464
+ *
465
+ * @group PocketBase
466
+ */
467
+ declare class NumberField implements core.NumberField {
468
+ constructor(data?: Partial<core.NumberField>)
469
+ }
470
+
471
+ interface BoolField extends core.BoolField{} // merge
472
+ /**
473
+ * {@inheritDoc core.BoolField}
474
+ *
475
+ * @group PocketBase
476
+ */
477
+ declare class BoolField implements core.BoolField {
478
+ constructor(data?: Partial<core.BoolField>)
479
+ }
480
+
481
+ interface TextField extends core.TextField{} // merge
482
+ /**
483
+ * {@inheritDoc core.TextField}
484
+ *
485
+ * @group PocketBase
486
+ */
487
+ declare class TextField implements core.TextField {
488
+ constructor(data?: Partial<core.TextField>)
489
+ }
490
+
491
+ interface URLField extends core.URLField{} // merge
492
+ /**
493
+ * {@inheritDoc core.URLField}
494
+ *
495
+ * @group PocketBase
496
+ */
497
+ declare class URLField implements core.URLField {
498
+ constructor(data?: Partial<core.URLField>)
499
+ }
500
+
501
+ interface EmailField extends core.EmailField{} // merge
502
+ /**
503
+ * {@inheritDoc core.EmailField}
504
+ *
505
+ * @group PocketBase
506
+ */
507
+ declare class EmailField implements core.EmailField {
508
+ constructor(data?: Partial<core.EmailField>)
509
+ }
510
+
511
+ interface EditorField extends core.EditorField{} // merge
512
+ /**
513
+ * {@inheritDoc core.EditorField}
514
+ *
515
+ * @group PocketBase
516
+ */
517
+ declare class EditorField implements core.EditorField {
518
+ constructor(data?: Partial<core.EditorField>)
519
+ }
520
+
521
+ interface PasswordField extends core.PasswordField{} // merge
522
+ /**
523
+ * {@inheritDoc core.PasswordField}
524
+ *
525
+ * @group PocketBase
526
+ */
527
+ declare class PasswordField implements core.PasswordField {
528
+ constructor(data?: Partial<core.PasswordField>)
529
+ }
530
+
531
+ interface DateField extends core.DateField{} // merge
532
+ /**
533
+ * {@inheritDoc core.DateField}
534
+ *
535
+ * @group PocketBase
536
+ */
537
+ declare class DateField implements core.DateField {
538
+ constructor(data?: Partial<core.DateField>)
539
+ }
540
+
541
+ interface AutodateField extends core.AutodateField{} // merge
542
+ /**
543
+ * {@inheritDoc core.AutodateField}
544
+ *
545
+ * @group PocketBase
546
+ */
547
+ declare class AutodateField implements core.AutodateField {
548
+ constructor(data?: Partial<core.AutodateField>)
549
+ }
550
+
551
+ interface JSONField extends core.JSONField{} // merge
552
+ /**
553
+ * {@inheritDoc core.JSONField}
554
+ *
555
+ * @group PocketBase
556
+ */
557
+ declare class JSONField implements core.JSONField {
558
+ constructor(data?: Partial<core.JSONField>)
559
+ }
560
+
561
+ interface RelationField extends core.RelationField{} // merge
562
+ /**
563
+ * {@inheritDoc core.RelationField}
564
+ *
565
+ * @group PocketBase
566
+ */
567
+ declare class RelationField implements core.RelationField {
568
+ constructor(data?: Partial<core.RelationField>)
569
+ }
570
+
571
+ interface SelectField extends core.SelectField{} // merge
572
+ /**
573
+ * {@inheritDoc core.SelectField}
574
+ *
575
+ * @group PocketBase
576
+ */
577
+ declare class SelectField implements core.SelectField {
578
+ constructor(data?: Partial<core.SelectField>)
579
+ }
580
+
581
+ interface FileField extends core.FileField{} // merge
582
+ /**
583
+ * {@inheritDoc core.FileField}
584
+ *
585
+ * @group PocketBase
586
+ */
587
+ declare class FileField implements core.FileField {
588
+ constructor(data?: Partial<core.FileField>)
589
+ }
590
+
591
+ interface GeoPointField extends core.GeoPointField{} // merge
592
+ /**
593
+ * {@inheritDoc core.GeoPointField}
594
+ *
595
+ * @group PocketBase
596
+ */
597
+ declare class GeoPointField implements core.GeoPointField {
598
+ constructor(data?: Partial<core.GeoPointField>)
599
+ }
600
+
601
+ interface MailerMessage extends mailer.Message{} // merge
602
+ /**
603
+ * MailerMessage defines a single email message.
604
+ *
605
+ * ` + "```" + `js
606
+ * const message = new MailerMessage({
607
+ * from: {
608
+ * address: $app.settings().meta.senderAddress,
609
+ * name: $app.settings().meta.senderName,
610
+ * },
611
+ * to: [{address: "test@example.com"}],
612
+ * subject: "YOUR_SUBJECT...",
613
+ * html: "YOUR_HTML_BODY...",
614
+ * })
615
+ *
616
+ * $app.newMailClient().send(message)
617
+ * ` + "```" + `
618
+ *
619
+ * @group PocketBase
620
+ */
621
+ declare class MailerMessage implements mailer.Message {
622
+ constructor(message?: Partial<mailer.Message>)
623
+ }
624
+
625
+ interface Command extends cobra.Command{} // merge
626
+ /**
627
+ * Command defines a single console command.
628
+ *
629
+ * Example:
630
+ *
631
+ * ` + "```" + `js
632
+ * const command = new Command({
633
+ * use: "hello",
634
+ * run: (cmd, args) => { console.log("Hello world!") },
635
+ * })
636
+ *
637
+ * $app.rootCmd.addCommand(command);
638
+ * ` + "```" + `
639
+ *
640
+ * @group PocketBase
641
+ */
642
+ declare class Command implements cobra.Command {
643
+ constructor(cmd?: Partial<cobra.Command>)
644
+ }
645
+
646
+ /**
647
+ * RequestInfo defines a single core.RequestInfo instance, usually used
648
+ * as part of various filter checks.
649
+ *
650
+ * Example:
651
+ *
652
+ * ` + "```" + `js
653
+ * const authRecord = $app.findAuthRecordByEmail("users", "test@example.com")
654
+ *
655
+ * const info = new RequestInfo({
656
+ * auth: authRecord,
657
+ * body: {"name": 123},
658
+ * headers: {"x-token": "..."},
659
+ * })
660
+ *
661
+ * const record = $app.findFirstRecordByData("articles", "slug", "hello")
662
+ *
663
+ * const canAccess = $app.canAccessRecord(record, info, "@request.auth.id != '' && @request.body.name = 123")
664
+ * ` + "```" + `
665
+ *
666
+ * @group PocketBase
667
+ */
668
+ declare const RequestInfo: {
669
+ new(info?: Partial<core.RequestInfo>): core.RequestInfo
670
+
671
+ // note: declare as "newable" const due to conflict with the RequestInfo TS node type
672
+ }
673
+
674
+ /**
675
+ * Middleware defines a single request middleware handler.
676
+ *
677
+ * This class is usually used when you want to explicitly specify a priority to your custom route middleware.
678
+ *
679
+ * Example:
680
+ *
681
+ * ` + "```" + `js
682
+ * routerUse(new Middleware((e) => {
683
+ * console.log(e.request.url.path)
684
+ * return e.next()
685
+ * }, -10))
686
+ * ` + "```" + `
687
+ *
688
+ * @group PocketBase
689
+ */
690
+ declare class Middleware {
691
+ constructor(
692
+ func: string|((e: core.RequestEvent) => void),
693
+ priority?: number,
694
+ id?: string,
695
+ )
696
+ }
697
+
698
+ interface Timezone extends time.Location{} // merge
699
+ /**
700
+ * Timezone returns the timezone location with the given name.
701
+ *
702
+ * The name is expected to be a location name corresponding to a file
703
+ * in the IANA Time Zone database, such as "America/New_York".
704
+ *
705
+ * If the name is "Local", LoadLocation returns Local.
706
+ *
707
+ * If the name is "", invalid or "UTC", returns UTC.
708
+ *
709
+ * The constructor is equivalent to calling the Go ` + "`" + `time.LoadLocation(name)` + "`" + ` method.
710
+ *
711
+ * Example:
712
+ *
713
+ * ` + "```" + `js
714
+ * const zone = new Timezone("America/New_York")
715
+ * $app.cron().setTimezone(zone)
716
+ * ` + "```" + `
717
+ *
718
+ * @group PocketBase
719
+ */
720
+ declare class Timezone implements time.Location {
721
+ constructor(name?: string)
722
+ }
723
+
724
+ interface DateTime extends types.DateTime{} // merge
725
+ /**
726
+ * DateTime defines a single DateTime type instance.
727
+ * The returned date is always represented in UTC.
728
+ *
729
+ * Example:
730
+ *
731
+ * ` + "```" + `js
732
+ * const dt0 = new DateTime() // now
733
+ *
734
+ * // full datetime string
735
+ * const dt1 = new DateTime('2023-07-01 00:00:00.000Z')
736
+ *
737
+ * // datetime string with default "parse in" timezone location
738
+ * //
739
+ * // similar to new DateTime('2023-07-01 00:00:00 +01:00') or new DateTime('2023-07-01 00:00:00 +02:00')
740
+ * // but accounts for the daylight saving time (DST)
741
+ * const dt2 = new DateTime('2023-07-01 00:00:00', 'Europe/Amsterdam')
742
+ * ` + "```" + `
743
+ *
744
+ * @group PocketBase
745
+ */
746
+ declare class DateTime implements types.DateTime {
747
+ constructor(date?: string, defaultParseInLocation?: string)
748
+ }
749
+
750
+ interface ValidationError extends ozzo_validation.Error{} // merge
751
+ /**
752
+ * ValidationError defines a single formatted data validation error,
753
+ * usually used as part of an error response.
754
+ *
755
+ * ` + "```" + `js
756
+ * new ValidationError("invalid_title", "Title is not valid")
757
+ * ` + "```" + `
758
+ *
759
+ * @group PocketBase
760
+ */
761
+ declare class ValidationError implements ozzo_validation.Error {
762
+ constructor(code?: string, message?: string)
763
+ }
764
+
765
+ interface Cookie extends http.Cookie{} // merge
766
+ /**
767
+ * A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
768
+ * HTTP response.
769
+ *
770
+ * Example:
771
+ *
772
+ * ` + "```" + `js
773
+ * routerAdd("POST", "/example", (c) => {
774
+ * c.setCookie(new Cookie({
775
+ * name: "example_name",
776
+ * value: "example_value",
777
+ * path: "/",
778
+ * domain: "example.com",
779
+ * maxAge: 10,
780
+ * secure: true,
781
+ * httpOnly: true,
782
+ * sameSite: 3,
783
+ * }))
784
+ *
785
+ * return c.redirect(200, "/");
786
+ * })
787
+ * ` + "```" + `
788
+ *
789
+ * @group PocketBase
790
+ */
791
+ declare class Cookie implements http.Cookie {
792
+ constructor(options?: Partial<http.Cookie>)
793
+ }
794
+
795
+ interface SubscriptionMessage extends subscriptions.Message{} // merge
796
+ /**
797
+ * SubscriptionMessage defines a realtime subscription payload.
798
+ *
799
+ * Example:
800
+ *
801
+ * ` + "```" + `js
802
+ * onRealtimeConnectRequest((e) => {
803
+ * e.client.send(new SubscriptionMessage({
804
+ * name: "example",
805
+ * data: '{"greeting": "Hello world"}'
806
+ * }))
807
+ * })
808
+ * ` + "```" + `
809
+ *
810
+ * @group PocketBase
811
+ */
812
+ declare class SubscriptionMessage implements subscriptions.Message {
813
+ constructor(options?: Partial<subscriptions.Message>)
814
+ }
815
+
816
+ // -------------------------------------------------------------------
817
+ // dbxBinds
818
+ // -------------------------------------------------------------------
819
+
820
+ /**
821
+ * ` + "`$dbx`" + ` defines common utility for working with the DB abstraction.
822
+ * For examples and guides please check the [Database guide](https://pocketbase.io/docs/js-database).
823
+ *
824
+ * @group PocketBase
825
+ */
826
+ declare namespace $dbx {
827
+ /**
828
+ * {@inheritDoc dbx.HashExp}
829
+ */
830
+ export function hashExp(pairs: { [key:string]: any }): dbx.Expression
831
+
832
+ let _in: dbx._in
833
+ export { _in as in }
834
+
835
+ export let exp: dbx.newExp
836
+ export let not: dbx.not
837
+ export let and: dbx.and
838
+ export let or: dbx.or
839
+ export let notIn: dbx.notIn
840
+ export let like: dbx.like
841
+ export let orLike: dbx.orLike
842
+ export let notLike: dbx.notLike
843
+ export let orNotLike: dbx.orNotLike
844
+ export let exists: dbx.exists
845
+ export let notExists: dbx.notExists
846
+ export let between: dbx.between
847
+ export let notBetween: dbx.notBetween
848
+ }
849
+
850
+ // -------------------------------------------------------------------
851
+ // mailsBinds
852
+ // -------------------------------------------------------------------
853
+
854
+ /**
855
+ * ` + "`" + `$mails` + "`" + ` defines helpers to send common
856
+ * auth records emails like verification, password reset, etc.
857
+ *
858
+ * @group PocketBase
859
+ */
860
+ declare namespace $mails {
861
+ let sendRecordPasswordReset: mails.sendRecordPasswordReset
862
+ let sendRecordVerification: mails.sendRecordVerification
863
+ let sendRecordChangeEmail: mails.sendRecordChangeEmail
864
+ let sendRecordOTP: mails.sendRecordOTP
865
+ let sendRecordAuthAlert: mails.sendRecordAuthAlert
866
+ }
867
+
868
+ // -------------------------------------------------------------------
869
+ // securityBinds
870
+ // -------------------------------------------------------------------
871
+
872
+ /**
873
+ * ` + "`" + `$security` + "`" + ` defines low level helpers for creating
874
+ * and parsing JWTs, random string generation, AES encryption, etc.
875
+ *
876
+ * @group PocketBase
877
+ */
878
+ declare namespace $security {
879
+ let randomString: security.randomString
880
+ let randomStringWithAlphabet: security.randomStringWithAlphabet
881
+ let randomStringByRegex: security.randomStringByRegex
882
+ let pseudorandomString: security.pseudorandomString
883
+ let pseudorandomStringWithAlphabet: security.pseudorandomStringWithAlphabet
884
+ let encrypt: security.encrypt
885
+ let decrypt: security.decrypt
886
+ let hs256: security.hs256
887
+ let hs512: security.hs512
888
+ let equal: security.equal
889
+ let md5: security.md5
890
+ let sha256: security.sha256
891
+ let sha512: security.sha512
892
+
893
+ /**
894
+ * {@inheritDoc security.newJWT}
895
+ */
896
+ function createJWT(payload: { [key:string]: any }, signingKey: string, secDuration: number): string
897
+
898
+ /**
899
+ * {@inheritDoc security.parseUnverifiedJWT}
900
+ */
901
+ function parseUnverifiedJWT(token: string): _TygojaDict
902
+
903
+ /**
904
+ * {@inheritDoc security.parseJWT}
905
+ */
906
+ function parseJWT(token: string, verificationKey: string): _TygojaDict
907
+ }
908
+
909
+ // -------------------------------------------------------------------
910
+ // filesystemBinds
911
+ // -------------------------------------------------------------------
912
+
913
+ /**
914
+ * ` + "`" + `$filesystem` + "`" + ` defines common helpers for working
915
+ * with the PocketBase filesystem abstraction.
916
+ *
917
+ * @group PocketBase
918
+ */
919
+ declare namespace $filesystem {
920
+ let fileFromPath: filesystem.newFileFromPath
921
+ let fileFromBytes: filesystem.newFileFromBytes
922
+ let fileFromMultipart: filesystem.newFileFromMultipart
923
+
924
+ /**
925
+ * Initializes a new S3-only filesystem instance
926
+ * (make sure to call ` + "`" + `close()` + "`" + ` after you are done working with it).
927
+ *
928
+ * Most users should prefer ` + "`" + `$app.newFilesystem()` + "`" + ` which will
929
+ * construct a local or S3 filesystem based on the configured application settings.
930
+ */
931
+ let s3: filesystem.newS3
932
+
933
+ /**
934
+ * Initializes a new local-only filesystem instance
935
+ * (make sure to call ` + "`" + `close()` + "`" + ` after you are done working with it).
936
+ *
937
+ * Most users should prefer ` + "`" + `$app.newFilesystem()` + "`" + ` which will
938
+ * construct a local or S3 filesystem based on the configured application settings.
939
+ */
940
+ let local: filesystem.newLocal
941
+
942
+ /**
943
+ * fileFromURL creates a new File from the provided url by
944
+ * downloading the resource and creating a BytesReader.
945
+ *
946
+ * Example:
947
+ *
948
+ * ` + "```" + `js
949
+ * // with default max timeout of 120sec
950
+ * const file1 = $filesystem.fileFromURL("https://...")
951
+ *
952
+ * // with custom timeout of 15sec
953
+ * const file2 = $filesystem.fileFromURL("https://...", 15)
954
+ * ` + "```" + `
955
+ */
956
+ function fileFromURL(url: string, secTimeout?: number): filesystem.File
957
+ }
958
+
959
+ // -------------------------------------------------------------------
960
+ // filepathBinds
961
+ // -------------------------------------------------------------------
962
+
963
+ /**
964
+ * ` + "`$filepath`" + ` defines common helpers for manipulating filename
965
+ * paths in a way compatible with the target operating system-defined file paths.
966
+ *
967
+ * @group PocketBase
968
+ */
969
+ declare namespace $filepath {
970
+ let base: filepath.base
971
+ let clean: filepath.clean
972
+ let dir: filepath.dir
973
+ let ext: filepath.ext
974
+ let fromSlash: filepath.fromSlash
975
+ let glob: filepath.glob
976
+ let isAbs: filepath.isAbs
977
+ let join: filepath.join
978
+ let match: filepath.match
979
+ let rel: filepath.rel
980
+ let split: filepath.split
981
+ let splitList: filepath.splitList
982
+ let toSlash: filepath.toSlash
983
+ let walk: filepath.walk
984
+ let walkDir: filepath.walkDir
985
+ }
986
+
987
+ // -------------------------------------------------------------------
988
+ // osBinds
989
+ // -------------------------------------------------------------------
990
+
991
+ /**
992
+ * ` + "`$os`" + ` defines common helpers for working with the OS level primitives
993
+ * (eg. deleting directories, executing shell commands, etc.).
994
+ *
995
+ * @group PocketBase
996
+ */
997
+ declare namespace $os {
998
+ /**
999
+ * Legacy alias for $os.cmd().
1000
+ */
1001
+ let exec: exec.command
1002
+
1003
+ /**
1004
+ * Prepares an external OS command.
1005
+ *
1006
+ * Example:
1007
+ *
1008
+ * ` + "```" + `js
1009
+ * // prepare the command to execute
1010
+ * const cmd = $os.cmd('ls', '-sl')
1011
+ *
1012
+ * // execute the command and return its standard output as string
1013
+ * const output = toString(cmd.output());
1014
+ * ` + "```" + `
1015
+ */
1016
+ let cmd: exec.command
1017
+
1018
+ /**
1019
+ * Args hold the command-line arguments, starting with the program name.
1020
+ */
1021
+ let args: Array<string>
1022
+
1023
+ let exit: os.exit
1024
+ let getenv: os.getenv
1025
+ let dirFS: os.dirFS
1026
+ let readFile: os.readFile
1027
+ let writeFile: os.writeFile
1028
+ let stat: os.stat
1029
+ let readDir: os.readDir
1030
+ let tempDir: os.tempDir
1031
+ let truncate: os.truncate
1032
+ let getwd: os.getwd
1033
+ let mkdir: os.mkdir
1034
+ let mkdirAll: os.mkdirAll
1035
+ let rename: os.rename
1036
+ let remove: os.remove
1037
+ let removeAll: os.removeAll
1038
+ let openRoot: os.openRoot
1039
+ let openInRoot: os.openInRoot
1040
+ }
1041
+
1042
+ // -------------------------------------------------------------------
1043
+ // formsBinds
1044
+ // -------------------------------------------------------------------
1045
+
1046
+ interface AppleClientSecretCreateForm extends forms.AppleClientSecretCreate{} // merge
1047
+ /**
1048
+ * @inheritDoc
1049
+ * @group PocketBase
1050
+ */
1051
+ declare class AppleClientSecretCreateForm implements forms.AppleClientSecretCreate {
1052
+ constructor(app: CoreApp)
1053
+ }
1054
+
1055
+ interface RecordUpsertForm extends forms.RecordUpsert{} // merge
1056
+ /**
1057
+ * @inheritDoc
1058
+ * @group PocketBase
1059
+ */
1060
+ declare class RecordUpsertForm implements forms.RecordUpsert {
1061
+ constructor(app: CoreApp, record: core.Record)
1062
+ }
1063
+
1064
+ interface TestEmailSendForm extends forms.TestEmailSend{} // merge
1065
+ /**
1066
+ * @inheritDoc
1067
+ * @group PocketBase
1068
+ */
1069
+ declare class TestEmailSendForm implements forms.TestEmailSend {
1070
+ constructor(app: CoreApp)
1071
+ }
1072
+
1073
+ interface TestS3FilesystemForm extends forms.TestS3Filesystem{} // merge
1074
+ /**
1075
+ * @inheritDoc
1076
+ * @group PocketBase
1077
+ */
1078
+ declare class TestS3FilesystemForm implements forms.TestS3Filesystem {
1079
+ constructor(app: CoreApp)
1080
+ }
1081
+
1082
+ // -------------------------------------------------------------------
1083
+ // apisBinds
1084
+ // -------------------------------------------------------------------
1085
+
1086
+ interface ApiError extends router.ApiError{} // merge
1087
+ /**
1088
+ * @inheritDoc
1089
+ *
1090
+ * @group PocketBase
1091
+ */
1092
+ declare class ApiError implements router.ApiError {
1093
+ constructor(status?: number, message?: string, data?: any)
1094
+ }
1095
+
1096
+ interface NotFoundError extends router.ApiError{} // merge
1097
+ /**
1098
+ * NotFounderor returns 404 ApiError.
1099
+ *
1100
+ * @group PocketBase
1101
+ */
1102
+ declare class NotFoundError implements router.ApiError {
1103
+ constructor(message?: string, data?: any)
1104
+ }
1105
+
1106
+ interface BadRequestError extends router.ApiError{} // merge
1107
+ /**
1108
+ * BadRequestError returns 400 ApiError.
1109
+ *
1110
+ * @group PocketBase
1111
+ */
1112
+ declare class BadRequestError implements router.ApiError {
1113
+ constructor(message?: string, data?: any)
1114
+ }
1115
+
1116
+ interface ForbiddenError extends router.ApiError{} // merge
1117
+ /**
1118
+ * ForbiddenError returns 403 ApiError.
1119
+ *
1120
+ * @group PocketBase
1121
+ */
1122
+ declare class ForbiddenError implements router.ApiError {
1123
+ constructor(message?: string, data?: any)
1124
+ }
1125
+
1126
+ interface UnauthorizedError extends router.ApiError{} // merge
1127
+ /**
1128
+ * UnauthorizedError returns 401 ApiError.
1129
+ *
1130
+ * @group PocketBase
1131
+ */
1132
+ declare class UnauthorizedError implements router.ApiError {
1133
+ constructor(message?: string, data?: any)
1134
+ }
1135
+
1136
+ interface TooManyRequestsError extends router.ApiError{} // merge
1137
+ /**
1138
+ * TooManyRequestsError returns 429 ApiError.
1139
+ *
1140
+ * @group PocketBase
1141
+ */
1142
+ declare class TooManyRequestsError implements router.ApiError {
1143
+ constructor(message?: string, data?: any)
1144
+ }
1145
+
1146
+ interface InternalServerError extends router.ApiError{} // merge
1147
+ /**
1148
+ * InternalServerError returns 429 ApiError.
1149
+ *
1150
+ * @group PocketBase
1151
+ */
1152
+ declare class InternalServerError implements router.ApiError {
1153
+ constructor(message?: string, data?: any)
1154
+ }
1155
+
1156
+ /**
1157
+ * ` + "`" + `$apis` + "`" + ` defines commonly used PocketBase api helpers and middlewares.
1158
+ *
1159
+ * @group PocketBase
1160
+ */
1161
+ declare namespace $apis {
1162
+ /**
1163
+ * Route handler to serve static directory content (html, js, css, etc.).
1164
+ *
1165
+ * If a file resource is missing and indexFallback is true, the request
1166
+ * will be forwarded to the base index.html (useful for SPA with pretty urls).
1167
+ *
1168
+ * NB! Expects the route to have a "{path...}" wildcard parameter.
1169
+ *
1170
+ * Special redirects:
1171
+ *
1172
+ * - if "path" is a file that ends in index.html, it is redirected to its non-index.html version (eg. /test/index.html -> /test/)
1173
+ * - if "path" is a directory that has index.html, the index.html file is rendered,
1174
+ * otherwise if missing - returns 404 or fallback to the root index.html if indexFallback is true
1175
+ *
1176
+ * Example:
1177
+ *
1178
+ * ` + "```" + `js
1179
+ * // serves static files from the provided dir string path (it will be wrapped in $os.dirFS())
1180
+ * routerAdd("GET", "/{path...}", $apis.static("/path/to/public", false))
1181
+ *
1182
+ * // serves static files from the explicit fs.FS value ($os.dirFS(), $os.openRoot().fs(), etc.)
1183
+ * routerAdd("GET", "/{path...}", $apis.static($os.dirFS("/path/to/public"), false))
1184
+ * ` + "```" + `
1185
+ */
1186
+ function static(dirOrFS: string|fs.FS, indexFallback: boolean): (e: core.RequestEvent) => void
1187
+
1188
+ let requireGuestOnly: apis.requireGuestOnly
1189
+ let requireAuth: apis.requireAuth
1190
+ let requireSuperuserAuth: apis.requireSuperuserAuth
1191
+ let requireSuperuserOrOwnerAuth: apis.requireSuperuserOrOwnerAuth
1192
+ let skipSuccessActivityLog: apis.skipSuccessActivityLog
1193
+ let gzip: apis.gzip
1194
+ let bodyLimit: apis.bodyLimit
1195
+ let enrichRecord: apis.enrichRecord
1196
+ let enrichRecords: apis.enrichRecords
1197
+
1198
+ /**
1199
+ * RecordAuthResponse writes standardized json record auth response
1200
+ * into the specified request event.
1201
+ *
1202
+ * The authMethod argument specify the name of the current authentication method (eg. password, oauth2, etc.)
1203
+ * that it is used primarily as an auth identifier during MFA and for login alerts.
1204
+ *
1205
+ * Set authMethod to empty string if you want to ignore the MFA checks and the login alerts
1206
+ * (can be also adjusted additionally via the onRecordAuthRequest hook).
1207
+ */
1208
+ function recordAuthResponse(e: core.RequestEvent, authRecord: core.Record, authMethod: string, meta?: any): void
1209
+ }
1210
+
1211
+ // -------------------------------------------------------------------
1212
+ // httpClientBinds
1213
+ // -------------------------------------------------------------------
1214
+
1215
+ // extra FormData overload to prevent TS warnings when used with non File/Blob value.
1216
+ interface FormData {
1217
+ append(key:string, value:any): void
1218
+ set(key:string, value:any): void
1219
+ }
1220
+
1221
+ /**
1222
+ * ` + "`" + `$http` + "`" + ` defines common methods for working with HTTP requests.
1223
+ *
1224
+ * @group PocketBase
1225
+ */
1226
+ declare namespace $http {
1227
+ /**
1228
+ * Sends a single HTTP request.
1229
+ *
1230
+ * Example:
1231
+ *
1232
+ * ` + "```" + `js
1233
+ * const res = $http.send({
1234
+ * method: "POST",
1235
+ * url: "https://example.com",
1236
+ * body: JSON.stringify({"title": "test"}),
1237
+ * headers: { 'Content-Type': 'application/json' }
1238
+ * })
1239
+ *
1240
+ * console.log(res.statusCode) // the response HTTP status code
1241
+ * console.log(res.headers) // the response headers (eg. res.headers['X-Custom'][0])
1242
+ * console.log(res.cookies) // the response cookies (eg. res.cookies.sessionId.value)
1243
+ * console.log(res.body) // the response body as raw bytes slice
1244
+ * console.log(res.json) // the response body as parsed json array or map
1245
+ * ` + "```" + `
1246
+ */
1247
+ function send(config: {
1248
+ url: string,
1249
+ body?: string|FormData,
1250
+ method?: string, // default to "GET"
1251
+ headers?: { [key:string]: string },
1252
+ timeout?: number, // default to 120
1253
+
1254
+ // @deprecated please use body instead
1255
+ data?: { [key:string]: any },
1256
+ }): {
1257
+ statusCode: number,
1258
+ headers: { [key:string]: Array<string> },
1259
+ cookies: { [key:string]: http.Cookie },
1260
+ json: any,
1261
+ body: Array<number>,
1262
+
1263
+ // @deprecated please use toString(result.body) instead
1264
+ raw: string,
1265
+ };
1266
+ }
1267
+
1268
+ // -------------------------------------------------------------------
1269
+ // migrate only
1270
+ // -------------------------------------------------------------------
1271
+
1272
+ /**
1273
+ * Migrate defines a single migration upgrade/downgrade action.
1274
+ *
1275
+ * _Note that this method is available only in pb_migrations context._
1276
+ *
1277
+ * @group PocketBase
1278
+ */
1279
+ declare function migrate(
1280
+ up: (txApp: CoreApp) => void,
1281
+ down?: (txApp: CoreApp) => void
1282
+ ): void;
1283
+ `
1284
+
1285
+ var mapper = &jsvm.FieldMapper{}
1286
+
1287
+ func main() {
1288
+ declarations := heading + hooksDeclarations()
1289
+
1290
+ gen := tygoja.New(tygoja.Config{
1291
+ Packages: map[string][]string{
1292
+ "github.com/pocketbase/ozzo-validation/v4": {"Error"},
1293
+ "github.com/pocketbase/dbx": {"*"},
1294
+ "github.com/pocketbase/pocketbase/tools/security": {"*"},
1295
+ "github.com/pocketbase/pocketbase/tools/filesystem": {"*"},
1296
+ "github.com/pocketbase/pocketbase/tools/template": {"*"},
1297
+ "github.com/pocketbase/pocketbase/mails": {"*"},
1298
+ "github.com/pocketbase/pocketbase/apis": {"*"},
1299
+ "github.com/pocketbase/pocketbase/core": {"*"},
1300
+ "github.com/pocketbase/pocketbase/forms": {"*"},
1301
+ "github.com/pocketbase/pocketbase": {"*"},
1302
+ "path/filepath": {"*"},
1303
+ "os": {"*"},
1304
+ "os/exec": {"Command"},
1305
+ },
1306
+ FieldNameFormatter: func(s string) string {
1307
+ return mapper.FieldName(nil, reflect.StructField{Name: s})
1308
+ },
1309
+ MethodNameFormatter: func(s string) string {
1310
+ return mapper.MethodName(nil, reflect.Method{Name: s})
1311
+ },
1312
+ TypeMappings: map[string]string{
1313
+ "crypto.*": "any",
1314
+ "acme.*": "any",
1315
+ "autocert.*": "any",
1316
+ "driver.*": "any",
1317
+ "reflect.*": "any",
1318
+ "fmt.*": "any",
1319
+ "rand.*": "any",
1320
+ "tls.*": "any",
1321
+ "asn1.*": "any",
1322
+ "pkix.*": "any",
1323
+ "x509.*": "any",
1324
+ "pflag.*": "any",
1325
+ "flag.*": "any",
1326
+ "log.*": "any",
1327
+ "http.Client": "any",
1328
+ "mail.Address": "{ address: string; name?: string; }", // prevents the LSP to complain in case no name is provided
1329
+ },
1330
+ Indent: " ", // use only a single space to reduce slightly the size
1331
+ WithPackageFunctions: true,
1332
+ Heading: declarations,
1333
+ })
1334
+
1335
+ result, err := gen.Generate()
1336
+ if err != nil {
1337
+ log.Fatal(err)
1338
+ }
1339
+
1340
+ _, filename, _, ok := runtime.Caller(0)
1341
+ if !ok {
1342
+ log.Fatal("Failed to get the current docs directory")
1343
+ }
1344
+
1345
+ // replace the original app interfaces with their non-"on*"" hooks equivalents
1346
+ result = strings.ReplaceAll(result, "core.App", "CoreApp")
1347
+ result = strings.ReplaceAll(result, "pocketbase.PocketBase", "PocketBase")
1348
+ result = strings.ReplaceAll(result, "ORIGINAL_CORE_APP", "core.App")
1349
+ result = strings.ReplaceAll(result, "ORIGINAL_POCKETBASE", "pocketbase.PocketBase")
1350
+
1351
+ // prepend a timestamp with the generation time
1352
+ // so that it can be compared without reading the entire file
1353
+ result = fmt.Sprintf("// %d\n%s", time.Now().Unix(), result)
1354
+
1355
+ parentDir := filepath.Dir(filename)
1356
+ typesFile := filepath.Join(parentDir, "generated", "types.d.ts")
1357
+
1358
+ lines := strings.Split(result, "\n")
1359
+ for i := range lines {
1360
+ lines[i] = strings.TrimRight(lines[i], " \t")
1361
+ }
1362
+ result = strings.Join(lines, "\n")
1363
+ if err := os.WriteFile(typesFile, []byte(result), 0644); err != nil {
1364
+ log.Fatal(err)
1365
+ }
1366
+ }
1367
+
1368
+ func hooksDeclarations() string {
1369
+ var result strings.Builder
1370
+
1371
+ excluded := []string{"OnServe"}
1372
+ appType := reflect.TypeOf(struct{ core.App }{})
1373
+ totalMethods := appType.NumMethod()
1374
+
1375
+ for i := 0; i < totalMethods; i++ {
1376
+ method := appType.Method(i)
1377
+ if !strings.HasPrefix(method.Name, "On") || list.ExistInSlice(method.Name, excluded) {
1378
+ continue // not a hook or excluded
1379
+ }
1380
+
1381
+ hookType := method.Type.Out(0)
1382
+
1383
+ withTags := strings.HasPrefix(hookType.String(), "*hook.TaggedHook")
1384
+
1385
+ addMethod, ok := hookType.MethodByName("BindFunc")
1386
+ if !ok {
1387
+ continue
1388
+ }
1389
+
1390
+ addHanlder := addMethod.Type.In(1)
1391
+ eventTypeName := strings.TrimPrefix(addHanlder.In(0).String(), "*")
1392
+
1393
+ jsName := mapper.MethodName(appType, method)
1394
+ result.WriteString("/** @group PocketBase */")
1395
+ result.WriteString("declare function ")
1396
+ result.WriteString(jsName)
1397
+ result.WriteString("(handler: (e: ")
1398
+ result.WriteString(eventTypeName)
1399
+ result.WriteString(") => void")
1400
+ if withTags {
1401
+ result.WriteString(", ...tags: string[]")
1402
+ }
1403
+ result.WriteString("): void")
1404
+ result.WriteString("\n")
1405
+ }
1406
+
1407
+ return result.String()
1408
+ }