Initial commit
This commit is contained in:
3
node_modules/postgres-date/index.d.ts
generated
vendored
Normal file
3
node_modules/postgres-date/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
declare function parseDate(isoDate: string): Date | number | null
|
||||
declare function parseDate(isoDate: null | undefined): null
|
||||
export default parseDate
|
||||
308
node_modules/postgres-date/index.js
generated
vendored
Normal file
308
node_modules/postgres-date/index.js
generated
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
'use strict'
|
||||
|
||||
const CHAR_CODE_0 = '0'.charCodeAt(0)
|
||||
const CHAR_CODE_9 = '9'.charCodeAt(0)
|
||||
const CHAR_CODE_DASH = '-'.charCodeAt(0)
|
||||
const CHAR_CODE_COLON = ':'.charCodeAt(0)
|
||||
const CHAR_CODE_SPACE = ' '.charCodeAt(0)
|
||||
const CHAR_CODE_DOT = '.'.charCodeAt(0)
|
||||
const CHAR_CODE_Z = 'Z'.charCodeAt(0)
|
||||
const CHAR_CODE_MINUS = '-'.charCodeAt(0)
|
||||
const CHAR_CODE_PLUS = '+'.charCodeAt(0)
|
||||
|
||||
class PGDateParser {
|
||||
constructor (dateString) {
|
||||
this.dateString = dateString
|
||||
this.pos = 0
|
||||
this.stringLen = dateString.length
|
||||
}
|
||||
|
||||
isDigit (c) {
|
||||
return c >= CHAR_CODE_0 && c <= CHAR_CODE_9
|
||||
}
|
||||
|
||||
/** read numbers and parse positive integer regex: \d+ */
|
||||
readInteger () {
|
||||
let val = 0
|
||||
const start = this.pos
|
||||
while (this.pos < this.stringLen) {
|
||||
const chr = this.dateString.charCodeAt(this.pos)
|
||||
if (this.isDigit(chr)) {
|
||||
val = val * 10
|
||||
this.pos += 1
|
||||
val += chr - CHAR_CODE_0
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (start === this.pos) {
|
||||
return null
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
/** read exactly 2 numbers and parse positive integer. regex: \d{2} */
|
||||
readInteger2 () {
|
||||
const chr1 = this.dateString.charCodeAt(this.pos)
|
||||
const chr2 = this.dateString.charCodeAt(this.pos + 1)
|
||||
|
||||
if (this.isDigit(chr1) && this.isDigit(chr2)) {
|
||||
this.pos += 2
|
||||
return (chr1 - CHAR_CODE_0) * 10 + (chr2 - CHAR_CODE_0)
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
skipChar (char) {
|
||||
if (this.pos === this.stringLen) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.dateString.charCodeAt(this.pos) === char) {
|
||||
this.pos += 1
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
readBC () {
|
||||
if (this.pos === this.stringLen) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.dateString.slice(this.pos, this.pos + 3) === ' BC') {
|
||||
this.pos += 3
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
checkEnd () {
|
||||
return this.pos === this.stringLen
|
||||
}
|
||||
|
||||
getUTC () {
|
||||
return this.skipChar(CHAR_CODE_Z)
|
||||
}
|
||||
|
||||
readSign () {
|
||||
if (this.pos >= this.stringLen) {
|
||||
return null
|
||||
}
|
||||
|
||||
const char = this.dateString.charCodeAt(this.pos)
|
||||
if (char === CHAR_CODE_PLUS) {
|
||||
this.pos += 1
|
||||
return 1
|
||||
}
|
||||
|
||||
if (char === CHAR_CODE_MINUS) {
|
||||
this.pos += 1
|
||||
return -1
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
getTZOffset () {
|
||||
// special handling for '+00' at the end of - UTC
|
||||
if (this.pos === this.stringLen - 3 && this.dateString.slice(this.pos, this.pos + 3) === '+00') {
|
||||
this.pos += 3
|
||||
return 0
|
||||
}
|
||||
|
||||
if (this.stringLen === this.pos) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const sign = this.readSign()
|
||||
if (sign === null) {
|
||||
if (this.getUTC()) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const hours = this.readInteger2()
|
||||
if (hours === null) {
|
||||
return null
|
||||
}
|
||||
let offset = hours * 3600
|
||||
|
||||
if (!this.skipChar(CHAR_CODE_COLON)) {
|
||||
return offset * sign * 1000
|
||||
}
|
||||
|
||||
const minutes = this.readInteger2()
|
||||
if (minutes === null) {
|
||||
return null
|
||||
}
|
||||
offset += minutes * 60
|
||||
|
||||
if (!this.skipChar(CHAR_CODE_COLON)) {
|
||||
return offset * sign * 1000
|
||||
}
|
||||
|
||||
const seconds = this.readInteger2()
|
||||
if (seconds == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (offset + seconds) * sign * 1000
|
||||
}
|
||||
|
||||
/* read milliseconds out of time fraction, returns 0 if missing, null if format invalid */
|
||||
readMilliseconds () {
|
||||
/* read milliseconds from fraction: .001=1, 0.1 = 100 */
|
||||
if (this.skipChar(CHAR_CODE_DOT)) {
|
||||
let i = 2
|
||||
let val = 0
|
||||
const start = this.pos
|
||||
while (this.pos < this.stringLen) {
|
||||
const chr = this.dateString.charCodeAt(this.pos)
|
||||
if (this.isDigit(chr)) {
|
||||
this.pos += 1
|
||||
if (i >= 0) {
|
||||
val += (chr - CHAR_CODE_0) * 10 ** i
|
||||
}
|
||||
i -= 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (start === this.pos) {
|
||||
return null
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
readDate () {
|
||||
const year = this.readInteger()
|
||||
if (!this.skipChar(CHAR_CODE_DASH)) {
|
||||
return null
|
||||
}
|
||||
|
||||
let month = this.readInteger2()
|
||||
if (!this.skipChar(CHAR_CODE_DASH)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const day = this.readInteger2()
|
||||
if (year === null || month === null || day === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
month = month - 1
|
||||
return { year, month, day }
|
||||
}
|
||||
|
||||
readTime () {
|
||||
if (this.stringLen - this.pos < 9 || !this.skipChar(CHAR_CODE_SPACE)) {
|
||||
return { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }
|
||||
}
|
||||
|
||||
const hours = this.readInteger2()
|
||||
if (hours === null || !this.skipChar(CHAR_CODE_COLON)) {
|
||||
return null
|
||||
}
|
||||
const minutes = this.readInteger2()
|
||||
if (minutes === null || !this.skipChar(CHAR_CODE_COLON)) {
|
||||
return null
|
||||
}
|
||||
const seconds = this.readInteger2()
|
||||
if (seconds === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const milliseconds = this.readMilliseconds()
|
||||
if (milliseconds === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return { hours, minutes, seconds, milliseconds }
|
||||
}
|
||||
|
||||
getJSDate () {
|
||||
const date = this.readDate()
|
||||
if (date === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const time = this.readTime()
|
||||
if (time === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const tzOffset = this.getTZOffset()
|
||||
if (tzOffset === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const isBC = this.readBC()
|
||||
if (isBC) {
|
||||
date.year = -(date.year - 1)
|
||||
}
|
||||
|
||||
if (!this.checkEnd()) {
|
||||
return null
|
||||
}
|
||||
|
||||
let jsDate
|
||||
if (tzOffset !== undefined) {
|
||||
jsDate = new Date(
|
||||
Date.UTC(date.year, date.month, date.day, time.hours, time.minutes, time.seconds, time.milliseconds)
|
||||
)
|
||||
|
||||
if (date.year <= 99 && date.year >= -99) {
|
||||
jsDate.setUTCFullYear(date.year)
|
||||
}
|
||||
|
||||
if (tzOffset !== 0) {
|
||||
jsDate.setTime(jsDate.getTime() - tzOffset)
|
||||
}
|
||||
} else {
|
||||
jsDate = new Date(date.year, date.month, date.day, time.hours, time.minutes, time.seconds, time.milliseconds)
|
||||
if (date.year <= 99 && date.year >= -99) {
|
||||
jsDate.setFullYear(date.year)
|
||||
}
|
||||
}
|
||||
|
||||
return jsDate
|
||||
}
|
||||
|
||||
static parse (dateString) {
|
||||
return new PGDateParser(dateString).getJSDate()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function parseDate (isoDate) {
|
||||
if (isoDate === null || isoDate === undefined) {
|
||||
return null
|
||||
}
|
||||
|
||||
const date = PGDateParser.parse(isoDate)
|
||||
|
||||
// parsing failed, check for infinity
|
||||
if (date === null) {
|
||||
if (isoDate === 'infinity') {
|
||||
return Infinity
|
||||
}
|
||||
|
||||
if (isoDate === '-infinity') {
|
||||
return -Infinity
|
||||
}
|
||||
}
|
||||
|
||||
return date
|
||||
}
|
||||
21
node_modules/postgres-date/license
generated
vendored
Normal file
21
node_modules/postgres-date/license
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Ben Drucker <bvdrucker@gmail.com> (bendrucker.me)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
35
node_modules/postgres-date/package.json
generated
vendored
Normal file
35
node_modules/postgres-date/package.json
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "postgres-date",
|
||||
"main": "index.js",
|
||||
"version": "2.1.0",
|
||||
"description": "Postgres date column parser",
|
||||
"license": "MIT",
|
||||
"repository": "bendrucker/postgres-date",
|
||||
"author": {
|
||||
"name": "Ben Drucker",
|
||||
"email": "bvdrucker@gmail.com",
|
||||
"url": "bendrucker.me"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && tape test.js && tsd"
|
||||
},
|
||||
"keywords": [
|
||||
"postgres",
|
||||
"date",
|
||||
"parser"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"standard": "^16.0.0",
|
||||
"tape": "^5.0.0",
|
||||
"tsd": "^0.19.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"readme.md"
|
||||
]
|
||||
}
|
||||
48
node_modules/postgres-date/readme.md
generated
vendored
Normal file
48
node_modules/postgres-date/readme.md
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# postgres-date [](https://github.com/bendrucker/postgres-date/actions?query=workflow%3Atests)
|
||||
|
||||
> Postgres date output parser
|
||||
|
||||
This package parses [date/time outputs](https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-OUTPUT) from Postgres into Javascript `Date` objects. Its goal is to match Postgres behavior and preserve data accuracy.
|
||||
|
||||
If you find a case where a valid Postgres output results in incorrect parsing (including loss of precision), please [create a pull request](https://github.com/bendrucker/postgres-date/compare) and provide a failing test.
|
||||
|
||||
**Supported Postgres Versions:** `>= 9.6`
|
||||
|
||||
All prior versions of Postgres are likely compatible but not officially supported.
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm install --save postgres-date
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const parse = require('postgres-date')
|
||||
parse('2011-01-23 22:15:51Z')
|
||||
// => 2011-01-23T22:15:51.000Z
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
#### `parse(isoDate)` -> `date`
|
||||
|
||||
##### isoDate
|
||||
|
||||
*Required*
|
||||
Type: `string`
|
||||
|
||||
A date string from Postgres.
|
||||
|
||||
## Releases
|
||||
|
||||
The following semantic versioning increments will be used for changes:
|
||||
|
||||
* **Major**: Removal of support for Node.js versions or Postgres versions (not expected)
|
||||
* **Minor**: Unused, since Postgres returns dates in standard ISO 8601 format
|
||||
* **Patch**: Any fix for parsing behavior
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Ben Drucker](http://bendrucker.me)
|
||||
Reference in New Issue
Block a user