@freehour/supabase-core 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,695 @@
1
+ import { assert as o } from "@freehour/assert";
2
+ import d from "zod";
3
+ import { PostgrestError as S } from "@supabase/supabase-js";
4
+ class k extends Error {
5
+ constructor(t, e = {}) {
6
+ super(t, e), this.name = this.constructor.name, Error.captureStackTrace(this, this.constructor);
7
+ }
8
+ }
9
+ class E extends k {
10
+ /**
11
+ * The ID of the file that was not found.
12
+ */
13
+ fileId;
14
+ /**
15
+ * The name of the bucket where the file was expected to be found.
16
+ */
17
+ bucket;
18
+ /**
19
+ * The path relative to the bucket root where the file was expected to be found.
20
+ */
21
+ path;
22
+ constructor(t, {
23
+ fileId: e,
24
+ bucket: a,
25
+ path: n
26
+ } = {}) {
27
+ super(t), this.fileId = e, this.bucket = a, this.path = n;
28
+ }
29
+ }
30
+ class q extends k {
31
+ /**
32
+ * The encountered expression that could not be parsed.
33
+ */
34
+ expression;
35
+ /**
36
+ * Additional context about the expected format or structure.
37
+ */
38
+ format;
39
+ constructor(t = "Expression could not be parsed", {
40
+ expression: e,
41
+ format: a,
42
+ ...n
43
+ } = {}) {
44
+ super(t, n), this.expression = e, this.format = a;
45
+ }
46
+ }
47
+ class _ extends k {
48
+ /**
49
+ * The schema where the record was expected to be found.
50
+ */
51
+ schema;
52
+ /**
53
+ * The table or view where the record was expected to be found.
54
+ */
55
+ relation;
56
+ /**
57
+ * The ID of the record that was not found.
58
+ */
59
+ id;
60
+ constructor(t, {
61
+ schema: e,
62
+ relation: a,
63
+ id: n
64
+ } = {}) {
65
+ super(t), this.schema = e, this.relation = a, this.id = n;
66
+ }
67
+ }
68
+ const $ = d.object({
69
+ code: d.string(),
70
+ details: d.string().nullable(),
71
+ hint: d.string().nullable(),
72
+ name: d.string().optional(),
73
+ message: d.string().optional()
74
+ });
75
+ function V(r) {
76
+ return r instanceof S || $.safeParse(r).success;
77
+ }
78
+ const I = ["eq", "neq", "gt", "gte", "lt", "lte", "like", "ilike", "match", "imatch", "in", "is", "isdistinct", "fts", "plfts", "phfts", "wfts", "cs", "cd", "ov", "sl", "sr", "nxr", "nxl", "adj"], Z = ["and", "or"], G = ",", v = "~", H = (r) => (t = {}) => {
79
+ const e = (n) => t[n] ?? n, a = Object.keys(r.shape);
80
+ return d.string().transform((n, s) => {
81
+ try {
82
+ return A(n, a, e);
83
+ } catch (i) {
84
+ return s.addIssue({
85
+ code: "custom",
86
+ input: n,
87
+ message: i instanceof Error ? i.message : void 0,
88
+ params: i instanceof q ? {
89
+ expression: i.expression,
90
+ format: i.format
91
+ } : void 0
92
+ }), [];
93
+ }
94
+ });
95
+ };
96
+ function P(r) {
97
+ return r.startsWith("not.") ? r.slice(4) : `not.${r}`;
98
+ }
99
+ function N(r) {
100
+ return {
101
+ ...r,
102
+ op: P(r.op)
103
+ };
104
+ }
105
+ function x(r, t = (e) => e) {
106
+ if (r.type === "logical") {
107
+ const e = r.args.map((a) => x(a, t));
108
+ return `${r.op}(${e})`;
109
+ }
110
+ return `${t(r.key)}.${r.op}.${r.value}`;
111
+ }
112
+ function j(r, t = (a) => a, e = v) {
113
+ return r.map((a) => x(a, t)).join(e);
114
+ }
115
+ function g(r, t = [], e = (a) => a) {
116
+ function a(l) {
117
+ const b = [];
118
+ let y = 0, h = "";
119
+ for (const f of l)
120
+ f === "(" ? (y++, h += f) : f === ")" ? (y--, h += f) : f === "," && y === 0 ? (b.push(h.trim()), h = "") : h += f;
121
+ return h && b.push(h.trim()), b;
122
+ }
123
+ if (r.endsWith(")")) {
124
+ if (r.startsWith("and("))
125
+ return {
126
+ type: "logical",
127
+ op: "and",
128
+ args: a(r.slice(4, -1)).map((l) => g(l, t, e))
129
+ };
130
+ if (r.startsWith("or("))
131
+ return {
132
+ type: "logical",
133
+ op: "or",
134
+ args: a(r.slice(3, -1)).map((l) => g(l, t, e))
135
+ };
136
+ if (r.startsWith("not.and("))
137
+ return {
138
+ type: "logical",
139
+ op: "not.and",
140
+ args: a(r.slice(8, -1)).map((l) => g(l, t, e))
141
+ };
142
+ if (r.startsWith("not.or("))
143
+ return {
144
+ type: "logical",
145
+ op: "not.or",
146
+ args: a(r.slice(7, -1)).map((l) => g(l, t, e))
147
+ };
148
+ }
149
+ const s = `^(${t.length === 0 ? "[a-zA-Z_][a-zA-Z0-9_]*" : t.join("|")})\\.((?:not\\.)?(?:${I.join("|")}))\\.(.+)$`, c = new RegExp(s).exec(r);
150
+ if (!c)
151
+ throw new q(`Invalid filter expression '${r}'`, {
152
+ expression: r,
153
+ format: {
154
+ syntax: "key.(not.)op.value",
155
+ keys: t.length === 0 ? "*" : t,
156
+ operators: I
157
+ }
158
+ });
159
+ const [, u, m, w] = c;
160
+ return {
161
+ type: "condition",
162
+ key: e(u),
163
+ op: m,
164
+ value: o.defined(w)
165
+ };
166
+ }
167
+ function A(r, t = [], e = (n) => n, a = v) {
168
+ return r.length === 0 ? [] : r.split(a).map((n) => g(n, t, e));
169
+ }
170
+ function D(r, t = "/") {
171
+ const e = r.lastIndexOf(t);
172
+ return e === -1 ? ["", r] : [r.substring(0, e), r.substring(e + 1)];
173
+ }
174
+ function O(r) {
175
+ return Array.isArray(r) ? r : [r];
176
+ }
177
+ function z(r, t) {
178
+ return r.reduce((e, a) => {
179
+ const n = t(a);
180
+ return (e[n] ??= []).push(a), e;
181
+ }, {});
182
+ }
183
+ function T(r) {
184
+ return Object.entries(r);
185
+ }
186
+ const p = {
187
+ /**
188
+ * Query extension for PostgREST queries.
189
+ * Supports typesafe column selection and counting.
190
+ * This extension can be used with any PostgREST query builder.
191
+ *
192
+ * @example
193
+ * const table = supabase.schema('public').from('my_table');
194
+ * const {data, error} = await postgrestExtensions.query.enable(table)
195
+ * .selectColumns(['id', 'name'])
196
+ * .then(({data}) => console.log(data)); // [{ id: 1, name: 'John' }, ...]
197
+ */
198
+ query: {
199
+ enable: (r) => Object.assign(r, {
200
+ /**
201
+ * Selects columns from the relation.
202
+ *
203
+ * @param columns The array of column names to select, or '*' to select all columns.
204
+ * @param options The options for the selection, such as count.
205
+ * @returns The PostgREST filter builder with selection applied and filter extension enabled.
206
+ */
207
+ select: (t, e) => p.filter.enable(
208
+ r.select(
209
+ O(t).join(","),
210
+ e
211
+ )
212
+ ),
213
+ /**
214
+ * Counts the number of rows in the relation.
215
+ * Does not select any columns, only counts the rows.
216
+ *
217
+ * @param method The counting method to use, defaults to 'exact'.
218
+ * @returns The PostgREST filter builder with counting applied and filter extension enabled.
219
+ */
220
+ count: (t = "exact") => p.filter.enable(
221
+ r.select("*", { count: t, head: !0 })
222
+ ),
223
+ /**
224
+ * Deletes rows from the relation.
225
+ * Returns a filter builder for further filtering before deletion.
226
+ *
227
+ * @returns The PostgREST filter builder with delete applied and filter extension enabled.
228
+ */
229
+ delete: () => p.filter.enable(
230
+ r.delete()
231
+ )
232
+ })
233
+ },
234
+ /**
235
+ * Filter extension for PostgREST queries.
236
+ * Supports applying filters, pagination and collecting results.
237
+ * This extension can be used with any PostgREST filter builder.
238
+ *
239
+ * @example
240
+ * const selection = supabase.schema('public').from('my_table').select('*', { count: 'exact' });
241
+ * const {data, error} = await postgrestExtensions.filter.enable(selection)
242
+ * .apply({ key: 'name', op: 'eq', value: 'John' })
243
+ * .paginate(1, 10)
244
+ * .collect();
245
+ */
246
+ filter: {
247
+ enable: (r, t = {}) => Object.assign(r, {
248
+ /**
249
+ * Applies a filter to the query.
250
+ * A filter is defined as an array of AST filter nodes including conditions and logical operators.
251
+ * @param filter The filter to apply.
252
+ */
253
+ apply: (e) => p.filter.enable(
254
+ (() => {
255
+ function a(n, s) {
256
+ if (s.type === "logical") {
257
+ const i = j(s.args, (c) => c, ",");
258
+ return s.op === "or" ? n.or(i) : s.op === "not.or" ? n.or(i, { referencedTable: "not" }) : a(n, {
259
+ type: "logical",
260
+ op: s.op === "and" ? "not.or" : "or",
261
+ args: s.args.map(N)
262
+ });
263
+ }
264
+ return n.filter(s.key, s.op, s.value);
265
+ }
266
+ return e.reduce(a, r);
267
+ })(),
268
+ t
269
+ ),
270
+ /**
271
+ * Limits the range of results to a specific page given a page index and limit.
272
+ * @param page The page index (0-based).
273
+ * @param limit The number of items per page.
274
+ * @param count Optional count of total items, if known.
275
+ * If provided, it will be used to check if the pagination range is valid and resolve to an empty range if not.
276
+ */
277
+ paginate: (e, a, n) => p.filter.enable(
278
+ (() => {
279
+ o(e >= 0, "Page index must be ≥ 0"), o(a >= 0, "Page limit must be ≥ 0");
280
+ const s = e * a, i = s + a - 1;
281
+ if (n !== void 0) {
282
+ if (s >= n)
283
+ return r.limit(0);
284
+ if (i >= n)
285
+ return r.range(s, n - 1);
286
+ }
287
+ return r.range(s, i);
288
+ })(),
289
+ {
290
+ ...t,
291
+ pagination: {
292
+ page: e,
293
+ limit: a,
294
+ count: n
295
+ }
296
+ }
297
+ ),
298
+ /**
299
+ * Collects the results of a pagination query.
300
+ * **Note:** For collect to work, paginate() must be called before collect() and the selection must include a `count`.
301
+ * @returns The paginated list of queried items.
302
+ */
303
+ collect: () => r.throwOnError().then((e) => {
304
+ const { data: a, count: n } = e, { page: s, limit: i, ...c } = o.defined(t.pagination, "Pagination context is required for collect(). Make sure to call paginate() before collect()"), u = n ?? c.count;
305
+ return o(i > 0, "Page limit must be > 0"), o(Array.isArray(a), "Data must be an array for pagination, make sure to select multiple rows in query"), o(u !== void 0, "Row count is required for pagination, make sure to count in query or pass `count` in paginate()"), {
306
+ items: a,
307
+ totalItems: u,
308
+ page: s,
309
+ totalPages: Math.ceil(u / i),
310
+ limit: i
311
+ };
312
+ })
313
+ })
314
+ }
315
+ };
316
+ class F {
317
+ database;
318
+ /**
319
+ * The name of the schema containing the view.
320
+ */
321
+ schema;
322
+ /**
323
+ * The name of the view or table that this service interacts with.
324
+ */
325
+ relation;
326
+ constructor({
327
+ database: t,
328
+ schema: e,
329
+ relation: a
330
+ }) {
331
+ this.database = t, this.schema = e, this.relation = a;
332
+ }
333
+ recordNotFoundError(t) {
334
+ return new _(`Record with id ${t} not found in ${this.schema}.${this.relation}`, {
335
+ schema: this.schema,
336
+ relation: this.relation,
337
+ id: t
338
+ });
339
+ }
340
+ /**
341
+ * The PostgREST query builder for this relation.
342
+ *
343
+ * @example
344
+ * const { data, error } = await dataService.query.select('*');
345
+ */
346
+ get query() {
347
+ const t = this.database.schema(this.schema).from(this.relation);
348
+ return p.query.enable(t);
349
+ }
350
+ /**
351
+ * Performs a fuzzy search on the specified column of the relation.
352
+ * @returns The rows that match the search criteria in descending order of similarity.
353
+ * @throws DatabaseApiError if the query fails.
354
+ */
355
+ async fuzzySearch({
356
+ column: t,
357
+ searchTerm: e = "",
358
+ minSimilarity: a = 0,
359
+ limit: n = 64
360
+ }) {
361
+ const { data: s } = await this.database.schema("core").rpc("fuzzy_search", {
362
+ relation: this.relation,
363
+ schema_name: this.schema,
364
+ column_name: t,
365
+ search_term: e,
366
+ min_similarity: a,
367
+ limit_results: n
368
+ }).throwOnError();
369
+ return s;
370
+ }
371
+ /**
372
+ * List all rows in the relation.
373
+ * Equivalent to `select('*')` with no filters or pagination.
374
+ * @returns Array of rows in the relation.
375
+ */
376
+ async list() {
377
+ const { data: t } = await this.query.select("*").throwOnError();
378
+ return t;
379
+ }
380
+ /**
381
+ * Gets a single row by its ID.
382
+ * @param id The ID of the row to find.
383
+ * @param columns The columns to select from the row. Defaults to all columns.
384
+ * @returns The found row or `undefined` if no row with the specified ID exists.
385
+ * @throws DatabaseApiError if the query fails.
386
+ */
387
+ async get(t, e = "*") {
388
+ const { data: a } = await this.query.select(e).eq("id", t).throwOnError();
389
+ return a[0];
390
+ }
391
+ /**
392
+ * Gets a single row by its ID, throwing an error if no such row exists.
393
+ * @param id The ID of the row to find.
394
+ * @param columns The columns to select from the row. Defaults to all columns.
395
+ * @returns The found row.
396
+ * @throws RecordNotFoundError if no row with the specified ID exists.
397
+ * @throws DatabaseApiError if the query fails for any other reason.
398
+ */
399
+ async getOrThrow(t, e = "*") {
400
+ const a = await this.get(t, e);
401
+ if (a === void 0)
402
+ throw this.recordNotFoundError(t);
403
+ return a;
404
+ }
405
+ /**
406
+ * Deletes a row from the relation by its ID, i.e. by the `id` column.
407
+ * @param id The ID of the row to delete.
408
+ * @return The deleted row, or `undefined` if no row with the specified ID existed.
409
+ * @throws DatabaseApiError if the deletion fails.
410
+ */
411
+ async delete(t) {
412
+ const { data: e } = await this.query.delete().eq("id", t).select().throwOnError();
413
+ return e[0];
414
+ }
415
+ /**
416
+ * Deletes a row from the relation by its ID, throwing an error if no such row exists.
417
+ * @param id The ID of the row to delete.
418
+ * @returns The deleted row.
419
+ * @throws RecordNotFoundError if no row with the specified ID exists.
420
+ * @throws DatabaseApiError if the deletion fails for any other reason.
421
+ */
422
+ async deleteOrThrow(t) {
423
+ const e = await this.delete(t);
424
+ if (e === void 0)
425
+ throw this.recordNotFoundError(t);
426
+ return e;
427
+ }
428
+ /**
429
+ * Inserts a new row into the relation.
430
+ * @param insert The data to insert into the relation.
431
+ * @returns The inserted row.
432
+ * @throws DatabaseApiError if the insertion fails.
433
+ */
434
+ async insert(t) {
435
+ const { data: e } = await this.query.insert(t).select().single().throwOnError();
436
+ return e;
437
+ }
438
+ /**
439
+ * Inserts or updates a row in the relation.
440
+ * @param insert The data to insert or update in the relation.
441
+ * @param options Options for the upsert operation, such as conflict resolution.
442
+ * @returns The inserted or updated row.
443
+ * @throws DatabaseApiError if the upsert operation fails.
444
+ */
445
+ async upsert(t, {
446
+ onConflict: e,
447
+ ...a
448
+ } = {}) {
449
+ const { data: n } = await this.query.upsert(t, {
450
+ onConflict: e?.join(","),
451
+ ...a
452
+ }).select().single().throwOnError();
453
+ return n;
454
+ }
455
+ /**
456
+ * Updates an existing row in the relation by its ID.
457
+ *
458
+ * @param id The ID of the row to update.
459
+ * @param update The data to update in the row.
460
+ * @returns The updated row.
461
+ * @throws DatabaseApiError if the update fails.
462
+ */
463
+ async update(t, e) {
464
+ const { data: a } = await this.query.update(e).eq("id", t).select().single().throwOnError();
465
+ return a;
466
+ }
467
+ }
468
+ class M extends F {
469
+ constructor({
470
+ database: t,
471
+ schema: e,
472
+ table: a
473
+ }) {
474
+ super({
475
+ database: t,
476
+ schema: e,
477
+ relation: a
478
+ });
479
+ }
480
+ }
481
+ class R extends F {
482
+ constructor({
483
+ database: t,
484
+ schema: e,
485
+ view: a
486
+ }) {
487
+ super({
488
+ database: t,
489
+ schema: e,
490
+ relation: a
491
+ });
492
+ }
493
+ }
494
+ function J(r) {
495
+ if (r.error)
496
+ throw r.error;
497
+ return o(r.count !== null, "Response does not contain a count. Make sure to set the `count` option in the request."), r;
498
+ }
499
+ class Q {
500
+ supabase;
501
+ constructor({ supabase: t }) {
502
+ this.supabase = t;
503
+ }
504
+ get schema() {
505
+ return this.supabase.schema.bind(this.supabase);
506
+ }
507
+ get rpc() {
508
+ return this.supabase.rpc.bind(this.supabase);
509
+ }
510
+ get from() {
511
+ return this.supabase.from.bind(this.supabase);
512
+ }
513
+ relation(t, e) {
514
+ return new F({
515
+ database: this,
516
+ schema: t,
517
+ relation: e
518
+ });
519
+ }
520
+ table(t, e) {
521
+ return new M({
522
+ database: this,
523
+ schema: t,
524
+ table: e
525
+ });
526
+ }
527
+ view(t, e) {
528
+ return new R({
529
+ database: this,
530
+ schema: t,
531
+ view: e
532
+ });
533
+ }
534
+ }
535
+ function W(r) {
536
+ return {
537
+ id: r.id,
538
+ bucket: o.notNull(r.bucket_id, "bucket_id must not be null"),
539
+ path: o.defined(r.path_tokens?.join("/"), "path_tokens must not be null")
540
+ };
541
+ }
542
+ function B(r) {
543
+ const t = o.notNull(r.metadata, "metadata must not be null");
544
+ return {
545
+ ...W(r),
546
+ metadata: t,
547
+ properties: {
548
+ type: t.mimetype,
549
+ lastModified: new Date(t.lastModified).getTime()
550
+ }
551
+ };
552
+ }
553
+ class X {
554
+ client;
555
+ database;
556
+ constructor({
557
+ client: t,
558
+ database: e
559
+ }) {
560
+ this.client = t, this.database = e;
561
+ }
562
+ get files() {
563
+ return this.database.table("storage", "objects");
564
+ }
565
+ async uploadFile({
566
+ bucket: t,
567
+ path: e,
568
+ file: a,
569
+ overwriteExisting: n = !1
570
+ }) {
571
+ const { data: s, error: i } = await this.client.from(t).upload(
572
+ `${e}/${a.name}`,
573
+ a,
574
+ {
575
+ upsert: n
576
+ }
577
+ );
578
+ if (i)
579
+ throw i;
580
+ return {
581
+ id: s.id,
582
+ bucket: t,
583
+ path: s.path
584
+ };
585
+ }
586
+ async downloadFile(t) {
587
+ const { bucket: e, path: a, properties: n } = "fileId" in t ? await this.getFileStorageInfo(t.fileId) : t, { data: s, error: i } = await this.client.from(e).download(a);
588
+ if (i)
589
+ throw i;
590
+ const [, c] = D(a);
591
+ return new File([s], c, n);
592
+ }
593
+ async deleteFiles(t) {
594
+ const e = "fileIds" in t ? (await this.files.query.select(["bucket_id", "path_tokens"]).containedBy("id", t.fileIds).throwOnError()).data.map(({ bucket_id: s, path_tokens: i }) => ({
595
+ bucket: o.notNull(s, "bucket_id must not be null"),
596
+ paths: o.notNull(i, "path_tokens must not be null").join("/")
597
+ })) : O(t), a = T(
598
+ z(e, (s) => s.bucket)
599
+ ).map(([s, i]) => ({
600
+ bucket: s,
601
+ paths: i.flatMap((c) => c.paths)
602
+ })).filter(({ paths: s }) => s.length > 0);
603
+ return (await Promise.all(a.map(
604
+ async ({ bucket: s, paths: i }) => this.client.from(s).remove(i).then(({ data: c, error: u }) => {
605
+ if (u)
606
+ throw u;
607
+ return c.map((m, w) => ({
608
+ id: o.notNull(m.id, "file id must not be null"),
609
+ bucket: s,
610
+ path: o.defined(i[w])
611
+ }));
612
+ })
613
+ ))).flat();
614
+ }
615
+ async existsFile(t) {
616
+ const { bucket: e, path: a } = "fileId" in t ? await this.getFileStorageInfo(t.fileId) : t, { data: n, error: s } = await this.client.from(e).exists(a);
617
+ if (s)
618
+ throw s;
619
+ return n;
620
+ }
621
+ async assertExistsFile(t) {
622
+ const { bucket: e, path: a } = "fileId" in t ? await this.getFileStorageInfo(t.fileId) : t, { data: n, error: s } = await this.client.from(e).exists(a);
623
+ if (s)
624
+ throw s;
625
+ if (!n)
626
+ throw new E(`File not found in bucket '${e}' at path '${a}'`, { bucket: e, path: a });
627
+ }
628
+ async getFiles({
629
+ bucket: t,
630
+ ...e
631
+ }) {
632
+ const { data: a, error: n } = await this.client.from(t).listV2(e);
633
+ if (n)
634
+ throw n;
635
+ return a;
636
+ }
637
+ async getFileStorageInfo(t) {
638
+ const e = await this.files.get(t, ["bucket_id", "path_tokens", "metadata"]);
639
+ if (!e)
640
+ throw new E(`File with ID ${t} not found`, { fileId: t });
641
+ return B({
642
+ id: t,
643
+ ...e
644
+ });
645
+ }
646
+ async getFileInfo(t) {
647
+ const { bucket: e, path: a } = "fileId" in t ? await this.getFileStorageInfo(t.fileId) : t, { data: n, error: s } = await this.client.from(e).info(a);
648
+ if (s)
649
+ throw s;
650
+ return n;
651
+ }
652
+ async getPublicURL({
653
+ transform: t,
654
+ download: e,
655
+ ...a
656
+ }) {
657
+ const { bucket: n, path: s } = "fileId" in a ? await this.getFileStorageInfo(a.fileId) : a, { data: { publicUrl: i } } = this.client.from(n).getPublicUrl(s, {
658
+ transform: t,
659
+ download: e
660
+ });
661
+ return i;
662
+ }
663
+ }
664
+ export {
665
+ F as DataService,
666
+ Q as DatabaseService,
667
+ E as FileNotFoundError,
668
+ H as Filter,
669
+ v as FilterChainSeparator,
670
+ I as FilterOp,
671
+ Z as LogicalOp,
672
+ G as LogicalOpSeparator,
673
+ q as ParseError,
674
+ $ as PostgrestErrorInterface,
675
+ _ as RecordNotFoundError,
676
+ X as StorageService,
677
+ M as TableDataService,
678
+ k as TracedError,
679
+ R as ViewDataService,
680
+ J as assertCounted,
681
+ O as coerceArray,
682
+ j as encodeFilter,
683
+ x as encodeFilterNode,
684
+ T as entries,
685
+ z as groupBy,
686
+ V as isDatabaseApiError,
687
+ N as negateFilterNode,
688
+ P as negateOp,
689
+ g as parseFilterExpression,
690
+ A as parseFilterExpressionChain,
691
+ p as postgrestExtensions,
692
+ D as splitPath,
693
+ B as toStorageInfo,
694
+ W as toStorageLocation
695
+ };
package/dist/json.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export type Json = string | number | boolean | null | {
2
+ [key: string]: Json | undefined;
3
+ } | Json[];
4
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../lib/json.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,GACnC,IAAI,EAAE,CAAC"}