@rebasepro/common 0.11.1-canary.gfadf355 → 0.12.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.es.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ANONYMOUS_USER_ID, CANONICAL_TO_REST, DEFAULT_DATA_SOURCE_KEY, EntityReference, EntityRelation, NULL_OPS, REST_TO_CANONICAL, getDataSourceCapabilities, getDeclaredSubcollections, isManyToMany, isPostgresCollectionConfig, policy, toCanonicalOp } from "@rebasepro/types";
2
- import { deepClone, generateForeignKeyName, getIn, getPolicyOperations, isDefaultFieldConfigId, mergeDeep, randomString, removeFunctions, toSnakeCase } from "@rebasepro/utils";
1
+ import { ANONYMOUS_USER_ID, CANONICAL_TO_REST, DEFAULT_DATA_SOURCE_KEY, EntityReference, EntityRelation, NULL_OPS, REST_TO_CANONICAL, getDataSourceCapabilities, getDeclaredSubcollections, isManyToMany, isPostgresCollectionConfig, isRelationalCollectionConfig, policy, toCanonicalOp } from "@rebasepro/types";
2
+ import { deepClone, generateForeignKeyName, getIn, getPolicyOperations, isDefaultFieldConfigId, mergeDeep, prettifyIdentifier, randomString, removeFunctions, toSnakeCase } from "@rebasepro/utils";
3
3
  import jsonLogic from "json-logic-js";
4
4
  import { deepEqual } from "fast-equals";
5
5
  //#region src/util/common.ts
@@ -494,7 +494,7 @@ var _resolvedRelationsCache = /* @__PURE__ */ new WeakMap();
494
494
  function resolveCollectionRelations(collection) {
495
495
  const cached = _resolvedRelationsCache.get(collection);
496
496
  if (cached) return cached;
497
- if (!getDataSourceCapabilities(collection.engine).supportsRelations) return {};
497
+ if (!isRelationalCollectionConfig(collection)) return {};
498
498
  const relations = {};
499
499
  for (const relation of collection.relations ?? []) {
500
500
  const resolved = resolveRelation(relation, collection);
@@ -510,7 +510,7 @@ function resolveCollectionRelations(collection) {
510
510
  return relations;
511
511
  }
512
512
  function getTableName(collection) {
513
- if (getDataSourceCapabilities(collection.engine).supportsRelations) return collection.table ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
513
+ if (isRelationalCollectionConfig(collection)) return collection.table ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
514
514
  return toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
515
515
  }
516
516
  function getTableVarName(tableName) {
@@ -1606,8 +1606,8 @@ function getIdPropertyName$1(collection) {
1606
1606
  * Collections that opt out via `disableDefaultPolicies` are returned unchanged.
1607
1607
  */
1608
1608
  function getEffectiveSecurityRules(collection) {
1609
- const explicit = [...(isPostgresCollectionConfig(collection) ? collection.securityRules : void 0) ?? []];
1610
- if (collection.disableDefaultPolicies) return explicit;
1609
+ const explicit = [...collection.securityRules ?? []];
1610
+ if (isPostgresCollectionConfig(collection) && collection.disableDefaultPolicies) return explicit;
1611
1611
  const tableName = getTableName(collection);
1612
1612
  const injected = [];
1613
1613
  injected.push({
@@ -1649,8 +1649,8 @@ function getEffectiveSecurityRules(collection) {
1649
1649
  * DDL, which policies are injected and how to take them off.
1650
1650
  */
1651
1651
  function getInjectedSecurityRules(collection) {
1652
- if (collection.disableDefaultPolicies) return [];
1653
- const explicitCount = ((isPostgresCollectionConfig(collection) ? collection.securityRules : void 0) ?? []).length;
1652
+ if (isPostgresCollectionConfig(collection) && collection.disableDefaultPolicies) return [];
1653
+ const explicitCount = (collection.securityRules ?? []).length;
1654
1654
  return getEffectiveSecurityRules(collection).slice(explicitCount);
1655
1655
  }
1656
1656
  //#endregion
@@ -1794,7 +1794,7 @@ function coversUpdate(rule) {
1794
1794
  * stays locked (RLS is still enabled) until they write policies for it.
1795
1795
  */
1796
1796
  function getJunctionSecurityRules(spec) {
1797
- if (spec.declaringSides.every((side) => side.collection.disableDefaultPolicies)) return [];
1797
+ if (spec.declaringSides.every((side) => isPostgresCollectionConfig(side.collection) && side.collection.disableDefaultPolicies)) return [];
1798
1798
  const rules = [];
1799
1799
  rules.push({
1800
1800
  name: `${spec.table}_default_admin_read`,
@@ -1947,6 +1947,243 @@ function buildConditionContext(params) {
1947
1947
  * Apply PropertyConditions to a resolved property, evaluating all JSON Logic rules.
1948
1948
  */
1949
1949
  //#endregion
1950
+ //#region src/util/pg-column-to-property.ts
1951
+ /**
1952
+ * Maps a PostgreSQL column data type to a Rebase property type.
1953
+ */
1954
+ function pgTypeToRebaseProperty(column) {
1955
+ const { column_name, data_type, udt_name, is_nullable, column_default, enum_values } = column;
1956
+ const required = is_nullable === "NO";
1957
+ const prettifiedName = prettifyIdentifier(column_name);
1958
+ const isAutoId = column_default != null && (column_default.includes("nextval") || column_default.includes("gen_random_uuid") || column_default.includes("uuid_generate") || column_default.includes("identity"));
1959
+ if (data_type === "USER-DEFINED" && enum_values && enum_values.length > 0) return {
1960
+ type: "string",
1961
+ name: prettifiedName,
1962
+ enum: enum_values.map((v) => ({
1963
+ id: v,
1964
+ label: prettifyIdentifier(v)
1965
+ })),
1966
+ validation: required ? { required: true } : void 0
1967
+ };
1968
+ const dt = data_type.toLowerCase();
1969
+ switch (dt) {
1970
+ case "character varying":
1971
+ case "varchar":
1972
+ case "text":
1973
+ case "char":
1974
+ case "character":
1975
+ case "citext": {
1976
+ let colType = "varchar";
1977
+ if (dt === "text" || dt === "citext") colType = "text";
1978
+ if (dt === "char" || dt === "character") colType = "char";
1979
+ const prop = {
1980
+ type: "string",
1981
+ name: prettifiedName,
1982
+ columnType: colType,
1983
+ validation: required ? { required: true } : void 0
1984
+ };
1985
+ if (isAutoId) prop.isId = "manual";
1986
+ return prop;
1987
+ }
1988
+ case "uuid": {
1989
+ const prop = {
1990
+ type: "string",
1991
+ name: prettifiedName,
1992
+ validation: required ? { required: true } : void 0
1993
+ };
1994
+ if (isAutoId) prop.isId = "uuid";
1995
+ return prop;
1996
+ }
1997
+ case "integer":
1998
+ case "bigint":
1999
+ case "smallint": {
2000
+ const prop = {
2001
+ type: "number",
2002
+ name: prettifiedName,
2003
+ columnType: dt === "bigint" ? "bigint" : "integer",
2004
+ validation: {
2005
+ ...required ? { required: true } : {},
2006
+ integer: true
2007
+ }
2008
+ };
2009
+ if (isAutoId) prop.isId = "increment";
2010
+ return prop;
2011
+ }
2012
+ case "serial":
2013
+ case "bigserial":
2014
+ case "smallserial": return {
2015
+ type: "number",
2016
+ name: prettifiedName,
2017
+ columnType: dt === "bigserial" ? "bigserial" : "serial",
2018
+ isId: "increment",
2019
+ validation: {
2020
+ ...required ? { required: true } : {},
2021
+ integer: true
2022
+ }
2023
+ };
2024
+ case "numeric":
2025
+ case "decimal":
2026
+ case "real":
2027
+ case "double precision": {
2028
+ let colType = "numeric";
2029
+ if (dt === "real") colType = "real";
2030
+ if (dt === "double precision") colType = "double precision";
2031
+ return {
2032
+ type: "number",
2033
+ name: prettifiedName,
2034
+ columnType: colType,
2035
+ validation: required ? { required: true } : void 0
2036
+ };
2037
+ }
2038
+ case "boolean": return {
2039
+ type: "boolean",
2040
+ name: prettifiedName,
2041
+ validation: required ? { required: true } : void 0
2042
+ };
2043
+ case "timestamp with time zone":
2044
+ case "timestamp without time zone":
2045
+ case "timestamp":
2046
+ case "timestamptz":
2047
+ case "date":
2048
+ case "time with time zone":
2049
+ case "time without time zone":
2050
+ case "time": {
2051
+ let colType = "timestamp";
2052
+ if (dt.startsWith("date")) colType = "date";
2053
+ if (dt.startsWith("time ") || dt === "time") colType = "time";
2054
+ return {
2055
+ type: "date",
2056
+ name: prettifiedName,
2057
+ columnType: colType,
2058
+ validation: required ? { required: true } : void 0
2059
+ };
2060
+ }
2061
+ case "jsonb":
2062
+ case "json": return {
2063
+ type: "map",
2064
+ name: prettifiedName,
2065
+ columnType: dt === "jsonb" ? "jsonb" : "json",
2066
+ keyValue: true,
2067
+ properties: {}
2068
+ };
2069
+ case "array":
2070
+ case "ARRAY": {
2071
+ let innerType = "string";
2072
+ let colType = void 0;
2073
+ if (udt_name === "_text" || udt_name === "_varchar") {
2074
+ innerType = "string";
2075
+ colType = "text[]";
2076
+ } else if (udt_name === "_int4" || udt_name === "_int2" || udt_name === "_int8") {
2077
+ innerType = "number";
2078
+ colType = "integer[]";
2079
+ } else if (udt_name === "_bool") {
2080
+ innerType = "boolean";
2081
+ colType = "boolean[]";
2082
+ } else if (udt_name === "_numeric") {
2083
+ innerType = "number";
2084
+ colType = "numeric[]";
2085
+ }
2086
+ return {
2087
+ type: "array",
2088
+ name: prettifiedName,
2089
+ columnType: colType,
2090
+ of: { type: innerType }
2091
+ };
2092
+ }
2093
+ default: return {
2094
+ type: "string",
2095
+ name: prettifiedName,
2096
+ validation: required ? { required: true } : void 0
2097
+ };
2098
+ }
2099
+ }
2100
+ /**
2101
+ * Builds a collection description from PostgreSQL table metadata.
2102
+ * This is used when creating a new collection from an existing database table.
2103
+ */
2104
+ function buildCollectionFromTableMetadata(tableName, metadata) {
2105
+ const properties = {};
2106
+ const propertiesOrder = [];
2107
+ const relations = [];
2108
+ const securityRules = [];
2109
+ for (const column of metadata.columns) {
2110
+ const property = pgTypeToRebaseProperty(column);
2111
+ if (property) {
2112
+ const propRecord = property;
2113
+ Object.keys(propRecord).forEach((key) => propRecord[key] === void 0 && delete propRecord[key]);
2114
+ properties[column.column_name] = property;
2115
+ propertiesOrder.push(column.column_name);
2116
+ }
2117
+ }
2118
+ if (metadata.foreignKeys) for (const fk of metadata.foreignKeys) {
2119
+ const relName = fk.column_name.endsWith("_id") ? fk.column_name.substring(0, fk.column_name.length - 3) : fk.column_name;
2120
+ relations.push({
2121
+ id: fk.column_name,
2122
+ relationName: relName,
2123
+ target: fk.foreign_table_name,
2124
+ kind: "belongsTo",
2125
+ localKey: fk.column_name
2126
+ });
2127
+ }
2128
+ if (metadata.junctions) for (const junction of metadata.junctions) {
2129
+ const relName = junction.target_table_name;
2130
+ relations.push({
2131
+ id: junction.target_table_name + "_relation",
2132
+ relationName: relName,
2133
+ target: junction.target_table_name,
2134
+ kind: "manyToMany",
2135
+ through: {
2136
+ table: junction.junction_table_name,
2137
+ sourceColumn: junction.source_column_name,
2138
+ targetColumn: junction.target_column_name
2139
+ }
2140
+ });
2141
+ }
2142
+ if (metadata.policies) for (const policy of metadata.policies) {
2143
+ let operations = [];
2144
+ switch (policy.cmd) {
2145
+ case "ALL":
2146
+ operations = ["all"];
2147
+ break;
2148
+ case "SELECT":
2149
+ operations = ["select"];
2150
+ break;
2151
+ case "INSERT":
2152
+ operations = ["insert"];
2153
+ break;
2154
+ case "UPDATE":
2155
+ operations = ["update"];
2156
+ break;
2157
+ case "DELETE":
2158
+ operations = ["delete"];
2159
+ break;
2160
+ }
2161
+ const qual = policy.qual ?? void 0;
2162
+ const withCheck = policy.with_check ?? void 0;
2163
+ if (qual) securityRules.push({
2164
+ name: policy.policy_name,
2165
+ operations,
2166
+ roles: policy.roles ?? [],
2167
+ using: qual,
2168
+ ...withCheck ? { withCheck } : {}
2169
+ });
2170
+ else securityRules.push({
2171
+ name: policy.policy_name,
2172
+ operations,
2173
+ roles: policy.roles ?? []
2174
+ });
2175
+ }
2176
+ return {
2177
+ name: prettifyIdentifier(tableName),
2178
+ slug: tableName,
2179
+ table: tableName,
2180
+ properties,
2181
+ propertiesOrder,
2182
+ ...relations.length > 0 ? { relations } : {},
2183
+ ...securityRules.length > 0 ? { securityRules } : {}
2184
+ };
2185
+ }
2186
+ //#endregion
1950
2187
  //#region src/data/resolveDataSource.ts
1951
2188
  /**
1952
2189
  * Build a keyed registry from a list of {@link DataSourceDefinition}s.
@@ -3536,6 +3773,6 @@ async function detectJunctionTables(executeSql) {
3536
3773
  return junctionTables;
3537
3774
  }
3538
3775
  //#endregion
3539
- export { COLLECTION_PATH_SEPARATOR, COMPOSITE_ID_SEPARATOR, CollectionRegistry, DEFAULT_FIND_ALL_MAX_ROWS, DEFAULT_MAX_PAGES, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, DEFAULT_PAGE_SIZE, JUNCTION_TABLES_SQL, QueryBuilder, REBASE_INTERNAL_PREFIXES, REBASE_INTERNAL_SCHEMAS, RebasePaginationError, and, buildCollection, buildCompositeId, buildConditionContext, buildProperty, buildPropertyCallbacks, buildRebaseData, buildRoutedRebaseData, buildSdkData, canCreateEntity, canDeleteEntity, canEditEntity, canReadCollection, checkOperation, classifyTable, collectAllPages, cond, createDataSourceRegistry, createPaginationHelpers, createRelationRef, createRelationRefWithData, defaultUsersCollection, defineCollection, deserializeFilter, deserializeLogicalCondition, deserializeOrderBy, detectJunctionTables, embedParentExpression, enumToObjectEntries, evaluateCondition, evaluatePolicy, findAnonymousGrants, findRelation, fullPathToCollectionSegments, getArrayResolvedProperties, getColumnName, getDeclaredPrimaryKeys, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEffectiveSecurityRules, getEntityChildViews, getEnumVarName, getInjectedSecurityRules, getJunctionCollectionConfig, getJunctionSecurityRules, getLabelOrConfigFrom, getPrimaryKeys, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, getTableVarName, isJunctionBackedRelation, isPropertyBuilder, isRebaseInternalTable, normalizeToEntityRelation, or, paginateFind, parseIdValues, policyToPostgres, registerConditionOperations, resolveArrayProperties, resolveCollectionRelations, resolveDataSource, resolveEnumValues, resolveJunctionSpecs, resolvePrimaryKeys, resolveProperties, resolveProperty, resolvePropertyEnum, resolveRelation, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource, sanitizeData, securityRuleToConditions, segmentsToStrippedPath, serializeFilter, serializeLogicalCondition, serializeOrderBy, sortProperties, sqlToPolicy, stripCollectionPath, traverseValueProperty, traverseValuesProperties, updateDateAutoValues, wrapAsEntityData, wrapAsSdkData };
3776
+ export { COLLECTION_PATH_SEPARATOR, COMPOSITE_ID_SEPARATOR, CollectionRegistry, DEFAULT_FIND_ALL_MAX_ROWS, DEFAULT_MAX_PAGES, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, DEFAULT_PAGE_SIZE, JUNCTION_TABLES_SQL, QueryBuilder, REBASE_INTERNAL_PREFIXES, REBASE_INTERNAL_SCHEMAS, RebasePaginationError, and, buildCollection, buildCollectionFromTableMetadata, buildCompositeId, buildConditionContext, buildProperty, buildPropertyCallbacks, buildRebaseData, buildRoutedRebaseData, buildSdkData, canCreateEntity, canDeleteEntity, canEditEntity, canReadCollection, checkOperation, classifyTable, collectAllPages, cond, createDataSourceRegistry, createPaginationHelpers, createRelationRef, createRelationRefWithData, defaultUsersCollection, defineCollection, deserializeFilter, deserializeLogicalCondition, deserializeOrderBy, detectJunctionTables, embedParentExpression, enumToObjectEntries, evaluateCondition, evaluatePolicy, findAnonymousGrants, findRelation, fullPathToCollectionSegments, getArrayResolvedProperties, getColumnName, getDeclaredPrimaryKeys, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEffectiveSecurityRules, getEntityChildViews, getEnumVarName, getInjectedSecurityRules, getJunctionCollectionConfig, getJunctionSecurityRules, getLabelOrConfigFrom, getPrimaryKeys, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, getTableVarName, isJunctionBackedRelation, isPropertyBuilder, isRebaseInternalTable, normalizeToEntityRelation, or, paginateFind, parseIdValues, policyToPostgres, registerConditionOperations, resolveArrayProperties, resolveCollectionRelations, resolveDataSource, resolveEnumValues, resolveJunctionSpecs, resolvePrimaryKeys, resolveProperties, resolveProperty, resolvePropertyEnum, resolveRelation, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource, sanitizeData, securityRuleToConditions, segmentsToStrippedPath, serializeFilter, serializeLogicalCondition, serializeOrderBy, sortProperties, sqlToPolicy, stripCollectionPath, traverseValueProperty, traverseValuesProperties, updateDateAutoValues, wrapAsEntityData, wrapAsSdkData };
3540
3777
 
3541
3778
  //# sourceMappingURL=index.es.js.map