@proteinjs/db 1.22.2 → 1.23.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteinjs/db",
3
- "version": "1.22.2",
3
+ "version": "1.23.0",
4
4
  "main": "./dist/generated/index.js",
5
5
  "types": "./dist/generated/index.d.ts",
6
6
  "exports": {
@@ -65,5 +65,6 @@
65
65
  "jest": "29.7.0",
66
66
  "ts-jest": "29.1.1",
67
67
  "typescript": "5.2.2"
68
- }
68
+ },
69
+ "gitHead": "cbdb41b438edb7c2b509d02827de16cc12e40959"
69
70
  }
package/src/Db.ts CHANGED
@@ -171,6 +171,16 @@ export class Db<R extends Record = Record> implements DbService<R> {
171
171
  }
172
172
 
173
173
  let recordCopy = Object.assign({}, record);
174
+ // Immutable columns can never be rewritten through an update — strip them from the payload
175
+ // (e.g. a ScopedRecord's `scope`: forced on insert; a client-path update rewriting it would
176
+ // reassign the row into another user's scope).
177
+ for (const columnPropertyName in table.columns) {
178
+ const column = (table.columns as any)[columnPropertyName];
179
+ const immutable = column?.options?.immutable;
180
+ if (immutable === true || (typeof immutable === 'function' && immutable(this.runAsSystem))) {
181
+ delete (recordCopy as any)[columnPropertyName];
182
+ }
183
+ }
174
184
  await addUpdateFieldValues(table, recordCopy);
175
185
  const qb = new QueryBuilderFactory().getQueryBuilder(table, query);
176
186
  await this.addColumnQueries(table, qb, 'write');
package/src/Table.ts CHANGED
@@ -161,6 +161,12 @@ export type ColumnOptions = {
161
161
  forceDefaultValue?: boolean | ((runAsSystem: boolean) => boolean);
162
162
  /** Value stored on update */
163
163
  updateValue?: (table: Table<any>, updateObj: any) => Promise<any>;
164
+ /**
165
+ * When active, `Db.update` strips this column from update payloads — the stored value can never
166
+ * be rewritten through an update (e.g. a ScopedRecord's `scope`: forced on insert, and without
167
+ * this a client-path update could reassign a row into another user's scope).
168
+ */
169
+ immutable?: boolean | ((runAsSystem: boolean) => boolean);
164
170
  /** Add conditions to query; called on every query of this table */
165
171
  addToQuery?: (qb: QueryBuilder, runAsSystem: boolean, operation: 'read' | 'write' | 'delete') => Promise<void>;
166
172
  onBeforeInsert?: (insertObj: any & Record, runAsSystem: boolean) => Promise<void>;