@rebasepro/server-postgresql 0.2.5 → 0.4.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.umd.js CHANGED
@@ -2719,166 +2719,6 @@
2719
2719
  };
2720
2720
  }
2721
2721
  }
2722
- const defaultUsersCollection = {
2723
- name: "Users",
2724
- singularName: "User",
2725
- slug: "users",
2726
- table: "users",
2727
- schema: "rebase",
2728
- icon: "Users",
2729
- group: "Settings",
2730
- openEntityMode: "dialog",
2731
- disableDefaultActions: ["copy"],
2732
- sort: ["createdAt", "desc"],
2733
- properties: {
2734
- id: {
2735
- name: "ID",
2736
- type: "string",
2737
- isId: "uuid",
2738
- ui: {
2739
- readOnly: true
2740
- }
2741
- },
2742
- email: {
2743
- name: "Email",
2744
- type: "string",
2745
- validation: {
2746
- required: true,
2747
- unique: true
2748
- }
2749
- },
2750
- displayName: {
2751
- name: "Name",
2752
- type: "string",
2753
- columnName: "display_name",
2754
- validation: {
2755
- required: true
2756
- }
2757
- },
2758
- photoURL: {
2759
- name: "Photo URL",
2760
- type: "string",
2761
- columnName: "photo_url",
2762
- url: "image"
2763
- },
2764
- roles: {
2765
- name: "Roles",
2766
- type: "array",
2767
- columnType: "text[]",
2768
- of: {
2769
- name: "Role",
2770
- type: "string",
2771
- enum: {
2772
- admin: "Admin",
2773
- editor: "Editor",
2774
- viewer: "Viewer"
2775
- }
2776
- }
2777
- },
2778
- passwordHash: {
2779
- name: "Password Hash",
2780
- type: "string",
2781
- columnName: "password_hash",
2782
- ui: {
2783
- hideFromCollection: true,
2784
- disabled: {
2785
- hidden: true
2786
- }
2787
- }
2788
- },
2789
- emailVerified: {
2790
- name: "Email Verified",
2791
- type: "boolean",
2792
- columnName: "email_verified",
2793
- defaultValue: false,
2794
- ui: {
2795
- hideFromCollection: true,
2796
- disabled: {
2797
- hidden: true
2798
- }
2799
- }
2800
- },
2801
- emailVerificationToken: {
2802
- name: "Email Verification Token",
2803
- type: "string",
2804
- columnName: "email_verification_token",
2805
- ui: {
2806
- hideFromCollection: true,
2807
- disabled: {
2808
- hidden: true
2809
- }
2810
- }
2811
- },
2812
- emailVerificationSentAt: {
2813
- name: "Email Verification Sent At",
2814
- type: "date",
2815
- columnName: "email_verification_sent_at",
2816
- ui: {
2817
- hideFromCollection: true,
2818
- disabled: {
2819
- hidden: true
2820
- }
2821
- }
2822
- },
2823
- metadata: {
2824
- name: "Metadata",
2825
- type: "map",
2826
- defaultValue: {},
2827
- ui: {
2828
- hideFromCollection: true,
2829
- disabled: {
2830
- hidden: true
2831
- }
2832
- }
2833
- },
2834
- createdAt: {
2835
- name: "Created At",
2836
- type: "date",
2837
- columnName: "created_at",
2838
- ui: {
2839
- readOnly: true
2840
- }
2841
- },
2842
- updatedAt: {
2843
- name: "Updated At",
2844
- type: "date",
2845
- columnName: "updated_at",
2846
- autoValue: "on_update",
2847
- ui: {
2848
- hideFromCollection: true,
2849
- disabled: {
2850
- hidden: true
2851
- }
2852
- }
2853
- }
2854
- },
2855
- listProperties: ["displayName", "email", "roles", "createdAt"],
2856
- propertiesOrder: ["id", "email", "displayName", "roles", "createdAt"]
2857
- };
2858
- function mapOperator(op) {
2859
- switch (op) {
2860
- case "==":
2861
- return "eq";
2862
- case "!=":
2863
- return "neq";
2864
- case ">":
2865
- return "gt";
2866
- case ">=":
2867
- return "gte";
2868
- case "<":
2869
- return "lt";
2870
- case "<=":
2871
- return "lte";
2872
- case "array-contains":
2873
- return "cs";
2874
- case "array-contains-any":
2875
- return "csa";
2876
- case "not-in":
2877
- return "nin";
2878
- default:
2879
- return op;
2880
- }
2881
- }
2882
2722
  class QueryBuilder {
2883
2723
  constructor(collection) {
2884
2724
  this.collection = collection;
@@ -2886,23 +2726,30 @@
2886
2726
  params = {
2887
2727
  where: {}
2888
2728
  };
2889
- /**
2890
- * Add a filter condition to your query.
2891
- * @example
2892
- * client.collection('users').where('age', '>=', 18).find()
2893
- */
2894
- where(column, operator, value) {
2729
+ where(columnOrCondition, operator, value) {
2730
+ if (typeof columnOrCondition === "object" && columnOrCondition !== null && "type" in columnOrCondition) {
2731
+ this.params.logical = columnOrCondition;
2732
+ return this;
2733
+ }
2895
2734
  if (!this.params.where) {
2896
2735
  this.params.where = {};
2897
2736
  }
2898
- const mappedOp = mapOperator(operator);
2899
- let formattedValue = value;
2900
- if (Array.isArray(value) && ["in", "nin", "cs", "csa"].includes(mappedOp)) {
2901
- formattedValue = `(${value.join(",")})`;
2902
- } else if (value === null) {
2903
- formattedValue = "null";
2737
+ const column = columnOrCondition;
2738
+ const condition = [operator, value];
2739
+ const existing = this.params.where[column];
2740
+ if (existing === void 0) {
2741
+ this.params.where[column] = condition;
2742
+ } else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {
2743
+ this.params.where[column].push(condition);
2744
+ } else {
2745
+ let firstCondition;
2746
+ if (Array.isArray(existing) && existing.length === 2 && typeof existing[0] === "string") {
2747
+ firstCondition = existing;
2748
+ } else {
2749
+ firstCondition = ["==", existing];
2750
+ }
2751
+ this.params.where[column] = [firstCondition, condition];
2904
2752
  }
2905
- this.params.where[column] = mappedOp === "eq" ? String(formattedValue) : `${mappedOp}.${formattedValue}`;
2906
2753
  return this;
2907
2754
  }
2908
2755
  /**
@@ -3004,10 +2851,13 @@
3004
2851
  filter[field] = ["==", rawValue];
3005
2852
  continue;
3006
2853
  }
3007
- if (Array.isArray(rawValue) && rawValue.length === 2) {
3008
- const [rawOp, val] = rawValue;
3009
- const mappedOp = operatorMap[rawOp] ?? "==";
3010
- filter[field] = [mappedOp, val];
2854
+ if (Array.isArray(rawValue)) {
2855
+ const conditions = Array.isArray(rawValue[0]) ? rawValue : [rawValue];
2856
+ const mappedConditions = conditions.map(([rawOp, val]) => {
2857
+ const mappedOp = operatorMap[rawOp] ?? "==";
2858
+ return [mappedOp, val];
2859
+ });
2860
+ filter[field] = Array.isArray(rawValue[0]) ? mappedConditions : mappedConditions[0];
3011
2861
  continue;
3012
2862
  }
3013
2863
  if (typeof rawValue === "string") {
@@ -3145,8 +2995,12 @@
3145
2995
  });
3146
2996
  } : void 0,
3147
2997
  // Fluent Query Builder
3148
- where(column, operator, value) {
3149
- return new QueryBuilder(accessor).where(column, operator, value);
2998
+ where(columnOrCondition, operator, value) {
2999
+ const builder = new QueryBuilder(accessor);
3000
+ if (typeof columnOrCondition === "object") {
3001
+ return builder.where(columnOrCondition);
3002
+ }
3003
+ return builder.where(columnOrCondition, operator, value);
3150
3004
  },
3151
3005
  orderBy(column, ascending) {
3152
3006
  return new QueryBuilder(accessor).orderBy(column, ascending);
@@ -3197,7 +3051,6 @@
3197
3051
  const conditions = [];
3198
3052
  for (const [field, filterParam] of Object.entries(filter)) {
3199
3053
  if (!filterParam) continue;
3200
- const [op, value] = filterParam;
3201
3054
  let fieldColumn = table[field];
3202
3055
  if (!fieldColumn) {
3203
3056
  const relationKey = `${field}_id`;
@@ -3209,13 +3062,39 @@
3209
3062
  console.warn(`Filtering by field '${field}', but it does not exist in table for collection '${collectionPath}'`);
3210
3063
  continue;
3211
3064
  }
3212
- const condition = this.buildSingleFilterCondition(fieldColumn, op, value);
3213
- if (condition) {
3214
- conditions.push(condition);
3065
+ const paramsList = Array.isArray(filterParam) && filterParam.length > 0 && Array.isArray(filterParam[0]) ? filterParam : [filterParam];
3066
+ for (const [op, value] of paramsList) {
3067
+ const condition = this.buildSingleFilterCondition(fieldColumn, op, value);
3068
+ if (condition) {
3069
+ conditions.push(condition);
3070
+ }
3215
3071
  }
3216
3072
  }
3217
3073
  return conditions;
3218
3074
  }
3075
+ /**
3076
+ * Build logical conditions recursively from LogicalCondition or FilterCondition
3077
+ */
3078
+ static buildLogicalConditions(cond, table, collectionPath) {
3079
+ if ("type" in cond) {
3080
+ const subSQLs = cond.conditions.map((c) => this.buildLogicalConditions(c, table, collectionPath)).filter((sql2) => sql2 !== null);
3081
+ if (subSQLs.length === 0) return null;
3082
+ return (cond.type === "or" ? drizzleOrm.or(...subSQLs) : drizzleOrm.and(...subSQLs)) ?? null;
3083
+ } else {
3084
+ let fieldColumn = table[cond.column];
3085
+ if (!fieldColumn) {
3086
+ const relationKey = `${cond.column}_id`;
3087
+ if (relationKey in table) {
3088
+ fieldColumn = table[relationKey];
3089
+ }
3090
+ }
3091
+ if (!fieldColumn) {
3092
+ console.warn(`Filtering by field '${cond.column}', but it does not exist in table for collection '${collectionPath}'`);
3093
+ return null;
3094
+ }
3095
+ return this.buildSingleFilterCondition(fieldColumn, cond.operator, cond.value);
3096
+ }
3097
+ }
3219
3098
  /**
3220
3099
  * Build a single filter condition for a specific operator and value
3221
3100
  */
@@ -5612,6 +5491,10 @@
5612
5491
  const filterConditions = this.buildFilterConditions(options.filter, table, collectionPath);
5613
5492
  if (filterConditions.length > 0) allConditions.push(...filterConditions);
5614
5493
  }
5494
+ if (options.logical) {
5495
+ const logicalCondition = DrizzleConditionBuilder.buildLogicalConditions(options.logical, table, collectionPath);
5496
+ if (logicalCondition) allConditions.push(logicalCondition);
5497
+ }
5615
5498
  if (options.startAfter) {
5616
5499
  const cursorConditions = this.buildCursorConditions(table, idField, idInfo, options, collectionPath);
5617
5500
  if (cursorConditions.length > 0) allConditions.push(...cursorConditions);
@@ -5783,6 +5666,10 @@
5783
5666
  const filterConditions = this.buildFilterConditions(options.filter, table, collectionPath);
5784
5667
  if (filterConditions.length > 0) allConditions.push(...filterConditions);
5785
5668
  }
5669
+ if (options.logical) {
5670
+ const logicalCondition = DrizzleConditionBuilder.buildLogicalConditions(options.logical, table, collectionPath);
5671
+ if (logicalCondition) allConditions.push(logicalCondition);
5672
+ }
5786
5673
  if (vectorMeta?.filter) {
5787
5674
  allConditions.push(vectorMeta.filter);
5788
5675
  }
@@ -8741,7 +8628,6 @@ ${tableRelations.join(",\n")}
8741
8628
  if (!collections || !Array.isArray(collections)) {
8742
8629
  collections = [];
8743
8630
  }
8744
- collections = Array.from(new Map([defaultUsersCollection, ...collections].map((c) => [c.slug, c])).values());
8745
8631
  collections.sort((a, b) => a.slug.localeCompare(b.slug));
8746
8632
  const schemaContent = await generateSchema(collections);
8747
8633
  if (outputPath) {
@@ -10349,31 +10235,23 @@ ${tableRelations.join(",\n")}
10349
10235
  return collection.relations.map((r) => r.relationName || r.localKey || "").filter(Boolean);
10350
10236
  }
10351
10237
  }
10352
- async function ensureAuthTablesExist(db, registry) {
10238
+ async function ensureAuthTablesExist(db, collection) {
10353
10239
  serverCore.logger.info("🔍 Checking auth tables...");
10354
10240
  try {
10355
- let usersTableName = '"users"';
10241
+ let usersTableName = '"rebase"."users"';
10356
10242
  let userIdType = "TEXT";
10357
- let usersSchema2 = "public";
10358
- if (registry) {
10359
- const usersTable = registry.getTable("users");
10360
- if (usersTable) {
10361
- const {
10362
- getTableName: getTableName2
10363
- } = await import("drizzle-orm");
10364
- usersSchema2 = pgCore.getTableConfig(usersTable).schema || "public";
10365
- usersTableName = usersSchema2 === "public" ? `"${getTableName2(usersTable)}"` : `"${usersSchema2}"."${getTableName2(usersTable)}"`;
10366
- if (usersTable.id) {
10367
- const col = usersTable.id;
10368
- const meta = getColumnMeta(col);
10369
- const columnType = meta.columnType;
10370
- if (columnType === "PgUUID") {
10371
- userIdType = "UUID";
10372
- } else if (columnType === "PgSerial" || columnType === "PgInteger") {
10373
- userIdType = "INTEGER";
10374
- } else if (columnType === "PgBigInt" || columnType === "PgBigSerial") {
10375
- userIdType = "BIGINT";
10376
- }
10243
+ let usersSchema2 = "rebase";
10244
+ if (collection) {
10245
+ const rawTable = "table" in collection && typeof collection.table === "string" ? collection.table : collection.slug;
10246
+ usersSchema2 = "schema" in collection && typeof collection.schema === "string" ? collection.schema : "public";
10247
+ usersTableName = usersSchema2 === "public" ? `"${rawTable}"` : `"${usersSchema2}"."${rawTable}"`;
10248
+ const idProp = collection.properties?.id;
10249
+ if (idProp) {
10250
+ const isId = "isId" in idProp ? idProp.isId : void 0;
10251
+ if (isId === "uuid") {
10252
+ userIdType = "UUID";
10253
+ } else if (isId === "autoincrement") {
10254
+ userIdType = "INTEGER";
10377
10255
  }
10378
10256
  }
10379
10257
  }
@@ -11766,19 +11644,21 @@ ${tableRelations.join(",\n")}
11766
11644
  const internals = driverResult.internals;
11767
11645
  const db = internals.db;
11768
11646
  const registry = internals.registry;
11769
- await ensureAuthTablesExist(db, registry);
11647
+ const authCollection = authConfig.collection;
11648
+ await ensureAuthTablesExist(db, authCollection);
11770
11649
  let emailService;
11771
11650
  if (authConfig.email) {
11772
11651
  emailService = serverCore.createEmailService(authConfig.email);
11773
11652
  }
11774
- const customUsersTable = registry?.getTable("users");
11653
+ const tableName = authCollection ? "table" in authCollection && typeof authCollection.table === "string" ? authCollection.table : authCollection.slug : void 0;
11654
+ const usersTable = tableName ? registry.getTable(tableName) : void 0;
11775
11655
  let usersSchemaName = "rebase";
11776
- if (customUsersTable) {
11777
- usersSchemaName = pgCore.getTableConfig(customUsersTable).schema || "public";
11656
+ if (authCollection && "schema" in authCollection && typeof authCollection.schema === "string") {
11657
+ usersSchemaName = authCollection.schema;
11778
11658
  }
11779
11659
  const authTables = createAuthSchema(usersSchemaName);
11780
- if (customUsersTable) {
11781
- authTables.users = customUsersTable;
11660
+ if (usersTable) {
11661
+ authTables.users = usersTable;
11782
11662
  }
11783
11663
  const userService = new UserService(db, authTables);
11784
11664
  const authRepository = new PostgresAuthRepository(db, authTables);