rads-db 0.1.54 → 0.1.56

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.cjs CHANGED
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const zod = require('zod');
4
3
  const _ = require('lodash');
4
+ const h3 = require('h3');
5
+ const zod = require('zod');
5
6
  const createMerge = require('@fastify/deepmerge');
6
7
  const uuid = require('uuid');
7
8
  const _radsDb = require('_rads-db');
@@ -893,24 +894,71 @@ function createRads(args) {
893
894
  const validators = generateValidators(s);
894
895
  return generateMethods(s, validators, args);
895
896
  }
896
- function getRestRoutes(db, prefix = "/") {
897
+ function getRestRoutes(options) {
898
+ const { db, prefix = "/api/" } = options;
897
899
  const routes = {};
898
900
  const schema2 = db._schema;
901
+ routes[`${prefix}me`] = { GET: async (args, ctx) => ({ userId: ctx?.getUser?.()?.id }) };
902
+ routes[`${prefix}radsTunnel`] = { POST: getRadsTunnelHandler(db) };
903
+ routes[`${prefix}uploadFile`] = { POST: getUploadFileHandler(db) };
899
904
  for (const key in schema2) {
900
905
  const entity = schema2[key];
901
906
  if (!entity.decorators?.entity)
902
907
  continue;
903
908
  routes[`${prefix}${entity.handle}`] = {
904
- POST: (args, ctx) => db[entity.handle].get(args, ctx),
905
- PUT: (args, ctx) => db[entity.handle].put(args?.data, ctx)
909
+ POST: (args, ctx) => db[entity.handle].get(args.body, ctx),
910
+ PUT: (args, ctx) => db[entity.handle].put(args.body?.data, ctx)
906
911
  };
907
912
  routes[`${prefix}${entity.handlePlural}`] = {
908
- POST: (args, ctx) => db[entity.handle].getMany(args, ctx),
909
- PUT: (args, ctx) => db[entity.handle].putMany(args?.data, ctx)
913
+ POST: (args, ctx) => db[entity.handle].getMany(args.body, ctx),
914
+ PUT: (args, ctx) => db[entity.handle].putMany(args.body?.data, ctx)
910
915
  };
911
916
  }
912
917
  return routes;
913
918
  }
919
+ function getUploadFileHandler(db) {
920
+ return async function uploadFileHandler(request, ctx) {
921
+ const { body } = request;
922
+ const blob = getBlobFromDataUrl(body?.blobDataUrl);
923
+ if (!blob)
924
+ throw h3.createError({ statusCode: 400, message: "Malformed request" });
925
+ return await db.uploadFile(
926
+ {
927
+ blob,
928
+ fileName: body.filename || body.fileName,
929
+ containerName: body.containerName
930
+ },
931
+ ctx
932
+ );
933
+ };
934
+ }
935
+ function getRadsTunnelHandler(db) {
936
+ return async function radsTunnelHandler(request, ctx) {
937
+ const { method, entity, args, uploadArgs } = request?.body || {};
938
+ if (method === "uploadFile") {
939
+ const blob = getBlobFromDataUrl(uploadArgs?.blobDataUrl);
940
+ if (!blob)
941
+ throw h3.createError({ statusCode: 400, message: "Malformed request" });
942
+ return db.uploadFile({ blob, ...uploadArgs }, ctx);
943
+ }
944
+ if (!method || !entity)
945
+ throw h3.createError({ statusCode: 400, message: "Malformed request" });
946
+ const handle = db[___default.lowerFirst(entity)];
947
+ if (!handle)
948
+ throw h3.createError({ statusCode: 400, message: "Malformed request" });
949
+ if (!handle[method])
950
+ throw h3.createError({ statusCode: 400, message: "Unknown method" });
951
+ return await handle[method](args, ctx);
952
+ };
953
+ }
954
+ function getBlobFromDataUrl(dataUrl) {
955
+ const [header, b64string] = dataUrl?.split(",");
956
+ const [protocol, format] = header?.split(":");
957
+ const [type, algorithm] = format?.split(";");
958
+ if (protocol !== "data" || algorithm !== "base64" || !b64string)
959
+ throw h3.createError({ statusCode: 400, message: "Malformed request" });
960
+ return new Blob([Buffer.from(b64string, "base64")], { type });
961
+ }
914
962
 
915
963
  exports.computed = computed;
916
964
  exports.createRads = createRads;
package/dist/index.d.ts CHANGED
@@ -158,8 +158,22 @@ interface TypeDefinition {
158
158
  }
159
159
  interface FileUploadDriver {
160
160
  driverName: string;
161
- uploadFile(args: FileUploadArgs): Promise<string>;
161
+ uploadFile(args: FileUploadArgs, ctx?: RadsRequestContext): Promise<{
162
+ url: string;
163
+ }>;
164
+ }
165
+ interface GetRestRoutesOptions {
166
+ /** Instance of RadsDb */
167
+ db: RadsDb;
168
+ /** Prefix to use for generated routes. Defaults to "/api/" */
169
+ prefix?: string;
170
+ }
171
+ interface GetRestRoutesArgs {
172
+ body?: any;
173
+ context: any;
174
+ headers: Record<string, string>;
162
175
  }
176
+ type GetRestRoutesResponse = Record<string, Partial<Record<'POST' | 'PUT' | 'GET' | 'PATCH', (args: GetRestRoutesArgs, ctx?: RadsRequestContext) => Promise<any>>>>;
163
177
  interface FileUploadArgs {
164
178
  blob: Blob;
165
179
  fileName: string;
@@ -243,6 +257,6 @@ declare function precomputed(meta?: ComputedDecoratorArgs): (a: any, b?: ClassFi
243
257
  declare function computed(meta?: ComputedDecoratorArgs): (a: any, b?: ClassFieldDecoratorContext | ClassDecoratorContext) => void;
244
258
 
245
259
  declare function createRads(args?: CreateRadsArgs): RadsDb;
246
- declare function getRestRoutes(db: RadsDb, prefix?: string): Record<string, Record<string, Function>>;
260
+ declare function getRestRoutes(options: GetRestRoutesOptions): GetRestRoutesResponse;
247
261
 
248
- export { Change, ComputedContext, ComputedDecoratorArgs, CreateRadsArgs, DeepPartial, DeepPartialNullable, Driver, DriverConstructor, EntityDecoratorArgs, EntityMethods, FieldDecoratorArgs, FieldDefinition, FileUploadArgs, FileUploadDriver, GenerateClientNormalizedOptions, GenerateClientOptions, GetAggArgs, GetAggArgsAgg, GetAggArgsAny, GetAggResponse, GetArgs, GetArgsAny, GetArgsInclude, GetManyArgs, GetManyArgsAny, GetManyResponse, GetResponse, GetResponseInclude, GetResponseIncludeSelect, GetResponseNoInclude, MinimalDriver, PutArgs, PutEffect, RadsRequestContext, Relation, RestFileUploadDriverOptions, Schema, SchemaValidators, TypeDefinition, UiDecoratorArgs, UiFieldDecoratorArgs, ValidateEntityDecoratorArgs, ValidateFieldDecoratorArgs, ValidateStringDecoratorArgs, computed, createRads, entity, field, getRestRoutes, precomputed, ui, validate };
262
+ export { Change, ComputedContext, ComputedDecoratorArgs, CreateRadsArgs, DeepPartial, DeepPartialNullable, Driver, DriverConstructor, EntityDecoratorArgs, EntityMethods, FieldDecoratorArgs, FieldDefinition, FileUploadArgs, FileUploadDriver, GenerateClientNormalizedOptions, GenerateClientOptions, GetAggArgs, GetAggArgsAgg, GetAggArgsAny, GetAggResponse, GetArgs, GetArgsAny, GetArgsInclude, GetManyArgs, GetManyArgsAny, GetManyResponse, GetResponse, GetResponseInclude, GetResponseIncludeSelect, GetResponseNoInclude, GetRestRoutesArgs, GetRestRoutesOptions, GetRestRoutesResponse, MinimalDriver, PutArgs, PutEffect, RadsRequestContext, Relation, RestFileUploadDriverOptions, Schema, SchemaValidators, TypeDefinition, UiDecoratorArgs, UiFieldDecoratorArgs, ValidateEntityDecoratorArgs, ValidateFieldDecoratorArgs, ValidateStringDecoratorArgs, computed, createRads, entity, field, getRestRoutes, precomputed, ui, validate };
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { z } from 'zod';
2
1
  import _ from 'lodash';
2
+ import { createError } from 'h3';
3
+ import { z } from 'zod';
3
4
  import createMerge from '@fastify/deepmerge';
4
5
  import { v4 } from 'uuid';
5
6
  import { schema } from '_rads-db';
@@ -886,23 +887,70 @@ function createRads(args) {
886
887
  const validators = generateValidators(s);
887
888
  return generateMethods(s, validators, args);
888
889
  }
889
- function getRestRoutes(db, prefix = "/") {
890
+ function getRestRoutes(options) {
891
+ const { db, prefix = "/api/" } = options;
890
892
  const routes = {};
891
893
  const schema2 = db._schema;
894
+ routes[`${prefix}me`] = { GET: async (args, ctx) => ({ userId: ctx?.getUser?.()?.id }) };
895
+ routes[`${prefix}radsTunnel`] = { POST: getRadsTunnelHandler(db) };
896
+ routes[`${prefix}uploadFile`] = { POST: getUploadFileHandler(db) };
892
897
  for (const key in schema2) {
893
898
  const entity = schema2[key];
894
899
  if (!entity.decorators?.entity)
895
900
  continue;
896
901
  routes[`${prefix}${entity.handle}`] = {
897
- POST: (args, ctx) => db[entity.handle].get(args, ctx),
898
- PUT: (args, ctx) => db[entity.handle].put(args?.data, ctx)
902
+ POST: (args, ctx) => db[entity.handle].get(args.body, ctx),
903
+ PUT: (args, ctx) => db[entity.handle].put(args.body?.data, ctx)
899
904
  };
900
905
  routes[`${prefix}${entity.handlePlural}`] = {
901
- POST: (args, ctx) => db[entity.handle].getMany(args, ctx),
902
- PUT: (args, ctx) => db[entity.handle].putMany(args?.data, ctx)
906
+ POST: (args, ctx) => db[entity.handle].getMany(args.body, ctx),
907
+ PUT: (args, ctx) => db[entity.handle].putMany(args.body?.data, ctx)
903
908
  };
904
909
  }
905
910
  return routes;
906
911
  }
912
+ function getUploadFileHandler(db) {
913
+ return async function uploadFileHandler(request, ctx) {
914
+ const { body } = request;
915
+ const blob = getBlobFromDataUrl(body?.blobDataUrl);
916
+ if (!blob)
917
+ throw createError({ statusCode: 400, message: "Malformed request" });
918
+ return await db.uploadFile(
919
+ {
920
+ blob,
921
+ fileName: body.filename || body.fileName,
922
+ containerName: body.containerName
923
+ },
924
+ ctx
925
+ );
926
+ };
927
+ }
928
+ function getRadsTunnelHandler(db) {
929
+ return async function radsTunnelHandler(request, ctx) {
930
+ const { method, entity, args, uploadArgs } = request?.body || {};
931
+ if (method === "uploadFile") {
932
+ const blob = getBlobFromDataUrl(uploadArgs?.blobDataUrl);
933
+ if (!blob)
934
+ throw createError({ statusCode: 400, message: "Malformed request" });
935
+ return db.uploadFile({ blob, ...uploadArgs }, ctx);
936
+ }
937
+ if (!method || !entity)
938
+ throw createError({ statusCode: 400, message: "Malformed request" });
939
+ const handle = db[_.lowerFirst(entity)];
940
+ if (!handle)
941
+ throw createError({ statusCode: 400, message: "Malformed request" });
942
+ if (!handle[method])
943
+ throw createError({ statusCode: 400, message: "Unknown method" });
944
+ return await handle[method](args, ctx);
945
+ };
946
+ }
947
+ function getBlobFromDataUrl(dataUrl) {
948
+ const [header, b64string] = dataUrl?.split(",");
949
+ const [protocol, format] = header?.split(":");
950
+ const [type, algorithm] = format?.split(";");
951
+ if (protocol !== "data" || algorithm !== "base64" || !b64string)
952
+ throw createError({ statusCode: 400, message: "Malformed request" });
953
+ return new Blob([Buffer.from(b64string, "base64")], { type });
954
+ }
907
955
 
908
956
  export { computed, createRads, entity, field, getRestRoutes, precomputed, ui, validate };
@@ -30,7 +30,9 @@ var _default = options => {
30
30
  console.error("Error uploading file to azure storage:");
31
31
  throw e;
32
32
  }
33
- return blobClient.url.split("?")[0];
33
+ return {
34
+ url: blobClient.url.split("?")[0]
35
+ };
34
36
  }
35
37
  };
36
38
  return driver;
@@ -20,7 +20,7 @@ export default (options) => {
20
20
  console.error("Error uploading file to azure storage:");
21
21
  throw e;
22
22
  }
23
- return blobClient.url.split("?")[0];
23
+ return { url: blobClient.url.split("?")[0] };
24
24
  }
25
25
  };
26
26
  return driver;
@@ -12,7 +12,9 @@ var _default = options => {
12
12
  blob
13
13
  } = args;
14
14
  const dataUrl = await blobToDataURL(blob);
15
- return dataUrl;
15
+ return {
16
+ url: dataUrl
17
+ };
16
18
  }
17
19
  };
18
20
  return driver;
@@ -4,7 +4,7 @@ export default (options) => {
4
4
  async uploadFile(args) {
5
5
  const { blob } = args;
6
6
  const dataUrl = await blobToDataURL(blob);
7
- return dataUrl;
7
+ return { url: dataUrl };
8
8
  }
9
9
  };
10
10
  return driver;
@@ -20,7 +20,7 @@ var _default = options => {
20
20
  method: "POST",
21
21
  body
22
22
  });
23
- return response.text();
23
+ return await response.json();
24
24
  }
25
25
  };
26
26
  return driver;
@@ -11,7 +11,7 @@ export default (options) => {
11
11
  method: "POST",
12
12
  body
13
13
  });
14
- return response.text();
14
+ return await response.json();
15
15
  }
16
16
  };
17
17
  return driver;
package/package.json CHANGED
@@ -34,7 +34,7 @@
34
34
  "require": "./integrations/*.cjs"
35
35
  }
36
36
  },
37
- "version": "0.1.54",
37
+ "version": "0.1.56",
38
38
  "description": "Say goodbye to boilerplate code and hello to efficient and elegant syntax.",
39
39
  "keywords": [],
40
40
  "author": "",