@supabase/realtime-js 1.1.3 → 1.3.1

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.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/dist/main/RealtimeClient.d.ts +7 -0
  3. package/dist/main/RealtimeClient.d.ts.map +1 -1
  4. package/dist/main/RealtimeClient.js +14 -6
  5. package/dist/main/RealtimeClient.js.map +1 -1
  6. package/dist/main/lib/constants.d.ts +2 -1
  7. package/dist/main/lib/constants.d.ts.map +1 -1
  8. package/dist/main/lib/constants.js +1 -0
  9. package/dist/main/lib/constants.js.map +1 -1
  10. package/dist/main/lib/transformers.d.ts +24 -25
  11. package/dist/main/lib/transformers.d.ts.map +1 -1
  12. package/dist/main/lib/transformers.js +112 -119
  13. package/dist/main/lib/transformers.js.map +1 -1
  14. package/dist/main/lib/version.d.ts +1 -1
  15. package/dist/main/lib/version.js +1 -1
  16. package/dist/module/RealtimeClient.d.ts +7 -0
  17. package/dist/module/RealtimeClient.d.ts.map +1 -1
  18. package/dist/module/RealtimeClient.js +14 -6
  19. package/dist/module/RealtimeClient.js.map +1 -1
  20. package/dist/module/lib/constants.d.ts +2 -1
  21. package/dist/module/lib/constants.d.ts.map +1 -1
  22. package/dist/module/lib/constants.js +1 -0
  23. package/dist/module/lib/constants.js.map +1 -1
  24. package/dist/module/lib/transformers.d.ts +24 -25
  25. package/dist/module/lib/transformers.d.ts.map +1 -1
  26. package/dist/module/lib/transformers.js +111 -118
  27. package/dist/module/lib/transformers.js.map +1 -1
  28. package/dist/module/lib/version.d.ts +1 -1
  29. package/dist/module/lib/version.js +1 -1
  30. package/package.json +1 -1
  31. package/src/RealtimeClient.ts +19 -6
  32. package/src/lib/constants.ts +1 -0
  33. package/src/lib/transformers.ts +132 -133
  34. package/src/lib/version.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supabase/realtime-js",
3
- "version": "1.1.3",
3
+ "version": "1.3.1",
4
4
  "description": "Listen to realtime updates to your PostgreSQL database",
5
5
  "keywords": [
6
6
  "realtime",
@@ -34,6 +34,7 @@ type Message = {
34
34
  const noop = () => {}
35
35
 
36
36
  export default class RealtimeClient {
37
+ accessToken: string | null = null
37
38
  channels: RealtimeSubscription[] = []
38
39
  endPoint: string = ''
39
40
  headers?: { [key: string]: string } = DEFAULT_HEADERS
@@ -317,6 +318,23 @@ export default class RealtimeClient {
317
318
  return this.ref.toString()
318
319
  }
319
320
 
321
+ /**
322
+ * Sets the JWT access token used for channel subscription authorization and Realtime RLS.
323
+ *
324
+ * @param token A JWT string.
325
+ */
326
+ setAuth(token: string | null) {
327
+ this.accessToken = token
328
+
329
+ this.channels.forEach(
330
+ (channel) =>
331
+ channel.joinedOnce &&
332
+ channel.push(CHANNEL_EVENTS.access_token, {
333
+ access_token: token,
334
+ })
335
+ )
336
+ }
337
+
320
338
  private _onConnOpen() {
321
339
  this.log('transport', `connected to ${this.endPointURL()}`)
322
340
  this._flushSendBuffer()
@@ -385,11 +403,6 @@ export default class RealtimeClient {
385
403
  return
386
404
  }
387
405
  this.pendingHeartbeatRef = this.makeRef()
388
- this.push({
389
- topic: 'phoenix',
390
- event: 'heartbeat',
391
- payload: {},
392
- ref: this.pendingHeartbeatRef,
393
- })
406
+ this.setAuth(this.accessToken)
394
407
  }
395
408
  }
@@ -29,6 +29,7 @@ export enum CHANNEL_EVENTS {
29
29
  join = 'phx_join',
30
30
  reply = 'phx_reply',
31
31
  leave = 'phx_leave',
32
+ access_token = 'access_token',
32
33
  }
33
34
 
34
35
  export enum TRANSPORTS {
@@ -23,6 +23,7 @@ export enum PostgresTypes {
23
23
  numeric = 'numeric',
24
24
  oid = 'oid',
25
25
  reltime = 'reltime',
26
+ text = 'text',
26
27
  time = 'time',
27
28
  timestamp = 'timestamp',
28
29
  timestamptz = 'timestamptz',
@@ -31,15 +32,18 @@ export enum PostgresTypes {
31
32
  tstzrange = 'tstzrange',
32
33
  }
33
34
 
34
- type Column = {
35
- flags: string[] // any special flags for the column. eg: ["key"]
35
+ type Columns = {
36
36
  name: string // the column name. eg: "user_id"
37
37
  type: string // the column type. eg: "uuid"
38
- type_modifier: number // the type modifier. eg: 4294967295
39
- }
38
+ flags?: string[] // any special flags for the column. eg: ["key"]
39
+ type_modifier?: number // the type modifier. eg: 4294967295
40
+ }[]
41
+
42
+ type BaseValue = null | string | number | boolean
43
+ type RecordValue = BaseValue | BaseValue[]
40
44
 
41
- type Records = {
42
- [key: string]: string
45
+ type Record = {
46
+ [key: string]: RecordValue
43
47
  }
44
48
 
45
49
  /**
@@ -47,7 +51,7 @@ type Records = {
47
51
  * to its mapped type.
48
52
  *
49
53
  * @param {{name: String, type: String}[]} columns
50
- * @param {Object} records
54
+ * @param {Object} record
51
55
  * @param {Object} options The map of various options that can be applied to the mapper
52
56
  * @param {Array} options.skipTypes The array of types that should not be converted
53
57
  *
@@ -55,17 +59,16 @@ type Records = {
55
59
  * //=>{ first_name: 'Paul', age: 33 }
56
60
  */
57
61
  export const convertChangeData = (
58
- columns: Column[],
59
- records: Records,
62
+ columns: Columns,
63
+ record: Record,
60
64
  options: { skipTypes?: string[] } = {}
61
- ) => {
62
- let result: { [key: string]: any } = {}
63
- let skipTypes =
64
- typeof options.skipTypes !== 'undefined' ? options.skipTypes : []
65
- Object.entries(records).map(([key, value]) => {
66
- result[key] = convertColumn(key, columns, records, skipTypes)
67
- })
68
- return result
65
+ ): Record => {
66
+ const skipTypes = options.skipTypes ?? []
67
+
68
+ return Object.keys(record).reduce((acc, rec_key) => {
69
+ acc[rec_key] = convertColumn(rec_key, columns, record, skipTypes)
70
+ return acc
71
+ }, {} as Record)
69
72
  }
70
73
 
71
74
  /**
@@ -73,7 +76,7 @@ export const convertChangeData = (
73
76
  *
74
77
  * @param {String} columnName The column that you want to convert
75
78
  * @param {{name: String, type: String}[]} columns All of the columns
76
- * @param {Object} records The map of string values
79
+ * @param {Object} record The map of string values
77
80
  * @param {Array} skipTypes An array of types that should not be converted
78
81
  * @return {object} Useless information
79
82
  *
@@ -84,16 +87,19 @@ export const convertChangeData = (
84
87
  */
85
88
  export const convertColumn = (
86
89
  columnName: string,
87
- columns: Column[],
88
- records: Records,
90
+ columns: Columns,
91
+ record: Record,
89
92
  skipTypes: string[]
90
- ): any => {
91
- let column = columns.find((x) => x.name == columnName)
92
- if (!column || skipTypes.includes(column.type)) {
93
- return noop(records[columnName])
94
- } else {
95
- return convertCell(column.type, records[columnName])
93
+ ): RecordValue => {
94
+ const column = columns.find((x) => x.name === columnName)
95
+ const colType = column?.type
96
+ const value = record[columnName]
97
+
98
+ if (colType && !skipTypes.includes(colType)) {
99
+ return convertCell(colType, value)
96
100
  }
101
+
102
+ return noop(value)
97
103
  }
98
104
 
99
105
  /**
@@ -109,131 +115,120 @@ export const convertColumn = (
109
115
  * @example convertCell('_int4', '{1,2,3,4}')
110
116
  * //=> [1,2,3,4]
111
117
  */
112
- export const convertCell = (type: string, stringValue: string) => {
113
- try {
114
- if (stringValue === null) return null
115
-
116
- // if data type is an array
117
- if (type.charAt(0) === '_') {
118
- let arrayValue = type.slice(1, type.length)
119
- return toArray(stringValue, arrayValue)
120
- }
118
+ export const convertCell = (type: string, value: RecordValue): RecordValue => {
119
+ // if data type is an array
120
+ if (type.charAt(0) === '_') {
121
+ const dataType = type.slice(1, type.length)
122
+ return toArray(value, dataType)
123
+ }
121
124
 
122
- // If not null, convert to correct type.
123
- switch (type) {
124
- case PostgresTypes.abstime:
125
- return noop(stringValue) // To allow users to cast it based on Timezone
126
- case PostgresTypes.bool:
127
- return toBoolean(stringValue)
128
- case PostgresTypes.date:
129
- return noop(stringValue) // To allow users to cast it based on Timezone
130
- case PostgresTypes.daterange:
131
- return toDateRange(stringValue)
132
- case PostgresTypes.float4:
133
- return toFloat(stringValue)
134
- case PostgresTypes.float8:
135
- return toFloat(stringValue)
136
- case PostgresTypes.int2:
137
- return toInt(stringValue)
138
- case PostgresTypes.int4:
139
- return toInt(stringValue)
140
- case PostgresTypes.int4range:
141
- return toIntRange(stringValue)
142
- case PostgresTypes.int8:
143
- return toInt(stringValue)
144
- case PostgresTypes.int8range:
145
- return toIntRange(stringValue)
146
- case PostgresTypes.json:
147
- return toJson(stringValue)
148
- case PostgresTypes.jsonb:
149
- return toJson(stringValue)
150
- case PostgresTypes.money:
151
- return toFloat(stringValue)
152
- case PostgresTypes.numeric:
153
- return toFloat(stringValue)
154
- case PostgresTypes.oid:
155
- return toInt(stringValue)
156
- case PostgresTypes.reltime:
157
- return noop(stringValue) // To allow users to cast it based on Timezone
158
- case PostgresTypes.time:
159
- return noop(stringValue) // To allow users to cast it based on Timezone
160
- case PostgresTypes.timestamp:
161
- return toTimestampString(stringValue) // Format to be consistent with PostgREST
162
- case PostgresTypes.timestamptz:
163
- return noop(stringValue) // To allow users to cast it based on Timezone
164
- case PostgresTypes.timetz:
165
- return noop(stringValue) // To allow users to cast it based on Timezone
166
- case PostgresTypes.tsrange:
167
- return toDateRange(stringValue)
168
- case PostgresTypes.tstzrange:
169
- return toDateRange(stringValue)
170
- default:
171
- // All the rest will be returned as strings
172
- return noop(stringValue)
173
- }
174
- } catch (error) {
175
- console.log(
176
- `Could not convert cell of type ${type} and value ${stringValue}`
177
- )
178
- console.log(`This is the error: ${error}`)
179
- return stringValue
125
+ // If not null, convert to correct type.
126
+ switch (type) {
127
+ case PostgresTypes.bool:
128
+ return toBoolean(value)
129
+ case PostgresTypes.float4:
130
+ case PostgresTypes.float8:
131
+ case PostgresTypes.int2:
132
+ case PostgresTypes.int4:
133
+ case PostgresTypes.int8:
134
+ case PostgresTypes.numeric:
135
+ case PostgresTypes.oid:
136
+ return toNumber(value)
137
+ case PostgresTypes.json:
138
+ case PostgresTypes.jsonb:
139
+ return toJson(value)
140
+ case PostgresTypes.timestamp:
141
+ return toTimestampString(value) // Format to be consistent with PostgREST
142
+ case PostgresTypes.abstime: // To allow users to cast it based on Timezone
143
+ case PostgresTypes.date: // To allow users to cast it based on Timezone
144
+ case PostgresTypes.daterange:
145
+ case PostgresTypes.int4range:
146
+ case PostgresTypes.int8range:
147
+ case PostgresTypes.money:
148
+ case PostgresTypes.reltime: // To allow users to cast it based on Timezone
149
+ case PostgresTypes.text:
150
+ case PostgresTypes.time: // To allow users to cast it based on Timezone
151
+ case PostgresTypes.timestamptz: // To allow users to cast it based on Timezone
152
+ case PostgresTypes.timetz: // To allow users to cast it based on Timezone
153
+ case PostgresTypes.tsrange:
154
+ case PostgresTypes.tstzrange:
155
+ return noop(value)
156
+ default:
157
+ // Return the value for remaining types
158
+ return noop(value)
180
159
  }
181
160
  }
182
161
 
183
- const noop = (stringValue: string): string => {
184
- return stringValue
162
+ const noop = (value: RecordValue): RecordValue => {
163
+ return value
185
164
  }
186
- export const toBoolean = (stringValue: string) => {
187
- switch (stringValue) {
165
+ export const toBoolean = (value: RecordValue): RecordValue => {
166
+ switch (value) {
188
167
  case 't':
189
168
  return true
190
169
  case 'f':
191
170
  return false
192
171
  default:
193
- return null
172
+ return value
194
173
  }
195
174
  }
196
- export const toDate = (stringValue: string) => {
197
- return new Date(stringValue)
198
- }
199
- export const toDateRange = (stringValue: string) => {
200
- let arr = JSON.parse(stringValue)
201
- return [new Date(arr[0]), new Date(arr[1])]
202
- }
203
- export const toFloat = (stringValue: string) => {
204
- return parseFloat(stringValue)
205
- }
206
- export const toInt = (stringValue: string) => {
207
- return parseInt(stringValue)
208
- }
209
- export const toIntRange = (stringValue: string) => {
210
- let arr = JSON.parse(stringValue)
211
- return [parseInt(arr[0]), parseInt(arr[1])]
212
- }
213
- export const toJson = (stringValue: string) => {
214
- return JSON.parse(stringValue)
175
+ export const toNumber = (value: RecordValue): RecordValue => {
176
+ if (typeof value === 'string') {
177
+ const parsedValue = parseFloat(value)
178
+ if (!Number.isNaN(parsedValue)) {
179
+ return parsedValue
180
+ }
181
+ }
182
+ return value
183
+ }
184
+ export const toJson = (value: RecordValue): RecordValue => {
185
+ if (typeof value === 'string') {
186
+ try {
187
+ return JSON.parse(value)
188
+ } catch (error) {
189
+ console.log(`JSON parse error: ${error}`)
190
+ return value
191
+ }
192
+ }
193
+ return value
215
194
  }
216
195
 
217
196
  /**
218
197
  * Converts a Postgres Array into a native JS array
219
198
  *
220
- * @example toArray('{1,2,3,4}', 'int4')
221
- * //=> [1,2,3,4]
222
199
  * @example toArray('{}', 'int4')
223
200
  * //=> []
201
+ * @example toArray('{"[2021-01-01,2021-12-31)","(2021-01-01,2021-12-32]"}', 'daterange')
202
+ * //=> ['[2021-01-01,2021-12-31)', '(2021-01-01,2021-12-32]']
203
+ * @example toArray([1,2,3,4], 'int4')
204
+ * //=> [1,2,3,4]
224
205
  */
225
- export const toArray = (stringValue: string, type: string) => {
226
- // this takes off the '{' & '}'
227
- let stringEnriched = stringValue.slice(1, stringValue.length - 1)
228
-
229
- // converts the string into an array
230
- // if string is empty (meaning the array was empty), an empty array will be immediately returned
231
- let stringArray = stringEnriched.length > 0 ? stringEnriched.split(',') : []
232
- let array: any[] = stringArray.map((string) => {
233
- return convertCell(type, string)
234
- })
235
-
236
- return array
206
+ export const toArray = (value: RecordValue, type: string): RecordValue => {
207
+ if (typeof value !== 'string') {
208
+ return value
209
+ }
210
+
211
+ const lastIdx = value.length - 1
212
+ const closeBrace = value[lastIdx]
213
+ const openBrace = value[0]
214
+
215
+ // Confirm value is a Postgres array by checking curly brackets
216
+ if (openBrace === '{' && closeBrace === '}') {
217
+ let arr
218
+ const valTrim = value.slice(1, lastIdx)
219
+
220
+ // TODO: find a better solution to separate Postgres array data
221
+ try {
222
+ arr = JSON.parse('[' + valTrim + ']')
223
+ } catch (_) {
224
+ // WARNING: splitting on comma does not cover all edge cases
225
+ arr = valTrim ? valTrim.split(',') : []
226
+ }
227
+
228
+ return arr.map((val: BaseValue) => convertCell(type, val))
229
+ }
230
+
231
+ return value
237
232
  }
238
233
 
239
234
  /**
@@ -243,6 +238,10 @@ export const toArray = (stringValue: string, type: string) => {
243
238
  * @example toTimestampString('2019-09-10 00:00:00')
244
239
  * //=> '2019-09-10T00:00:00'
245
240
  */
246
- export const toTimestampString = (stringValue: string) => {
247
- return stringValue.replace(' ', 'T')
241
+ export const toTimestampString = (value: RecordValue): RecordValue => {
242
+ if (typeof value === 'string') {
243
+ return value.replace(' ', 'T')
244
+ }
245
+
246
+ return value
248
247
  }
@@ -1,2 +1,2 @@
1
1
  // generated by genversion
2
- export const version = '1.1.3'
2
+ export const version = '1.3.1'