@potonz/shortlinks-manager-postgres 0.3.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/README.md +115 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +112 -0
- package/dist/package.json +37 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# @potonz/shortlinks-manager-postgres
|
|
2
|
+
|
|
3
|
+
PostgreSQL backend for short links manager using [postgres.js](https://github.com/porsager/postgres).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Full PostgreSQL support with prepared statements via postgres.js
|
|
8
|
+
- Automatic table creation and indexing
|
|
9
|
+
- Support for PostgreSQL 14, 15, 16, 17, and 18
|
|
10
|
+
- Type-safe SQL with tagged template literals
|
|
11
|
+
- Efficient parameterized queries
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @potonz/shortlinks-manager-postgres
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createManager } from "@potonz/shortlinks-manager";
|
|
23
|
+
import { createPostgresBackend } from "@potonz/shortlinks-manager-postgres";
|
|
24
|
+
|
|
25
|
+
// Create backend with connection URI
|
|
26
|
+
const backend = createPostgresBackend("postgres://user:password@localhost:5432/shortlinks");
|
|
27
|
+
|
|
28
|
+
// Initialize tables (run once during setup)
|
|
29
|
+
await backend.setupTables();
|
|
30
|
+
|
|
31
|
+
// Create manager
|
|
32
|
+
const manager = await createManager({
|
|
33
|
+
backend,
|
|
34
|
+
shortIdLength: 6,
|
|
35
|
+
onShortIdLengthUpdated: (newLength) => {
|
|
36
|
+
console.log(`Short ID length updated to ${newLength}`);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Create short link
|
|
41
|
+
const shortId = await manager.createShortLink("https://example.com");
|
|
42
|
+
console.log(`Created short link: ${shortId}`);
|
|
43
|
+
|
|
44
|
+
// Resolve short link
|
|
45
|
+
const targetUrl = await manager.getTargetUrl(shortId);
|
|
46
|
+
console.log(`Target URL: ${targetUrl}`);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Database Schema
|
|
50
|
+
|
|
51
|
+
The backend automatically creates the following table:
|
|
52
|
+
|
|
53
|
+
```sql
|
|
54
|
+
CREATE TABLE IF NOT EXISTS sl_links_map (
|
|
55
|
+
short_id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
56
|
+
target_url TEXT NOT NULL,
|
|
57
|
+
last_accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
58
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_sl_links_map_last_accessed_at
|
|
62
|
+
ON sl_links_map(last_accessed_at);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
### `createPostgresBackend(connectionUri: string)`
|
|
68
|
+
|
|
69
|
+
Creates a PostgreSQL backend instance.
|
|
70
|
+
|
|
71
|
+
**Parameters:**
|
|
72
|
+
- `connectionUri` - PostgreSQL connection URI (e.g., `postgres://user:password@localhost:5432/dbname`)
|
|
73
|
+
|
|
74
|
+
**Returns:** `IShortLinksManagerPostgresBackend`
|
|
75
|
+
|
|
76
|
+
### `backend.setupTables()`
|
|
77
|
+
|
|
78
|
+
Creates the required database tables and indexes. Should be called once during application initialization.
|
|
79
|
+
|
|
80
|
+
### Backend Methods
|
|
81
|
+
|
|
82
|
+
Implements all `IShortLinksManagerBackend` methods:
|
|
83
|
+
|
|
84
|
+
- `getTargetUrl(shortId)` - Get target URL by short ID
|
|
85
|
+
- `createShortLink(shortId, targetUrl)` - Create a new short link
|
|
86
|
+
- `checkShortIdsExist(shortIds)` - Check which short IDs already exist
|
|
87
|
+
- `updateShortLinkLastAccessTime(shortId, time)` - Update last accessed timestamp
|
|
88
|
+
- `cleanUnusedLinks(maxAge)` - Remove links not accessed in `maxAge` days
|
|
89
|
+
- `removeShortLink(shortId)` - Remove a short link by ID
|
|
90
|
+
|
|
91
|
+
## Testing
|
|
92
|
+
|
|
93
|
+
Tests run automatically in CI against PostgreSQL versions 14, 15, 16, 17, and 18.
|
|
94
|
+
|
|
95
|
+
To run tests locally:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Start PostgreSQL (using Docker)
|
|
99
|
+
docker run --name shortlinks-postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=shortlinks -p 5432:5432 -d postgres:16
|
|
100
|
+
|
|
101
|
+
# Run tests
|
|
102
|
+
POSTGRES_URI=postgres://postgres:password@localhost:5432/shortlinks bun test packages/shortlinks-manager-postgres
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Supported PostgreSQL Versions
|
|
106
|
+
|
|
107
|
+
- PostgreSQL 14 (until 2026)
|
|
108
|
+
- PostgreSQL 15
|
|
109
|
+
- PostgreSQL 16
|
|
110
|
+
- PostgreSQL 17
|
|
111
|
+
- PostgreSQL 18 (latest)
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
4
|
+
export interface IBaseUrlRecord {
|
|
5
|
+
id: number;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
isActive?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface IShortLinksManagerBackend {
|
|
10
|
+
/**
|
|
11
|
+
* Initialise any logic before the manager can do its thing. E.g. setting up tables.
|
|
12
|
+
* Run once when {@link createManager} is called
|
|
13
|
+
*/
|
|
14
|
+
init?: () => unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Get target URL for the given short ID
|
|
17
|
+
* @param {string} shortId
|
|
18
|
+
* @param {number} baseUrlId optional base URL ID to filter by
|
|
19
|
+
* @returns the target URL or null if not found
|
|
20
|
+
*/
|
|
21
|
+
getTargetUrl(shortId: string, baseUrlId: number | null): string | null | Promise<string | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Create a short link map with the given short ID and target URL
|
|
24
|
+
* @param {string} shortId
|
|
25
|
+
* @param {string} targetUrl
|
|
26
|
+
* @param {number} baseUrlId optional base URL ID
|
|
27
|
+
*/
|
|
28
|
+
createShortLink(shortId: string, targetUrl: string, baseUrlId: number | null): void | Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Check the provided list of short IDs and return the ones that already exist.
|
|
31
|
+
* @param {string[]} shortIds
|
|
32
|
+
* @param {number} baseUrlId optional base URL ID to check within
|
|
33
|
+
*/
|
|
34
|
+
checkShortIdsExist(shortIds: string[], baseUrlId: number | null): string[] | Promise<string[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Update last accessed time to current timestamp
|
|
37
|
+
* @param shortId
|
|
38
|
+
* @param baseUrlId optional base URL ID to filter by
|
|
39
|
+
* @param time Unix timestamp or a Date object
|
|
40
|
+
*/
|
|
41
|
+
updateShortLinkLastAccessTime(shortId: string, baseUrlId: number | null, time?: number | Date): void | Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Remove unused links that are older than the given maxAge
|
|
44
|
+
* @param maxAge number of days the record should be kept
|
|
45
|
+
* @returns an array of objects with shortId and baseUrlId that have been cleaned
|
|
46
|
+
*/
|
|
47
|
+
cleanUnusedLinks(maxAge: number): Array<{
|
|
48
|
+
shortId: string;
|
|
49
|
+
baseUrlId: number | null;
|
|
50
|
+
}> | Promise<Array<{
|
|
51
|
+
shortId: string;
|
|
52
|
+
baseUrlId: number | null;
|
|
53
|
+
}>>;
|
|
54
|
+
/**
|
|
55
|
+
* Remove a short link by its ID
|
|
56
|
+
* @param shortId the short ID to remove
|
|
57
|
+
* @param baseUrlId optional base URL ID to filter by
|
|
58
|
+
*/
|
|
59
|
+
removeShortLink(shortId: string, baseUrlId: number | null): void | Promise<void>;
|
|
60
|
+
baseUrl: {
|
|
61
|
+
/**
|
|
62
|
+
* Add a new base URL
|
|
63
|
+
* @param baseUrl the base URL to add
|
|
64
|
+
*/
|
|
65
|
+
add(baseUrl: string): void | Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Remove a base URL by its ID
|
|
68
|
+
* @param id the ID of the base URL to remove
|
|
69
|
+
*/
|
|
70
|
+
remove(id: number): void | Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* List all base URLs
|
|
73
|
+
* @param includeInactive whether to include inactive base URLs (default: false)
|
|
74
|
+
* @returns array of base URL records
|
|
75
|
+
*/
|
|
76
|
+
list(includeInactive?: boolean): IBaseUrlRecord[] | Promise<IBaseUrlRecord[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the ID for a base URL
|
|
79
|
+
* @param baseUrl the base URL to get the ID for
|
|
80
|
+
* @returns the base URL ID or null if not found
|
|
81
|
+
*/
|
|
82
|
+
getId(baseUrl: string): number | Promise<number>;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export interface IShortLinksManagerPostgresBackend extends IShortLinksManagerBackend {
|
|
86
|
+
setupTables: () => Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Create a PostgreSQL backend for short links manager using postgres.js
|
|
90
|
+
* @param connectionUri PostgreSQL connection URI (e.g., "postgres://user:pass@localhost/dbname")
|
|
91
|
+
* @returns IShortLinksManagerPostgresBackend implementation
|
|
92
|
+
*/
|
|
93
|
+
export declare function createPostgresBackend(connectionUri: string): IShortLinksManagerPostgresBackend;
|
|
94
|
+
declare const _default: {};
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
_default as default,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Thomas Nguyen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
import Af from"os";import $f from"fs";var Ih=new Map,uu=new Map,nu=Symbol("OriginError"),Xh={};class lh extends Promise{constructor(h,n,f,l,w={}){let E,t;super((O,S)=>{E=O,t=S});this.tagged=Array.isArray(h.raw),this.strings=h,this.args=n,this.handler=f,this.canceller=l,this.options=w,this.state=null,this.statement=null,this.resolve=(O)=>(this.active=!1,E(O)),this.reject=(O)=>(this.active=!1,t(O)),this.active=!1,this.cancelled=null,this.executed=!1,this.signature="",this[nu]=this.handler.debug?Error():this.tagged&&mn(this.strings)}get origin(){return(this.handler.debug?this[nu].stack:this.tagged&&uu.has(this.strings)?uu.get(this.strings):uu.set(this.strings,this[nu].stack).get(this.strings))||""}static get[Symbol.species](){return Promise}cancel(){return this.canceller&&(this.canceller(this),this.canceller=null)}simple(){return this.options.simple=!0,this.options.prepare=!1,this}async readable(){return this.simple(),this.streaming=!0,this}async writable(){return this.simple(),this.streaming=!0,this}cursor(h=1,n){if(this.options.simple=!1,typeof h==="function")n=h,h=1;if(this.cursorRows=h,typeof n==="function")return this.cursorFn=n,this;let f;return{[Symbol.asyncIterator]:()=>({next:()=>{if(this.executed&&!this.active)return{done:!0};f&&f();let l=new Promise((w,E)=>{this.cursorFn=(t)=>{return w({value:t,done:!1}),new Promise((O)=>f=O)},this.resolve=()=>(this.active=!1,w({done:!0})),this.reject=(t)=>(this.active=!1,E(t))});return this.execute(),l},return(){return f&&f(Xh),{done:!0}}})}}describe(){return this.options.simple=!1,this.onlyDescribe=this.options.prepare=!0,this}stream(){throw Error(".stream has been renamed to .forEach")}forEach(h){return this.forEachFn=h,this.handle(),this}raw(){return this.isRaw=!0,this}values(){return this.isRaw="values",this}async handle(){!this.executed&&(this.executed=!0)&&await 1&&this.handler(this)}execute(){return this.handle(),this}then(){return this.handle(),super.then.apply(this,arguments)}catch(){return this.handle(),super.catch.apply(this,arguments)}finally(){return this.handle(),super.finally.apply(this,arguments)}}function mn(h){if(Ih.has(h))return Ih.get(h);let n=Error.stackTraceLimit;return Error.stackTraceLimit=4,Ih.set(h,Error()),Error.stackTraceLimit=n,Ih.get(h)}class Rh extends Error{constructor(h){super(h.message);this.name=this.constructor.name,Object.assign(this,h)}}var i={connection:Zu,postgres:Fu,generic:Hu,notSupported:zu};function Zu(h,n,f){let{host:l,port:w}=f||n,E=Object.assign(Error("write "+h+" "+(n.path||l+":"+w)),{code:h,errno:h,address:n.path||l},n.path?{}:{port:w});return Error.captureStackTrace(E,Zu),E}function Fu(h){let n=new Rh(h);return Error.captureStackTrace(n,Fu),n}function Hu(h,n){let f=Object.assign(Error(h+": "+n),{code:h});return Error.captureStackTrace(f,Hu),f}function zu(h){let n=Object.assign(Error(h+" (B) is not supported"),{code:"MESSAGE_NOT_SUPPORTED",name:h});return Error.captureStackTrace(n,zu),n}var bn={string:{to:25,from:null,serialize:(h)=>""+h},number:{to:0,from:[21,23,26,700,701],serialize:(h)=>""+h,parse:(h)=>+h},json:{to:114,from:[114,3802],serialize:(h)=>JSON.stringify(h),parse:(h)=>JSON.parse(h)},boolean:{to:16,from:16,serialize:(h)=>h===!0?"t":"f",parse:(h)=>h==="t"},date:{to:1184,from:[1082,1114,1184],serialize:(h)=>(h instanceof Date?h:new Date(h)).toISOString(),parse:(h)=>new Date(h)},bytea:{to:17,from:17,serialize:(h)=>"\\x"+Buffer.from(h).toString("hex"),parse:(h)=>Buffer.from(h.slice(2),"hex")}};class mh{then(){fu()}catch(){fu()}finally(){fu()}}class Vh extends mh{constructor(h){super();this.value=ah(h)}}class th extends mh{constructor(h,n,f){super();this.value=h,this.type=n,this.array=f}}class bh extends mh{constructor(h,n){super();this.first=h,this.rest=n}build(h,n,f,l){let w=kn.map(([E,t])=>({fn:t,i:h.search(E)})).sort((E,t)=>E.i-t.i).pop();return w.i===-1?Ou(this.first,l):w.fn(this.first,this.rest,n,f,l)}}function kh(h,n,f,l){let w=h instanceof th?h.value:h;if(w===void 0){if(h instanceof th?h.value=l.transform.undefined:w=h=l.transform.undefined,w===void 0)throw i.generic("UNDEFINED_VALUE","Undefined values are not allowed")}return"$"+f.push(h instanceof th?(n.push(h.value),h.array?h.array[h.type||dh(h.value)]||h.type||Vu(h.value):h.type):(n.push(h),dh(h)))}var Cu=Ku(bn);function wu(h,n,f,l,w,E){for(let t=1;t<h.strings.length;t++)n+=tu(n,f,l,w,E)+h.strings[t],f=h.args[t];return n}function tu(h,n,f,l,w){return n instanceof bh?n.build(h,f,l,w):n instanceof lh?cu(n,f,l,w):n instanceof Vh?n.value:n&&n[0]instanceof lh?n.reduce((E,t)=>E+" "+cu(t,f,l,w),""):kh(n,f,l,w)}function cu(h,n,f,l){return h.fragment=!0,wu(h,h.strings[0],h.args[0],n,f,l)}function Qu(h,n,f,l,w){return h.map((E)=>"("+l.map((t)=>tu("values",E[t],n,f,w)).join(",")+")").join(",")}function Ju(h,n,f,l,w){let E=Array.isArray(h[0]),t=n.length?n.flat():Object.keys(E?h[0]:h);return Qu(E?h:[h],f,l,t,w)}function ih(h,n,f,l,w){if(typeof h==="string"&&(h=[h].concat(n)),Array.isArray(h))return Ou(h,w);let E;return(n.length?n.flat():Object.keys(h)).map((O)=>{return E=h[O],(E instanceof lh?cu(E,f,l,w):E instanceof Vh?E.value:kh(E,f,l,w))+" as "+ah(w.transform.column.to?w.transform.column.to(O):O)}).join(",")}var kn=Object.entries({values:Ju,in:(...h)=>{let n=Ju(...h);return n==="()"?"(null)":n},select:ih,as:ih,returning:ih,"\\(":ih,update(h,n,f,l,w){return(n.length?n.flat():Object.keys(h)).map((E)=>ah(w.transform.column.to?w.transform.column.to(E):E)+"="+tu("values",h[E],f,l,w))},insert(h,n,f,l,w){let E=n.length?n.flat():Object.keys(Array.isArray(h)?h[0]:h);return"("+Ou(E,w)+")values"+Qu(Array.isArray(h)?h:[h],f,l,E,w)}}).map(([h,n])=>[new RegExp("((?:^|[\\s(])"+h+"(?:$|[\\s(]))(?![\\s\\S]*\\1)","i"),n]);function fu(){throw i.generic("NOT_TAGGED_CALL","Query not called as a tagged template literal")}var{serializers:an,parsers:en}=Cu;function Vu(h){if(Array.isArray(h))return Vu(h[0]);return typeof h==="string"?1009:0}var Wu=function(h){let n=Ku(h||{});return{serializers:Object.assign({},an,n.serializers),parsers:Object.assign({},en,n.parsers)}};function Ku(h){return Object.keys(h).reduce((n,f)=>{if(h[f].from&&[].concat(h[f].from).forEach((l)=>n.parsers[l]=h[f].parse),h[f].serialize)n.serializers[h[f].to]=h[f].serialize,h[f].from&&[].concat(h[f].from).forEach((l)=>n.serializers[l]=h[f].serialize);return n},{parsers:{},serializers:{}})}function Ou(h,{transform:{column:n}}){return h.map((f)=>ah(n.to?n.to(f):f)).join(",")}var ah=function(n){return'"'+n.replace(/"/g,'""').replace(/\./g,'"."')+'"'},dh=function h(n){return n instanceof th?n.type:n instanceof Date?1184:n instanceof Uint8Array?17:n===!0||n===!1?16:typeof n==="bigint"?20:Array.isArray(n)?h(n[0]):0},on=/\\/g,yn=/"/g;function pn(h){return h.replace(on,"\\\\").replace(yn,"\\\"")}var vu=function h(n,f,l,w){if(Array.isArray(n)===!1)return n;if(!n.length)return"{}";let E=n[0],t=w===1020?";":",";if(Array.isArray(E)&&!E.type)return"{"+n.map((O)=>h(O,f,l,w)).join(t)+"}";return"{"+n.map((O)=>{if(O===void 0){if(O=l.transform.undefined,O===void 0)throw i.generic("UNDEFINED_VALUE","Undefined values are not allowed")}return O===null?"null":'"'+pn(f?f(O.type?O.value:O):""+O)+'"'}).join(t)+"}"},lu={i:0,char:null,str:"",quoted:!1,last:0},Iu=function(n,f,l){return lu.i=lu.last=0,iu(lu,n,f,l)};function iu(h,n,f,l){let w=[],E=l===1020?";":",";for(;h.i<n.length;h.i++){if(h.char=n[h.i],h.quoted)if(h.char==="\\")h.str+=n[++h.i];else if(h.char==='"')w.push(f?f(h.str):h.str),h.str="",h.quoted=n[h.i+1]==='"',h.last=h.i+2;else h.str+=h.char;else if(h.char==='"')h.quoted=!0;else if(h.char==="{")h.last=++h.i,w.push(iu(h,n,f,l));else if(h.char==="}"){h.quoted=!1,h.last<h.i&&w.push(f?f(n.slice(h.last,h.i)):n.slice(h.last,h.i)),h.last=h.i+1;break}else if(h.char===E&&h.p!=="}"&&h.p!=='"')w.push(f?f(n.slice(h.last,h.i)):n.slice(h.last,h.i)),h.last=h.i+1;h.p=h.char}return h.last<h.i&&w.push(f?f(n.slice(h.last,h.i+1)):n.slice(h.last,h.i+1)),w}var jh=(h)=>{let n=h[0];for(let f=1;f<h.length;f++)n+=h[f]==="_"?h[++f].toUpperCase():h[f];return n},Mh=(h)=>{let n=h[0].toUpperCase();for(let f=1;f<h.length;f++)n+=h[f]==="_"?h[++f].toUpperCase():h[f];return n},Nh=(h)=>h.replace(/_/g,"-"),Jh=(h)=>h.replace(/([A-Z])/g,"_$1").toLowerCase(),Ch=(h)=>(h.slice(0,1)+h.slice(1).replace(/([A-Z])/g,"_$1")).toLowerCase(),Qh=(h)=>h.replace(/-/g,"_");function _u(h){return function n(f,l){return typeof f==="object"&&f!==null&&(l.type===114||l.type===3802)?Array.isArray(f)?f.map((w)=>n(w,l)):Object.entries(f).reduce((w,[E,t])=>Object.assign(w,{[h(E)]:n(t,l)}),{}):f}}jh.column={from:jh};jh.value={from:_u(jh)};Jh.column={to:Jh};var Eu={...jh};Eu.column.to=Jh;Mh.column={from:Mh};Mh.value={from:_u(Mh)};Ch.column={to:Ch};var Au={...Mh};Au.column.to=Ch;Nh.column={from:Nh};Nh.value={from:_u(Nh)};Qh.column={to:Qh};var $u={...Nh};$u.column.to=Qh;import du from"net";import xn from"tls";import Wh from"crypto";import Bu from"stream";import{performance as mu}from"perf_hooks";class Ph extends Array{constructor(){super();Object.defineProperties(this,{count:{value:null,writable:!0},state:{value:null,writable:!0},command:{value:null,writable:!0},columns:{value:null,writable:!0},statement:{value:null,writable:!0}})}static get[Symbol.species](){return Array}}var uh=qn;function qn(h=[]){let n=h.slice(),f=0;return{get length(){return n.length-f},remove:(l)=>{let w=n.indexOf(l);return w===-1?null:(n.splice(w,1),l)},push:(l)=>(n.push(l),l),shift:()=>{let l=n[f++];if(f===n.length)f=0,n=[];else n[f-1]=void 0;return l}}}var y=Buffer.allocUnsafe(256),rn="BCcDdEFfHPpQSX".split("").reduce((h,n)=>{let f=n.charCodeAt(0);return h[n]=()=>{return y[0]=f,U.i=5,U},h},{}),U=Object.assign(sn,rn,{N:String.fromCharCode(0),i:0,inc(h){return U.i+=h,U},str(h){let n=Buffer.byteLength(h);return eh(n),U.i+=y.write(h,U.i,n,"utf8"),U},i16(h){return eh(2),y.writeUInt16BE(h,U.i),U.i+=2,U},i32(h,n){if(n||n===0)return y.writeUInt32BE(h,n),U;return eh(4),y.writeUInt32BE(h,U.i),U.i+=4,U},z(h){return eh(h),y.fill(0,U.i,U.i+h),U.i+=h,U},raw(h){return y=Buffer.concat([y.subarray(0,U.i),h]),U.i=y.length,U},end(h=1){y.writeUInt32BE(U.i-h,h);let n=y.subarray(0,U.i);return U.i=0,y=Buffer.allocUnsafe(256),n}}),B=U;function eh(h){if(y.length-U.i<h){let n=y,f=n.length;y=Buffer.allocUnsafe(f+(f>>1)+h),n.copy(y)}}function sn(){return U.i=0,U}var Su=au,hf=1,Sh=B().S().end(),bu=B().H().end(),uf=B().i32(8).i32(80877103).end(8),nf=Buffer.concat([B().E().str(B.N).i32(0).end(),Sh]),ff=B().D().str("S").str(B.N).end(),Uh=()=>{},lf=new Set(["FetchPreparedStatement","RevalidateCachedQuery","transformAssignedExpr"]),cf={83:"severity_local",86:"severity",67:"code",77:"message",68:"detail",72:"hint",80:"position",112:"internal_position",113:"internal_query",87:"where",115:"schema_name",116:"table_name",99:"column_name",100:"data type_name",110:"constraint_name",70:"file",76:"line",82:"routine"};function au(h,n={},{onopen:f=Uh,onend:l=Uh,onclose:w=Uh}={}){let{sslnegotiation:E,ssl:t,max:O,user:S,host:K,port:Z,database:R,parsers:N,transform:P,onnotice:C,onnotify:g,onparameter:b,max_pipeline:z,keep_alive:ch,backoff:nh,target_session_attrs:x}=h,D=uh(),$h=hf++,Oh={pid:null,secret:null},Lh=Gu(xh,h.idle_timeout),gh=Gu(xh,h.max_lifetime),Y=Gu(hn,h.connect_timeout),$=null,_h,s=null,T=new Ph,p=Buffer.alloc(0),Dh=h.fetch_types,Eh={},_={},j=Math.random().toString(36).slice(2),J=1,d=0,v=0,M=0,X=0,V=0,W=0,m=0,q=null,F=null,Ah=!1,wh=null,Bh=null,a=null,Q=null,H=null,hh=null,Kh=null,rh=null,A=null,Zh=null,e={queue:n.closed,idleTimer:Lh,connect(u){a=u,Yu()},terminate:zh,execute:Fh,cancel:qu,end:xh,count:0,id:$h};return n.closed&&n.closed.push(e),e;async function pu(){let u;try{u=h.socket?await Promise.resolve(h.socket(h)):new du.Socket}catch(c){Th(c);return}return u.on("error",Th),u.on("close",Tu),u.on("drain",Lu),u}async function qu({pid:u,secret:c},G,L){try{_h=B().i32(16).i32(80877102).i32(u).i32(c).end(16),await Du(),$.once("error",L),$.once("close",G)}catch(I){L(I)}}function Fh(u){if(Ah)return Hh(u,i.connection("CONNECTION_DESTROYED",h));if(H)return Hh(u,i.generic("COPY_IN_PROGRESS","You cannot execute queries during copy"));if(u.cancelled)return;try{return u.state=Oh,A?D.push(u):(A=u,A.active=!0),xu(u),k(ru(u))&&!u.describeFirst&&!u.cursorFn&&D.length<z&&(!u.options.onexecute||u.options.onexecute(e))}catch(c){return D.length===0&&k(Sh),fh(c),!0}}function ru(u){if(u.parameters.length>=65534)throw i.generic("MAX_PARAMETERS_EXCEEDED","Max number of parameters (65534) exceeded");return u.options.simple?B().Q().str(u.statement.string+B.N).end():u.describeFirst?Buffer.concat([Mu(u),bu]):u.prepare?u.prepared?vh(u):Buffer.concat([Mu(u),vh(u)]):su(u)}function Mu(u){return Buffer.concat([Ru(u.statement.string,u.parameters,u.statement.types,u.statement.name),vn("S",u.statement.name)])}function vh(u){return Buffer.concat([Kn(u.parameters,u.statement.types,u.statement.name,u.cursorName),u.cursorFn?Uu("",u.cursorRows):nf])}function su(u){return Buffer.concat([Ru(u.statement.string,u.parameters,u.statement.types),ff,vh(u)])}function xu(u){let c=[],G=[],L=wu(u,u.strings[0],u.args[0],c,G,h);!u.tagged&&u.args.forEach((I)=>kh(I,c,G,h)),u.prepare=h.prepare&&("prepare"in u.options?u.options.prepare:!0),u.string=L,u.signature=u.prepare&&G+L,u.onlyDescribe&&delete _[u.signature],u.parameters=u.parameters||c,u.prepared=u.prepare&&u.signature in _,u.describeFirst=u.onlyDescribe||c.length&&!u.prepared,u.statement=u.prepared?_[u.signature]:{string:L,types:G,name:u.prepare?j+J++:""},typeof h.debug==="function"&&h.debug($h,L,c,G)}function k(u,c){if(hh=hh?Buffer.concat([hh,u]):Buffer.from(u),c||hh.length>=1024)return Nu(c);return F===null&&(F=setImmediate(Nu)),!0}function Nu(u){let c=$.write(hh,u);return F!==null&&clearImmediate(F),hh=F=null,c}function hn(){fh(i.connection("CONNECT_TIMEOUT",h,$)),$.destroy()}async function Pu(){if(E!=="direct"){if(k(uf),!await new Promise((G)=>$.once("data",(L)=>G(L[0]===83)))&&t==="prefer")return Yh()}let u={socket:$,servername:du.isIP($.host)?void 0:$.host};if(E==="direct")u.ALPNProtocols=["postgresql"];if(t==="require"||t==="allow"||t==="prefer")u.rejectUnauthorized=!1;else if(typeof t==="object")Object.assign(u,t);$.removeAllListeners(),$=xn.connect(u),$.on("secureConnect",Yh),$.on("error",Th),$.on("close",Tu),$.on("drain",Lu)}function Lu(){!A&&f(e)}function sh(u){if(wh){if(wh.push(u),v-=u.length,v>0)return}p=wh?Buffer.concat(wh,V-v):p.length===0?u:Buffer.concat([p,u],p.length+u.length);while(p.length>4){if(V=p.readUInt32BE(1),V>=p.length){v=V-p.length,wh=[p];break}try{un(p.subarray(0,V+1))}catch(c){A&&(A.cursorFn||A.describeFirst)&&k(Sh),fh(c)}p=p.subarray(V+1),v=0,wh=null}}async function Du(){if(Ah=!1,Eh={},$||($=await pu()),!$)return;if(Y.start(),h.socket)return t?Pu():Yh();if($.on("connect",t?Pu:Yh),h.path)return $.connect(h.path);$.ssl=t,$.connect(Z[M],K[M]),$.host=K[M],$.port=Z[M],M=(M+1)%Z.length}function Yu(){setTimeout(Du,d?Math.max(0,d+W-mu.now()):0)}function Yh(){try{_={},Dh=h.fetch_types,j=Math.random().toString(36).slice(2),J=1,gh.start(),$.on("data",sh),ch&&$.setKeepAlive&&$.setKeepAlive(!0,1000*ch);let u=dn();k(u)}catch(u){Th(u)}}function Th(u){if(e.queue===n.connecting&&h.host[X+1])return;fh(u);while(D.length)Hh(D.shift(),u)}function fh(u){H&&(H.destroy(u),H=null),A&&Hh(A,u),a&&(Hh(a,u),a=null)}function Hh(u,c){if(u.reserve)return u.reject(c);if(!c||typeof c!=="object")c=Error(c);"query"in c||"parameters"in c||Object.defineProperties(c,{stack:{value:c.stack+u.origin.replace(/.*\n/,`
|
|
24
|
+
`),enumerable:h.debug},query:{value:u.string,enumerable:h.debug},parameters:{value:u.parameters,enumerable:h.debug},args:{value:u.args,enumerable:h.debug},types:{value:u.statement&&u.statement.types,enumerable:h.debug}}),u.reject(c)}function xh(){return Q||(!e.reserved&&l(e),!e.reserved&&!a&&!A&&D.length===0?(zh(),new Promise((u)=>$&&$.readyState!=="closed"?$.once("close",u):u())):Q=new Promise((u)=>Kh=u))}function zh(){if(Ah=!0,H||A||a||D.length)Th(i.connection("CONNECTION_DESTROYED",h));if(clearImmediate(F),$)$.removeListener("data",sh),$.removeListener("connect",Yh),$.readyState==="open"&&$.end(B().X().end());Kh&&(Kh(),Q=Kh=null)}async function Tu(u){if(p=Buffer.alloc(0),v=0,wh=null,clearImmediate(F),$.removeListener("data",sh),$.removeListener("connect",Yh),Lh.cancel(),gh.cancel(),Y.cancel(),$.removeAllListeners(),$=null,a)return Yu();!u&&(A||D.length)&&Th(i.connection("CONNECTION_CLOSED",h,$)),d=mu.now(),u&&h.shared.retries++,W=(typeof nh==="function"?nh(h.shared.retries):nh)*1000,w(e,i.connection("CONNECTION_CLOSED",h,$))}function un(u,c=u[0]){(c===68?nn:c===100?Fn:c===65?Yn:c===83?fn:c===90?ln:c===67?cn:c===50?Xu:c===49?wn:c===116?tn:c===84?On:c===82?_n:c===110?Sn:c===75?gn:c===69?Ln:c===115?Tn:c===51?Xn:c===71?Rn:c===78?zn:c===72?Un:c===99?Hn:c===73?Jn:c===86?Cn:c===118?Qn:c===87?Zn:Vn)(u)}function nn(u){let c=7,G,L,I,o=A.isRaw?Array(A.statement.columns.length):{};for(let r=0;r<A.statement.columns.length;r++)L=A.statement.columns[r],G=u.readInt32BE(c),c+=4,I=G===-1?null:A.isRaw===!0?u.subarray(c,c+=G):L.parser===void 0?u.toString("utf8",c,c+=G):L.parser.array===!0?L.parser(u.toString("utf8",c+1,c+=G)):L.parser(u.toString("utf8",c,c+=G)),A.isRaw?o[r]=A.isRaw===!0?I:P.value.from?P.value.from(I,L):I:o[L.name]=P.value.from?P.value.from(I,L):I;A.forEachFn?A.forEachFn(P.row.from?P.row.from(o):o,T):T[m++]=P.row.from?P.row.from(o):o}function fn(u){let[c,G]=u.toString("utf8",5,u.length-1).split(B.N);if(Eh[c]=G,h.parameters[c]!==G)h.parameters[c]=G,b&&b(c,G)}function ln(u){if(A)if(s)A.retried?fh(A.retried):A.prepared&&lf.has(s.routine)?Dn(A,s):fh(s);else A.resolve(Bh||T);else if(s)fh(s);if(A=Bh=s=null,T=new Ph,Y.cancel(),a){if(x){if(!Eh.in_hot_standby||!Eh.default_transaction_read_only)return Pn();else if(Nn(x,Eh))return zh()}if(Dh)return a.reserve&&(a=null),jn();a&&!a.reserve&&Fh(a),h.shared.retries=X=0,a=null;return}while(D.length&&(A=D.shift())&&(A.active=!0,A.cancelled))au(h).cancel(A.state,A.cancelled.resolve,A.cancelled.reject);if(A)return;e.reserved?!e.reserved.release&&u[5]===73?Q?zh():(e.reserved=null,f(e)):e.reserved():Q?zh():f(e)}function cn(u){m=0;for(let c=u.length-1;c>0;c--){if(u[c]===32&&u[c+1]<58&&T.count===null)T.count=+u.toString("utf8",c+1,u.length-1);if(u[c-1]>=65){T.command=u.toString("utf8",5,c),T.state=Oh;break}}if(Zh&&(Zh(),Zh=null),T.command==="BEGIN"&&O!==1&&!e.reserved)return fh(i.generic("UNSAFE_TRANSACTION","Only use sql.begin, sql.reserved or max: 1"));if(A.options.simple)return Xu();if(A.cursorFn)T.count&&A.cursorFn(T),k(Sh)}function wn(){A.parsing=!1}function Xu(){!T.statement&&(T.statement=A.statement),T.columns=A.statement.columns}function tn(u){let c=u.readUInt16BE(5);for(let G=0;G<c;++G)!A.statement.types[G]&&(A.statement.types[G]=u.readUInt32BE(7+G*4));A.prepare&&(_[A.signature]=A.statement),A.describeFirst&&!A.onlyDescribe&&(k(vh(A)),A.describeFirst=!1)}function On(u){if(T.command)Bh=Bh||[T],Bh.push(T=new Ph),T.count=null,A.statement.columns=null;let c=u.readUInt16BE(5),G=7,L;A.statement.columns=Array(c);for(let I=0;I<c;++I){L=G;while(u[G++]!==0);let o=u.readUInt32BE(G),r=u.readUInt16BE(G+4),Gh=u.readUInt32BE(G+6);A.statement.columns[I]={name:P.column.from?P.column.from(u.toString("utf8",L,G-1)):u.toString("utf8",L,G-1),parser:N[Gh],table:o,number:r,type:Gh},G+=18}if(T.statement=A.statement,A.onlyDescribe)return A.resolve(A.statement),k(Sh)}async function _n(u,c=u.readUInt32BE(5)){(c===3?En:c===5?An:c===10?$n:c===11?Bn:c===12?Gn:c!==0?Wn:Uh)(u,c)}async function En(){let u=await hu();k(B().p().str(u).z(1).end())}async function An(u){let c="md5"+await ku(Buffer.concat([Buffer.from(await ku(await hu()+S)),u.subarray(9)]));k(B().p().str(c).z(1).end())}async function $n(){rh=(await Wh.randomBytes(18)).toString("base64"),B().p().str("SCRAM-SHA-256"+B.N);let u=B.i;k(B.inc(4).str("n,,n=*,r="+rh).i32(B.i-u-4,u).end())}async function Bn(u){let c=u.toString("utf8",9).split(",").reduce((r,Gh)=>(r[Gh[0]]=Gh.slice(2),r),{}),G=await Wh.pbkdf2Sync(await hu(),Buffer.from(c.s,"base64"),parseInt(c.i),32,"sha256"),L=await yh(G,"Client Key"),I="n=*,r="+rh+",r="+c.r+",s="+c.s+",i="+c.i+",c=biws,r="+c.r;q=(await yh(await yh(G,"Server Key"),I)).toString("base64");let o="c=biws,r="+c.r+",p="+tf(L,Buffer.from(await yh(await wf(L),I))).toString("base64");k(B().p().str(o).end())}function Gn(u){if(u.toString("utf8",9).split(B.N,1)[0].slice(2)===q)return;fh(i.generic("SASL_SIGNATURE_MISMATCH","The server did not return the correct signature")),$.destroy()}function hu(){return Promise.resolve(typeof h.pass==="function"?h.pass():h.pass)}function Sn(){if(T.statement=A.statement,T.statement.columns=[],A.onlyDescribe)return A.resolve(A.statement),k(Sh)}function gn(u){Oh.pid=u.readUInt32BE(5),Oh.secret=u.readUInt32BE(9)}async function jn(){Dh=!1,(await new lh([`
|
|
25
|
+
select b.oid, b.typarray
|
|
26
|
+
from pg_catalog.pg_type a
|
|
27
|
+
left join pg_catalog.pg_type b on b.oid = a.typelem
|
|
28
|
+
where a.typcategory = 'A'
|
|
29
|
+
group by b.oid, b.typarray
|
|
30
|
+
order by b.oid
|
|
31
|
+
`],[],Fh)).forEach(({oid:c,typarray:G})=>Mn(c,G))}function Mn(u,c){if(!!h.parsers[c]&&!!h.serializers[c])return;let G=h.parsers[u];h.shared.typeArrayMap[u]=c,h.parsers[c]=(L)=>Iu(L,G,c),h.parsers[c].array=!0,h.serializers[c]=(L)=>vu(L,h.serializers[u],h,c)}function Nn(u,c){return u==="read-write"&&c.default_transaction_read_only==="on"||u==="read-only"&&c.default_transaction_read_only==="off"||u==="primary"&&c.in_hot_standby==="on"||u==="standby"&&c.in_hot_standby==="off"||u==="prefer-standby"&&c.in_hot_standby==="off"&&h.host[X]}function Pn(){let u=new lh([`
|
|
32
|
+
show transaction_read_only;
|
|
33
|
+
select pg_catalog.pg_is_in_recovery()
|
|
34
|
+
`],[],Fh,null,{simple:!0});u.resolve=([[c],[G]])=>{Eh.default_transaction_read_only=c.transaction_read_only,Eh.in_hot_standby=G.pg_is_in_recovery?"on":"off"},u.execute()}function Ln(u){if(A)(A.cursorFn||A.describeFirst)&&k(Sh),s=i.postgres(oh(u));else fh(i.postgres(oh(u)))}function Dn(u,c){delete _[u.signature],u.retried=c,Fh(u)}function Yn(u){if(!g)return;let c=9;while(u[c++]!==0);g(u.toString("utf8",9,c-1),u.toString("utf8",c,u.length-1))}async function Tn(){try{let u=await Promise.resolve(A.cursorFn(T));m=0,u===Xh?k(In(A.portal)):(T=new Ph,k(Uu("",A.cursorRows)))}catch(u){k(Sh),A.reject(u)}}function Xn(){T.count&&A.cursorFn(T),A.resolve(T)}function Rn(){H=new Bu.Writable({autoDestroy:!0,write(u,c,G){$.write(B().d().raw(u).end(),G)},destroy(u,c){c(u),$.write(B().f().str(u+B.N).end()),H=null},final(u){$.write(B().c().end()),Zh=u,H=null}}),A.resolve(H)}function Un(){H=new Bu.Readable({read(){$.resume()}}),A.resolve(H)}function Zn(){H=new Bu.Duplex({autoDestroy:!0,read(){$.resume()},write(u,c,G){$.write(B().d().raw(u).end(),G)},destroy(u,c){c(u),$.write(B().f().str(u+B.N).end()),H=null},final(u){$.write(B().c().end()),Zh=u}}),A.resolve(H)}function Fn(u){H&&(H.push(u.subarray(5))||$.pause())}function Hn(){H&&H.push(null),H=null}function zn(u){C?C(oh(u)):console.log(oh(u))}function Jn(){}function Cn(){fh(i.notSupported("FunctionCallResponse"))}function Qn(){fh(i.notSupported("NegotiateProtocolVersion"))}function Vn(u){console.error("Postgres.js : Unknown Message:",u[0])}function Wn(u,c){console.error("Postgres.js : Unknown Auth:",c)}function Kn(u,c,G="",L=""){let I,o;return B().B().str(L+B.N).str(G+B.N).i16(0).i16(u.length),u.forEach((r,Gh)=>{if(r===null)return B.i32(4294967295);o=c[Gh],u[Gh]=r=o in h.serializers?h.serializers[o](r):""+r,I=B.i,B.inc(4).str(r).i32(B.i-I-4,I)}),B.i16(0),B.end()}function Ru(u,c,G,L=""){return B().P().str(L+B.N).str(u+B.N).i16(c.length),c.forEach((I,o)=>B.i32(G[o]||0)),B.end()}function vn(u,c=""){return B().D().str(u).str(c+B.N).end()}function Uu(u="",c=0){return Buffer.concat([B().E().str(u+B.N).i32(c).end(),bu])}function In(u=""){return Buffer.concat([B().C().str("P").str(u+B.N).end(),B().S().end()])}function dn(){return _h||B().inc(4).i16(3).z(2).str(Object.entries(Object.assign({user:S,database:R,client_encoding:"UTF8"},h.connection)).filter(([,u])=>u).map(([u,c])=>u+B.N+c).join(B.N)).z(2).end(0)}}function oh(h){let n={},f=5;for(let l=5;l<h.length-1;l++)if(h[l]===0)n[cf[h[f]]]=h.toString("utf8",f+1,l),f=l+1;return n}function ku(h){return Wh.createHash("md5").update(h).digest("hex")}function yh(h,n){return Wh.createHmac("sha256",h).update(n).digest()}function wf(h){return Wh.createHash("sha256").update(h).digest()}function tf(h,n){let f=Math.max(h.length,n.length),l=Buffer.allocUnsafe(f);for(let w=0;w<f;w++)l[w]=h[w]^n[w];return l}function Gu(h,n){if(n=typeof n==="function"?n():n,!n)return{cancel:Uh,start:Uh};let f;return{cancel(){f&&(clearTimeout(f),f=null)},start(){f&&clearTimeout(f),f=setTimeout(l,n*1000,arguments)}};function l(w){h.apply(null,w),f=null}}var eu=()=>{};function gu(h,n){let f=new Map,l="postgresjs_"+Math.random().toString(36).slice(2),w={},E,t,O=!1,S=R.sql=h({...n,transform:{column:{},value:{},row:{}},max:1,fetch_types:!1,idle_timeout:null,max_lifetime:null,connection:{...n.connection,replication:"database"},onclose:async function(){if(O)return;t=null,w.pid=w.secret=void 0,N(await P(S,l,n.publications)),f.forEach((g)=>g.forEach(({onsubscribe:b})=>b()))},no_subscribe:!0}),K=S.end,Z=S.close;return S.end=async()=>{return O=!0,t&&await new Promise((g)=>(t.once("close",g),t.end())),K()},S.close=async()=>{return t&&await new Promise((g)=>(t.once("close",g),t.end())),Z()},R;async function R(g,b,z=eu,ch=eu){if(g=Ef(g),!E)E=P(S,l,n.publications);let nh={fn:b,onsubscribe:z},x=f.has(g)?f.get(g).add(nh):f.set(g,new Set([nh])).get(g),D=()=>{x.delete(nh),x.size===0&&f.delete(g)};return E.then(($h)=>{return N($h),z(),t&&t.on("error",ch),{unsubscribe:D,state:w,sql:S}})}function N(g){t=g.stream,w.pid=g.state.pid,w.secret=g.state.secret}async function P(g,b,z){if(!z)throw Error("Missing publication names");let ch=await g.unsafe(`CREATE_REPLICATION_SLOT ${b} TEMPORARY LOGICAL pgoutput NOEXPORT_SNAPSHOT`),[nh]=ch,x=await g.unsafe(`START_REPLICATION SLOT ${b} LOGICAL ${nh.consistent_point} (proto_version '1', publication_names '${z}')`).writable(),D={lsn:Buffer.concat(nh.consistent_point.split("/").map((Y)=>Buffer.from(("00000000"+Y).slice(-8),"hex")))};return x.on("data",Oh),x.on("error",$h),x.on("close",g.close),{stream:x,state:ch.state};function $h(Y){console.error("Unexpected error during logical streaming - reconnecting",Y)}function Oh(Y){if(Y[0]===119)_f(Y.subarray(25),D,g.options.parsers,Lh,n.transform);else if(Y[0]===107&&Y[17])D.lsn=Y.subarray(1,9),gh()}function Lh(Y,$){let _h=$.relation.schema+"."+$.relation.table;C("*",Y,$),C("*:"+_h,Y,$),$.relation.keys.length&&C("*:"+_h+"="+$.relation.keys.map((s)=>Y[s.name]),Y,$),C($.command,Y,$),C($.command+":"+_h,Y,$),$.relation.keys.length&&C($.command+":"+_h+"="+$.relation.keys.map((s)=>Y[s.name]),Y,$)}function gh(){let Y=Buffer.alloc(34);Y[0]=114,Y.fill(D.lsn,1),Y.writeBigInt64BE(BigInt(Date.now()-Date.UTC(2000,0,1))*BigInt(1000),25),x.write(Y)}}function C(g,b,z){f.has(g)&&f.get(g).forEach(({fn:ch})=>ch(b,z,g))}}function Of(h){return new Date(Date.UTC(2000,0,1)+Number(h/BigInt(1000)))}function _f(h,n,f,l,w){let E=(t,[O,S])=>(t[O.charCodeAt(0)]=S,t);Object.entries({R:(t)=>{let O=1,S=n[t.readUInt32BE(O)]={schema:t.toString("utf8",O+=4,O=t.indexOf(0,O))||"pg_catalog",table:t.toString("utf8",O+1,O=t.indexOf(0,O+1)),columns:Array(t.readUInt16BE(O+=2)),keys:[]};O+=2;let K=0,Z;while(O<t.length)Z=S.columns[K++]={key:t[O++],name:w.column.from?w.column.from(t.toString("utf8",O,O=t.indexOf(0,O))):t.toString("utf8",O,O=t.indexOf(0,O)),type:t.readUInt32BE(O+=1),parser:f[t.readUInt32BE(O)],atttypmod:t.readUInt32BE(O+=4)},Z.key&&S.keys.push(Z),O+=4},Y:()=>{},O:()=>{},B:(t)=>{n.date=Of(t.readBigInt64BE(9)),n.lsn=t.subarray(1,9)},I:(t)=>{let O=1,S=n[t.readUInt32BE(O)],{row:K}=ph(t,S.columns,O+=7,w);l(K,{command:"insert",relation:S})},D:(t)=>{let O=1,S=n[t.readUInt32BE(O)];O+=4;let K=t[O]===75;l(K||t[O]===79?ph(t,S.columns,O+=3,w).row:null,{command:"delete",relation:S,key:K})},U:(t)=>{let O=1,S=n[t.readUInt32BE(O)];O+=4;let K=t[O]===75,Z=K||t[O]===79?ph(t,S.columns,O+=3,w):null;Z&&(O=Z.i);let{row:R}=ph(t,S.columns,O+3,w);l(R,{command:"update",relation:S,key:K,old:Z&&Z.row})},T:()=>{},C:()=>{}}).reduce(E,{})[h[0]](h)}function ph(h,n,f,l){let w,E,t,O=l.raw?Array(n.length):{};for(let S=0;S<n.length;S++)w=h[f++],E=n[S],t=w===110?null:w===117?void 0:E.parser===void 0?h.toString("utf8",f+4,f+=4+h.readUInt32BE(f)):E.parser.array===!0?E.parser(h.toString("utf8",f+5,f+=4+h.readUInt32BE(f))):E.parser(h.toString("utf8",f+4,f+=4+h.readUInt32BE(f))),l.raw?O[S]=l.raw===!0?t:l.value.from?l.value.from(t,E):t:O[E.name]=l.value.from?l.value.from(t,E):t;return{i:f,row:l.row.from?l.row.from(O):O}}function Ef(h){let n=h.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i)||[];if(!n)throw Error("Malformed subscribe pattern: "+h);let[,f,l,w]=n;return(f||"*")+(l?":"+(l.indexOf(".")===-1?"public."+l:l):"")+(w?"="+w:"")}import ou from"stream";function ju(h,n,f=393216){return new Promise(async(l,w)=>{await h.begin(async(E)=>{let t;!n&&([{oid:n}]=await E`select lo_creat(-1) as oid`);let[{fd:O}]=await E`select lo_open(${n}, ${f}) as fd`,S={writable:Z,readable:K,close:()=>E`select lo_close(${O})`.then(t),tell:()=>E`select lo_tell64(${O})`,read:(R)=>E`select loread(${O}, ${R}) as data`,write:(R)=>E`select lowrite(${O}, ${R})`,truncate:(R)=>E`select lo_truncate64(${O}, ${R})`,seek:(R,N=0)=>E`select lo_lseek64(${O}, ${R}, ${N})`,size:()=>E`
|
|
35
|
+
select
|
|
36
|
+
lo_lseek64(${O}, location, 0) as position,
|
|
37
|
+
seek.size
|
|
38
|
+
from (
|
|
39
|
+
select
|
|
40
|
+
lo_lseek64($1, 0, 2) as size,
|
|
41
|
+
tell.location
|
|
42
|
+
from (select lo_tell64($1) as location) tell
|
|
43
|
+
) seek
|
|
44
|
+
`};return l(S),new Promise(async(R)=>t=R);async function K({highWaterMark:R=16384,start:N=0,end:P=1/0}={}){let C=P-N;return N&&await S.seek(N),new ou.Readable({highWaterMark:R,async read(g){let b=g>C?g-C:g;C-=g;let[{data:z}]=await S.read(b);if(this.push(z),z.length<g)this.push(null)}})}async function Z({highWaterMark:R=16384,start:N=0}={}){return N&&await S.seek(N),new ou.Writable({highWaterMark:R,write(P,C,g){S.write(P).then(()=>g(),g)}})}}).catch(w)})}Object.assign(qh,{PostgresError:Rh,toPascal:Mh,pascal:Au,toCamel:jh,camel:Eu,toKebab:Nh,kebab:$u,fromPascal:Ch,fromCamel:Jh,fromKebab:Qh,BigInt:{to:20,from:[20],parse:(h)=>BigInt(h),serialize:(h)=>h.toString()}});var yu=qh;function qh(h,n){let f=Bf(h,n),l=f.no_subscribe||gu(qh,{...f}),w=!1,E=uh(),t=uh(),O=uh(),S=uh(),K=uh(),Z=uh(),R=uh(),N=uh(),P={connecting:t,reserved:O,closed:S,ended:K,open:Z,busy:R,full:N},C=[...Array(f.max)].map(()=>Su(f,P,{onopen:Dh,onend:p,onclose:Eh})),g=b(Lh);return Object.assign(g,{get parameters(){return f.parameters},largeObject:ju.bind(null,g),subscribe:l,CLOSE:Xh,END:Xh,PostgresError:Rh,options:f,reserve:nh,listen:z,begin:x,close:_h,end:$}),g;function b(_){return _.debug=f.debug,Object.entries(f.types).reduce((M,[X,V])=>{return M[X]=(W)=>new th(W,V.to),M},j),Object.assign(J,{types:j,typed:j,unsafe:d,notify:ch,array:Oh,json:$h,file:v}),J;function j(M,X){return new th(M,X)}function J(M,...X){return M&&Array.isArray(M.raw)?new lh(M,X,_,Y):typeof M==="string"&&!X.length?new Vh(f.transform.column.to?f.transform.column.to(M):M):new bh(M,X)}function d(M,X=[],V={}){return arguments.length===2&&!Array.isArray(X)&&(V=X,X=[]),new lh([M],X,_,Y,{prepare:!1,...V,simple:"simple"in V?V.simple:X.length===0})}function v(M,X=[],V={}){return arguments.length===2&&!Array.isArray(X)&&(V=X,X=[]),new lh([],X,(m)=>{$f.readFile(M,"utf8",(q,F)=>{if(q)return m.reject(q);m.strings=[F],_(m)})},Y,{...V,simple:"simple"in V?V.simple:X.length===0})}}async function z(_,j,J){let d={fn:j,onlisten:J},v=z.sql||(z.sql=qh({...f,max:1,idle_timeout:null,max_lifetime:null,fetch_types:!1,onclose(){Object.entries(z.channels).forEach(([m,{listeners:q}])=>{delete z.channels[m],Promise.all(q.map((F)=>z(m,F.fn,F.onlisten).catch(()=>{})))})},onnotify(m,q){m in z.channels&&z.channels[m].listeners.forEach((F)=>F.fn(q))}})),M=z.channels||(z.channels={});if(_ in M){M[_].listeners.push(d);let m=await M[_].result;return d.onlisten&&d.onlisten(),{state:m.state,unlisten:W}}M[_]={result:v`listen ${v.unsafe('"'+_.replace(/"/g,'""')+'"')}`,listeners:[d]};let V=await M[_].result;return d.onlisten&&d.onlisten(),{state:V.state,unlisten:W};async function W(){if(_ in M===!1)return;if(M[_].listeners=M[_].listeners.filter((m)=>m!==d),M[_].listeners.length)return;return delete M[_],v`unlisten ${v.unsafe('"'+_.replace(/"/g,'""')+'"')}`}}async function ch(_,j){return await g`select pg_notify(${_}, ${""+j})`}async function nh(){let _=uh(),j=Z.length?Z.shift():await new Promise((v,M)=>{let X={reserve:v,reject:M};E.push(X),S.length&&T(S.shift(),X)});D(j,O),j.reserved=()=>_.length?j.execute(_.shift()):D(j,O),j.reserved.release=!0;let J=b(d);return J.release=()=>{j.reserved=null,Dh(j)},J;function d(v){j.queue===N?_.push(v):j.execute(v)||D(j,N)}}async function x(_,j){!j&&(j=_,_="");let J=uh(),d=0,v,M=null;try{return await g.unsafe("begin "+_.replace(/[^a-z ]/ig,""),[],{onexecute:V}).execute(),await Promise.race([X(v,j),new Promise((W,m)=>v.onclose=m)])}catch(W){throw W}async function X(W,m,q){let F=b(a);F.savepoint=Bh,F.prepare=(Q)=>M=Q.replace(/[^a-z0-9$-_. ]/gi);let Ah,wh;q&&await F`savepoint ${F(q)}`;try{if(wh=await new Promise((Q,H)=>{let hh=m(F);Promise.resolve(Array.isArray(hh)?Promise.all(hh):hh).then(Q,H)}),Ah)throw Ah}catch(Q){throw await(q?F`rollback to ${F(q)}`:F`rollback`),Q instanceof Rh&&Q.code==="25P02"&&Ah||Q}if(!q)M?await F`prepare transaction '${F.unsafe(M)}'`:await F`commit`;return wh;function Bh(Q,H){if(Q&&Array.isArray(Q.raw))return Bh((hh)=>hh.apply(hh,arguments));return arguments.length===1&&(H=Q,Q=null),X(W,H,"s"+d+++(Q?"_"+Q:""))}function a(Q){Q.catch((H)=>Ah||(Ah=H)),W.queue===N?J.push(Q):W.execute(Q)||D(W,N)}}function V(W){v=W,D(W,O),W.reserved=()=>J.length?W.execute(J.shift()):D(W,O)}}function D(_,j){return _.queue.remove(_),j.push(_),_.queue=j,j===Z?_.idleTimer.start():_.idleTimer.cancel(),_}function $h(_){return new th(_,3802)}function Oh(_,j){if(!Array.isArray(_))return Oh(Array.from(arguments));return new th(_,j||(_.length?dh(_)||25:0),f.shared.typeArrayMap)}function Lh(_){if(w)return _.reject(i.connection("CONNECTION_ENDED",f,f));if(Z.length)return gh(Z.shift(),_);if(S.length)return T(S.shift(),_);R.length?gh(R.shift(),_):E.push(_)}function gh(_,j){return _.execute(j)?D(_,R):D(_,N)}function Y(_){return new Promise((j,J)=>{_.state?_.active?Su(f).cancel(_.state,j,J):_.cancelled={resolve:j,reject:J}:(E.remove(_),_.cancelled=!0,_.reject(i.generic("57014","canceling statement due to user request")),j())})}async function $({timeout:_=null}={}){if(w)return w;await 1;let j;return w=Promise.race([new Promise((J)=>_!==null&&(j=setTimeout(s,_*1000,J))),Promise.all(C.map((J)=>J.end()).concat(z.sql?z.sql.end({timeout:0}):[],l.sql?l.sql.end({timeout:0}):[]))]).then(()=>clearTimeout(j))}async function _h(){await Promise.all(C.map((_)=>_.end()))}async function s(_){await Promise.all(C.map((j)=>j.terminate()));while(E.length)E.shift().reject(i.connection("CONNECTION_DESTROYED",f));_()}function T(_,j){return D(_,t),_.connect(j),_}function p(_){D(_,K)}function Dh(_){if(E.length===0)return D(_,Z);let j=Math.ceil(E.length/(t.length+1)),J=!0;while(J&&E.length&&j-- >0){let d=E.shift();if(d.reserve)return d.reserve(_);J=_.execute(d)}J?D(_,R):D(_,N)}function Eh(_,j){D(_,S),_.reserved=null,_.onclose&&(_.onclose(j),_.onclose=null),f.onclose&&f.onclose(_.id),E.length&&T(_,E.shift())}}function Bf(h,n){if(h&&h.shared)return h;let f=process.env,l=(!h||typeof h==="string"?n:h)||{},{url:w,multihost:E}=Mf(h),t=[...w.searchParams].reduce((N,[P,C])=>(N[P]=C,N),{}),O=l.hostname||l.host||E||w.hostname||f.PGHOST||"localhost",S=l.port||w.port||f.PGPORT||5432,K=l.user||l.username||w.username||f.PGUSERNAME||f.PGUSER||Nf();l.no_prepare&&(l.prepare=!1),t.sslmode&&(t.ssl=t.sslmode,delete t.sslmode),"timeout"in l&&(console.log("The timeout option is deprecated, use idle_timeout instead"),l.idle_timeout=l.timeout),t.sslrootcert==="system"&&(t.ssl="verify-full");let Z=["idle_timeout","connect_timeout","max_lifetime","max_pipeline","backoff","keep_alive"],R={max:globalThis.Cloudflare?3:10,ssl:!1,sslnegotiation:null,idle_timeout:null,connect_timeout:30,max_lifetime:gf,max_pipeline:100,backoff:Sf,keep_alive:60,prepare:!0,debug:!1,fetch_types:!0,publications:"alltables",target_session_attrs:null};return{host:Array.isArray(O)?O:O.split(",").map((N)=>N.split(":")[0]),port:Array.isArray(S)?S:O.split(",").map((N)=>parseInt(N.split(":")[1]||S)),path:l.path||O.indexOf("/")>-1&&O+"/.s.PGSQL."+S,database:l.database||l.db||(w.pathname||"").slice(1)||f.PGDATABASE||K,user:K,pass:l.pass||l.password||w.password||f.PGPASSWORD||"",...Object.entries(R).reduce((N,[P,C])=>{let g=P in l?l[P]:(P in t)?t[P]==="disable"||t[P]==="false"?!1:t[P]:f["PG"+P.toUpperCase()]||C;return N[P]=typeof g==="string"&&Z.includes(P)?+g:g,N},{}),connection:{application_name:f.PGAPPNAME||"postgres.js",...l.connection,...Object.entries(t).reduce((N,[P,C])=>((P in R)||(N[P]=C),N),{})},types:l.types||{},target_session_attrs:Gf(l,w,f),onnotice:l.onnotice,onnotify:l.onnotify,onclose:l.onclose,onparameter:l.onparameter,socket:l.socket,transform:jf(l.transform||{undefined:void 0}),parameters:{},shared:{retries:0,typeArrayMap:{}},...Wu(l.types)}}function Gf(h,n,f){let l=h.target_session_attrs||n.searchParams.get("target_session_attrs")||f.PGTARGETSESSIONATTRS;if(!l||["read-write","read-only","primary","standby","prefer-standby"].includes(l))return l;throw Error("target_session_attrs "+l+" is not supported")}function Sf(h){return(0.5+Math.random()/2)*Math.min(3**h/100,20)}function gf(){return 60*(30+Math.random()*30)}function jf(h){return{undefined:h.undefined,column:{from:typeof h.column==="function"?h.column:h.column&&h.column.from,to:h.column&&h.column.to},value:{from:typeof h.value==="function"?h.value:h.value&&h.value.from,to:h.value&&h.value.to},row:{from:typeof h.row==="function"?h.row:h.row&&h.row.from,to:h.row&&h.row.to}}}function Mf(h){if(!h||typeof h!=="string")return{url:{searchParams:new Map}};let n=h;n=n.slice(n.indexOf("://")+3).split(/[?/]/)[0],n=decodeURIComponent(n.slice(n.indexOf("@")+1));let f=new URL(h.replace(n,n.split(",")[0]));return{url:{username:decodeURIComponent(f.username),password:decodeURIComponent(f.password),host:f.host,hostname:f.hostname,port:f.port,pathname:f.pathname,searchParams:f.searchParams},multihost:n.indexOf(",")>-1&&n}}function Nf(){try{return Af.userInfo().username}catch(h){return process.env.USERNAME||process.env.USER||process.env.LOGNAME}}function ul(h){let n=yu(h);return{async setupTables(){await n`
|
|
45
|
+
CREATE TABLE IF NOT EXISTS sl_base_urls (
|
|
46
|
+
id SERIAL PRIMARY KEY,
|
|
47
|
+
base_url VARCHAR(255) NOT NULL UNIQUE,
|
|
48
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
49
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
50
|
+
)
|
|
51
|
+
`,await n`
|
|
52
|
+
CREATE TABLE IF NOT EXISTS sl_links_map (
|
|
53
|
+
id SERIAL PRIMARY KEY,
|
|
54
|
+
short_id VARCHAR(255) NOT NULL,
|
|
55
|
+
target_url TEXT NOT NULL,
|
|
56
|
+
base_url_id INT NULL,
|
|
57
|
+
last_accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
58
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
59
|
+
CONSTRAINT uk_short_id_base_url UNIQUE (short_id, base_url_id),
|
|
60
|
+
FOREIGN KEY (base_url_id) REFERENCES sl_base_urls(id) ON DELETE SET NULL
|
|
61
|
+
)
|
|
62
|
+
`,await n`
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_sl_links_map_last_accessed_at
|
|
64
|
+
ON sl_links_map(last_accessed_at)
|
|
65
|
+
`,await n`
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_sl_links_map_base_url_id
|
|
67
|
+
ON sl_links_map(base_url_id)
|
|
68
|
+
`,await n`
|
|
69
|
+
CREATE INDEX IF NOT EXISTS idx_sl_links_map_short_id_base_url
|
|
70
|
+
ON sl_links_map(short_id, base_url_id)
|
|
71
|
+
`},async getTargetUrl(f,l){return(l===null?await n`
|
|
72
|
+
SELECT target_url
|
|
73
|
+
FROM sl_links_map
|
|
74
|
+
WHERE short_id = ${f} AND base_url_id IS NULL
|
|
75
|
+
LIMIT 1
|
|
76
|
+
`:await n`
|
|
77
|
+
SELECT target_url
|
|
78
|
+
FROM sl_links_map
|
|
79
|
+
WHERE short_id = ${f} AND base_url_id = ${l}
|
|
80
|
+
LIMIT 1
|
|
81
|
+
`)[0]?.target_url??null},async createShortLink(f,l,w){await n`
|
|
82
|
+
INSERT INTO sl_links_map (short_id, target_url, base_url_id)
|
|
83
|
+
VALUES (${f}, ${l}, ${w})
|
|
84
|
+
`},async checkShortIdsExist(f,l){if(f.length===0)return[];let w=l===null?n`short_id IN ${n(f)} AND base_url_id IS NULL`:n`short_id IN ${n(f)} AND base_url_id = ${l}`;return(await n`
|
|
85
|
+
SELECT short_id
|
|
86
|
+
FROM sl_links_map
|
|
87
|
+
WHERE ${w}
|
|
88
|
+
`).map((t)=>t.short_id)},async updateShortLinkLastAccessTime(f,l,w=new Date){let E=w;if(typeof E==="number")E=new Date(E);let t=l===null?n`WHERE short_id = ${f} AND base_url_id IS NULL`:n`WHERE short_id = ${f} AND base_url_id = ${l}`;await n`
|
|
89
|
+
UPDATE sl_links_map
|
|
90
|
+
SET last_accessed_at = ${E}
|
|
91
|
+
${t}
|
|
92
|
+
`},async cleanUnusedLinks(f){return(await n`
|
|
93
|
+
DELETE FROM sl_links_map
|
|
94
|
+
WHERE last_accessed_at < NOW() - make_interval(days => ${f})
|
|
95
|
+
RETURNING short_id, base_url_id
|
|
96
|
+
`).map((w)=>({shortId:w.short_id,baseUrlId:w.base_url_id}))},async removeShortLink(f,l){let w=l===null?n`WHERE short_id = ${f} AND base_url_id IS NULL`:n`WHERE short_id = ${f} AND base_url_id = ${l}`;await n`
|
|
97
|
+
DELETE FROM sl_links_map
|
|
98
|
+
${w}
|
|
99
|
+
`},baseUrl:{async add(f){await n`
|
|
100
|
+
INSERT INTO sl_base_urls (base_url)
|
|
101
|
+
VALUES (${f})
|
|
102
|
+
ON CONFLICT (base_url) DO NOTHING
|
|
103
|
+
`},async remove(f){await n`
|
|
104
|
+
UPDATE sl_base_urls SET is_active = FALSE
|
|
105
|
+
WHERE id = ${f}
|
|
106
|
+
`},async list(f){return(f?await n`
|
|
107
|
+
SELECT id, base_url, is_active FROM sl_base_urls
|
|
108
|
+
`:await n`
|
|
109
|
+
SELECT id, base_url, is_active FROM sl_base_urls WHERE is_active = TRUE
|
|
110
|
+
`).map((w)=>({id:w.id,baseUrl:w.base_url,isActive:w.is_active}))},async getId(f){let l=await n`
|
|
111
|
+
SELECT id FROM sl_base_urls WHERE base_url = ${f} LIMIT 1
|
|
112
|
+
`;if(l.length===0)throw Error(`Base URL not found: ${f}`);return l[0].id}}}}var fl={};export{fl as default,ul as createPostgresBackend};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@potonz/shortlinks-manager-postgres",
|
|
3
|
+
"description": "Short links manager extension for PostgreSQL using postgres.js",
|
|
4
|
+
"author": {
|
|
5
|
+
"name": "Thomas Nguyen",
|
|
6
|
+
"email": "tom@tomng.dev"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/potonz/shortlinks-manager",
|
|
9
|
+
"repository": {
|
|
10
|
+
"url": "git+https://github.com/potonz/shortlinks-manager.git",
|
|
11
|
+
"type": "git",
|
|
12
|
+
"directory": "packages/shortlinks-manager-postgres"
|
|
13
|
+
},
|
|
14
|
+
"version": "0.3.0",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@potonz/shortlinks-manager": "workspace:*",
|
|
19
|
+
"postgres": "^3.4.5"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"module": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"require": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@potonz/shortlinks-manager-postgres",
|
|
3
|
+
"description": "Short links manager extension for PostgreSQL using postgres.js",
|
|
4
|
+
"author": {
|
|
5
|
+
"name": "Thomas Nguyen",
|
|
6
|
+
"email": "tom@tomng.dev"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/potonz/shortlinks-manager",
|
|
9
|
+
"repository": {
|
|
10
|
+
"url": "git+https://github.com/potonz/shortlinks-manager.git",
|
|
11
|
+
"type": "git",
|
|
12
|
+
"directory": "packages/shortlinks-manager-postgres"
|
|
13
|
+
},
|
|
14
|
+
"version": "0.3.0",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "bun test"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@potonz/shortlinks-manager": "0.2.3",
|
|
22
|
+
"postgres": "^3.4.5"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"date-fns": "^4.1.0"
|
|
26
|
+
},
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"require": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist"
|
|
39
|
+
],
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|