@rebasepro/common 0.12.0 → 0.12.1-canary.gdfba2a1

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.
@@ -16,3 +16,4 @@ export * from "./auth-default-policies";
16
16
  export * from "./junction-policies";
17
17
  export * from "./conditions";
18
18
  export * from "./pg-column-to-property";
19
+ export * from "./string-column-length";
@@ -0,0 +1,24 @@
1
+ import type { StringProperty } from "@rebasepro/types";
2
+ /**
3
+ * The length a bounded string column is declared with when the property does
4
+ * not say. Historical: it is what the DDL generator hardcoded, kept so that
5
+ * regenerating an existing schema does not silently redefine its columns.
6
+ */
7
+ export declare const DEFAULT_STRING_COLUMN_LENGTH = 255;
8
+ /**
9
+ * How wide a `varchar`/`char` column should be for a given property.
10
+ *
11
+ * One definition, three call sites, because they used to disagree. For the same
12
+ * `columnType: "varchar"` property the DDL generator emitted `VARCHAR(255)`
13
+ * while the Drizzle generator emitted a bare `varchar("col")` — which Postgres
14
+ * reads as *unbounded* — so which of the two you ran decided whether the column
15
+ * had a limit at all. Introspection then dropped the length entirely, so reading
16
+ * an existing `character varying(500)` column back and regenerating it produced
17
+ * a `VARCHAR(255)`: a silent narrowing of a column with data already in it.
18
+ *
19
+ * `validation.max` is the property's own statement about how long the value may
20
+ * be, so it is the only sensible source for the column's width — and it keeps
21
+ * the constraint the database enforces in step with the one the app enforces,
22
+ * rather than inventing a second, different limit underneath it.
23
+ */
24
+ export declare function resolveStringColumnLength(prop: Pick<StringProperty, "validation">): number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/common",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "0.12.1-canary.gdfba2a1",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -38,26 +38,26 @@
38
38
  "./package.json": "./package.json"
39
39
  },
40
40
  "dependencies": {
41
- "fast-equals": "6.0.0",
41
+ "fast-equals": "6.0.2",
42
42
  "json-logic-js": "^2.0.5",
43
- "@rebasepro/types": "0.12.0",
44
- "@rebasepro/utils": "0.12.0"
43
+ "@rebasepro/types": "0.12.1-canary.gdfba2a1",
44
+ "@rebasepro/utils": "0.12.1-canary.gdfba2a1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@jest/globals": "^30.4.1",
48
48
  "@testing-library/react": "^16.3.2",
49
49
  "@testing-library/user-event": "^14.6.1",
50
50
  "@types/jest": "^30.0.0",
51
- "@types/node": "^25.9.3",
51
+ "@types/node": "^26.1.2",
52
52
  "@types/object-hash": "^3.0.6",
53
53
  "@types/react-measure": "^2.0.12",
54
54
  "babel-plugin-react-compiler": "beta",
55
55
  "cross-env": "^10.1.0",
56
56
  "jest": "^30.4.2",
57
- "ts-jest": "^29.4.11",
57
+ "ts-jest": "^29.4.12",
58
58
  "tsd": "^0.33.0",
59
59
  "typescript": "^6.0.3",
60
- "vite": "^8.0.16"
60
+ "vite": "^8.1.5"
61
61
  },
62
62
  "files": [
63
63
  "dist",
package/src/util/index.ts CHANGED
@@ -16,3 +16,4 @@ export * from "./auth-default-policies";
16
16
  export * from "./junction-policies";
17
17
  export * from "./conditions";
18
18
  export * from "./pg-column-to-property";
19
+ export * from "./string-column-length";
@@ -42,6 +42,7 @@ function pgTypeToRebaseProperty(column: TableColumnInfo): Property | null {
42
42
  udt_name,
43
43
  is_nullable,
44
44
  column_default,
45
+ character_maximum_length,
45
46
  enum_values
46
47
  } = column;
47
48
 
@@ -78,11 +79,23 @@ label: prettifyIdentifier(v) })),
78
79
  let colType: "varchar" | "text" | "char" = "varchar";
79
80
  if (dt === "text" || dt === "citext") colType = "text";
80
81
  if (dt === "char" || dt === "character") colType = "char";
82
+ // Carry the declared width across. Dropping it made introspection
83
+ // lossy in the one direction that costs data: a `character
84
+ // varying(500)` column read back as a bare `varchar` regenerates as
85
+ // `VARCHAR(255)`, narrowing a column that already holds longer
86
+ // values. TEXT has no width, and reporting one would invent a limit
87
+ // the database does not have.
88
+ const declaredLength = colType === "text" ? null : character_maximum_length;
81
89
  const prop: StringProperty = {
82
90
  type: "string",
83
91
  name: prettifiedName,
84
92
  columnType: colType,
85
- validation: required ? { required: true } : undefined
93
+ validation: required || declaredLength
94
+ ? {
95
+ ...(required ? { required: true } : {}),
96
+ ...(declaredLength ? { max: declaredLength } : {})
97
+ }
98
+ : undefined
86
99
  };
87
100
  if (isAutoId) {
88
101
  prop.isId = "manual";
@@ -0,0 +1,31 @@
1
+ import type { StringProperty } from "@rebasepro/types";
2
+
3
+ /**
4
+ * The length a bounded string column is declared with when the property does
5
+ * not say. Historical: it is what the DDL generator hardcoded, kept so that
6
+ * regenerating an existing schema does not silently redefine its columns.
7
+ */
8
+ export const DEFAULT_STRING_COLUMN_LENGTH = 255;
9
+
10
+ /**
11
+ * How wide a `varchar`/`char` column should be for a given property.
12
+ *
13
+ * One definition, three call sites, because they used to disagree. For the same
14
+ * `columnType: "varchar"` property the DDL generator emitted `VARCHAR(255)`
15
+ * while the Drizzle generator emitted a bare `varchar("col")` — which Postgres
16
+ * reads as *unbounded* — so which of the two you ran decided whether the column
17
+ * had a limit at all. Introspection then dropped the length entirely, so reading
18
+ * an existing `character varying(500)` column back and regenerating it produced
19
+ * a `VARCHAR(255)`: a silent narrowing of a column with data already in it.
20
+ *
21
+ * `validation.max` is the property's own statement about how long the value may
22
+ * be, so it is the only sensible source for the column's width — and it keeps
23
+ * the constraint the database enforces in step with the one the app enforces,
24
+ * rather than inventing a second, different limit underneath it.
25
+ */
26
+ export function resolveStringColumnLength(prop: Pick<StringProperty, "validation">): number {
27
+ const max = prop.validation?.max;
28
+ return typeof max === "number" && Number.isInteger(max) && max > 0
29
+ ? max
30
+ : DEFAULT_STRING_COLUMN_LENGTH;
31
+ }