Download node_modules/@supabase/realtime-js/src/lib/transformers.ts from metarm/QMetaRam: direct link, hf CLI and curl.
- Browser
- Download file 7.91 kB
-
https://huggingface.co/metarm/QMetaRam/resolve/main/node_modules/%40supabase/realtime-js/src/lib/transformers.ts
- Command line
-
hf download hf://metarm/QMetaRam/node_modules/@supabase/realtime-js/src/lib/transformers.ts
-
curl -L -o transformers.ts https://huggingface.co/metarm/QMetaRam/resolve/main/node_modules/%40supabase/realtime-js/src/lib/transformers.ts
7.91 kB
| /** | |
| * Helpers to convert the change Payload into native JS types. | |
| */ | |
| // Adapted from epgsql (src/epgsql_binary.erl), this module licensed under | |
| // 3-clause BSD found here: https://raw.githubusercontent.com/epgsql/epgsql/devel/LICENSE | |
| export enum PostgresTypes { | |
| abstime = 'abstime', | |
| bool = 'bool', | |
| date = 'date', | |
| daterange = 'daterange', | |
| float4 = 'float4', | |
| float8 = 'float8', | |
| int2 = 'int2', | |
| int4 = 'int4', | |
| int4range = 'int4range', | |
| int8 = 'int8', | |
| int8range = 'int8range', | |
| json = 'json', | |
| jsonb = 'jsonb', | |
| money = 'money', | |
| numeric = 'numeric', | |
| oid = 'oid', | |
| reltime = 'reltime', | |
| text = 'text', | |
| time = 'time', | |
| timestamp = 'timestamp', | |
| timestamptz = 'timestamptz', | |
| timetz = 'timetz', | |
| tsrange = 'tsrange', | |
| tstzrange = 'tstzrange', | |
| } | |
| type Columns = { | |
| name: string // the column name. eg: "user_id" | |
| type: string // the column type. eg: "uuid" | |
| flags?: string[] // any special flags for the column. eg: ["key"] | |
| type_modifier?: number // the type modifier. eg: 4294967295 | |
| }[] | |
| type BaseValue = null | string | number | boolean | |
| type RecordValue = BaseValue | BaseValue[] | |
| type Record = { | |
| [key: string]: RecordValue | |
| } | |
| /** | |
| * Takes an array of columns and an object of string values then converts each string value | |
| * to its mapped type. | |
| * | |
| * @param {{name: String, type: String}[]} columns | |
| * @param {Object} record | |
| * @param {Object} options The map of various options that can be applied to the mapper | |
| * @param {Array} options.skipTypes The array of types that should not be converted | |
| * | |
| * @example convertChangeData([{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age:'33'}, {}) | |
| * //=>{ first_name: 'Paul', age: 33 } | |
| */ | |
| export const convertChangeData = ( | |
| columns: Columns, | |
| record: Record | null, | |
| options: { skipTypes?: string[] } = {} | |
| ): Record => { | |
| const skipTypes = options.skipTypes ?? [] | |
| if (!record) { | |
| return {} | |
| } | |
| return Object.keys(record).reduce((acc, rec_key) => { | |
| acc[rec_key] = convertColumn(rec_key, columns, record, skipTypes) | |
| return acc | |
| }, {} as Record) | |
| } | |
| /** | |
| * Converts the value of an individual column. | |
| * | |
| * @param {String} columnName The column that you want to convert | |
| * @param {{name: String, type: String}[]} columns All of the columns | |
| * @param {Object} record The map of string values | |
| * @param {Array} skipTypes An array of types that should not be converted | |
| * @return {object} Useless information | |
| * | |
| * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, []) | |
| * //=> 33 | |
| * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, ['int4']) | |
| * //=> "33" | |
| */ | |
| export const convertColumn = ( | |
| columnName: string, | |
| columns: Columns, | |
| record: Record, | |
| skipTypes: string[] | |
| ): RecordValue => { | |
| const column = columns.find((x) => x.name === columnName) | |
| const colType = column?.type | |
| const value = record[columnName] | |
| if (colType && !skipTypes.includes(colType)) { | |
| return convertCell(colType, value) | |
| } | |
| return noop(value) | |
| } | |
| /** | |
| * If the value of the cell is `null`, returns null. | |
| * Otherwise converts the string value to the correct type. | |
| * @param {String} type A postgres column type | |
| * @param {String} value The cell value | |
| * | |
| * @example convertCell('bool', 't') | |
| * //=> true | |
| * @example convertCell('int8', '10') | |
| * //=> 10 | |
| * @example convertCell('_int4', '{1,2,3,4}') | |
| * //=> [1,2,3,4] | |
| */ | |
| export const convertCell = (type: string, value: RecordValue): RecordValue => { | |
| // if data type is an array | |
| if (type.charAt(0) === '_') { | |
| const dataType = type.slice(1, type.length) | |
| return toArray(value, dataType) | |
| } | |
| // If not null, convert to correct type. | |
| switch (type) { | |
| case PostgresTypes.bool: | |
| return toBoolean(value) | |
| case PostgresTypes.float4: | |
| case PostgresTypes.float8: | |
| case PostgresTypes.int2: | |
| case PostgresTypes.int4: | |
| case PostgresTypes.int8: | |
| case PostgresTypes.numeric: | |
| case PostgresTypes.oid: | |
| return toNumber(value) | |
| case PostgresTypes.json: | |
| case PostgresTypes.jsonb: | |
| return toJson(value) | |
| case PostgresTypes.timestamp: | |
| return toTimestampString(value) // Format to be consistent with PostgREST | |
| case PostgresTypes.abstime: // To allow users to cast it based on Timezone | |
| case PostgresTypes.date: // To allow users to cast it based on Timezone | |
| case PostgresTypes.daterange: | |
| case PostgresTypes.int4range: | |
| case PostgresTypes.int8range: | |
| case PostgresTypes.money: | |
| case PostgresTypes.reltime: // To allow users to cast it based on Timezone | |
| case PostgresTypes.text: | |
| case PostgresTypes.time: // To allow users to cast it based on Timezone | |
| case PostgresTypes.timestamptz: // To allow users to cast it based on Timezone | |
| case PostgresTypes.timetz: // To allow users to cast it based on Timezone | |
| case PostgresTypes.tsrange: | |
| case PostgresTypes.tstzrange: | |
| return noop(value) | |
| default: | |
| // Return the value for remaining types | |
| return noop(value) | |
| } | |
| } | |
| const noop = (value: RecordValue): RecordValue => { | |
| return value | |
| } | |
| export const toBoolean = (value: RecordValue): RecordValue => { | |
| switch (value) { | |
| case 't': | |
| return true | |
| case 'f': | |
| return false | |
| default: | |
| return value | |
| } | |
| } | |
| export const toNumber = (value: RecordValue): RecordValue => { | |
| if (typeof value === 'string') { | |
| const parsedValue = parseFloat(value) | |
| if (!Number.isNaN(parsedValue)) { | |
| return parsedValue | |
| } | |
| } | |
| return value | |
| } | |
| export const toJson = (value: RecordValue): RecordValue => { | |
| if (typeof value === 'string') { | |
| try { | |
| return JSON.parse(value) | |
| } catch { | |
| return value | |
| } | |
| } | |
| return value | |
| } | |
| /** | |
| * Converts a Postgres Array into a native JS array | |
| * | |
| * @example toArray('{}', 'int4') | |
| * //=> [] | |
| * @example toArray('{"[2021-01-01,2021-12-31)","(2021-01-01,2021-12-32]"}', 'daterange') | |
| * //=> ['[2021-01-01,2021-12-31)', '(2021-01-01,2021-12-32]'] | |
| * @example toArray([1,2,3,4], 'int4') | |
| * //=> [1,2,3,4] | |
| */ | |
| export const toArray = (value: RecordValue, type: string): RecordValue => { | |
| if (typeof value !== 'string') { | |
| return value | |
| } | |
| const lastIdx = value.length - 1 | |
| const closeBrace = value[lastIdx] | |
| const openBrace = value[0] | |
| // Confirm value is a Postgres array by checking curly brackets | |
| if (openBrace === '{' && closeBrace === '}') { | |
| let arr | |
| const valTrim = value.slice(1, lastIdx) | |
| // TODO: find a better solution to separate Postgres array data | |
| try { | |
| arr = JSON.parse('[' + valTrim + ']') | |
| } catch (_) { | |
| // WARNING: splitting on comma does not cover all edge cases | |
| arr = valTrim ? valTrim.split(',') : [] | |
| } | |
| return arr.map((val: BaseValue) => convertCell(type, val)) | |
| } | |
| return value | |
| } | |
| /** | |
| * Fixes timestamp to be ISO-8601. Swaps the space between the date and time for a 'T' | |
| * See https://github.com/supabase/supabase/issues/18 | |
| * | |
| * @example toTimestampString('2019-09-10 00:00:00') | |
| * //=> '2019-09-10T00:00:00' | |
| */ | |
| export const toTimestampString = (value: RecordValue): RecordValue => { | |
| if (typeof value === 'string') { | |
| return value.replace(' ', 'T') | |
| } | |
| return value | |
| } | |
| export const httpEndpointURL = (socketUrl: string): string => { | |
| const wsUrl = new URL(socketUrl) | |
| wsUrl.protocol = wsUrl.protocol.replace(/^ws/i, 'http') | |
| wsUrl.pathname = wsUrl.pathname | |
| .replace(/\/+$/, '') // remove all trailing slashes | |
| .replace(/\/socket\/websocket$/i, '') // remove the socket/websocket path | |
| .replace(/\/socket$/i, '') // remove the socket path | |
| .replace(/\/websocket$/i, '') // remove the websocket path | |
| if (wsUrl.pathname === '' || wsUrl.pathname === '/') { | |
| wsUrl.pathname = '/api/broadcast' | |
| } else { | |
| wsUrl.pathname = wsUrl.pathname + '/api/broadcast' | |
| } | |
| return wsUrl.href | |
| } | |