Add esm exports (#3423)

* build: add esm exports

* fix: add defaults as per arethetypeswrong report

* fix: add missing types

* lint

* Fix broken tests

* Add (failing) test for esm compat

* Begin moving files to proper extension and adding tests

* Add tests for connection-string and fix cloudflare module type and esm compat

* Add query-stream and cursor as esm exports

* Update PR copilot review

* Publish

 - pg-cloudflare@1.1.2-alpha.0
 - pg-connection-string@2.7.1-alpha.0
 - pg-cursor@2.13.2-alpha.0
 - pg-esm-test@1.0.1-alpha.0
 - pg-native@3.3.1-alpha.0
 - pg-pool@3.8.1-alpha.0
 - pg-protocol@1.8.1-alpha.0
 - pg-query-stream@4.8.2-alpha.0
 - pg@8.14.2-alpha.0

* More cf compat work

* Publish

 - pg-cloudflare@1.1.2-alpha.1
 - pg-cursor@2.13.2-alpha.1
 - pg-esm-test@1.0.1-alpha.1
 - pg-pool@3.8.1-alpha.1
 - pg-query-stream@4.8.2-alpha.1
 - pg@8.14.2-alpha.1

* Add more cf compat and update tests

* Make tests pass - update exports for esm

* Use env vars for test connection in cf tests

* Fix lint

* Fit vitest into existing legacy framework

* Skip worker tests on node below 18

* Revert doc changes for now

* Remove legacy worker test in favor of vitest

---------

Co-authored-by: Luca Ban <mesqueeb@users.noreply.github.com>
This commit is contained in:
Brian C 2025-04-22 10:53:22 -05:00 committed by GitHub
parent 81ec0635fc
commit 940479bc4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 1684 additions and 463 deletions

View File

@ -10,7 +10,7 @@
"packages/*"
],
"scripts": {
"test": "yarn lerna exec yarn test",
"test": "yarn lerna exec --concurrency 1 yarn test",
"build": "tsc --build",
"build:watch": "tsc --build --watch",
"docs:build": "cd docs && yarn build",

View File

@ -0,0 +1,3 @@
import cf from '../dist/index.js'
export const CloudflareSocket = cf.CloudflareSocket

View File

@ -1,8 +1,8 @@
{
"name": "pg-cloudflare",
"version": "1.1.1",
"version": "1.1.2-alpha.1",
"description": "A socket implementation that can run on Cloudflare Workers using native TCP connections.",
"main": "dist/empty.js",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "MIT",
"devDependencies": {
@ -10,8 +10,11 @@
"typescript": "^4.0.3"
},
"exports": {
"workerd": "./dist/index.js",
"default": "./dist/empty.js"
".": {
"import": "./esm/index.mjs",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"scripts": {
"build": "tsc",
@ -26,6 +29,7 @@
},
"files": [
"/dist/*{js,ts,map}",
"/src"
"/src",
"/esm"
]
}

View File

@ -37,7 +37,8 @@ export class CloudflareSocket extends EventEmitter {
if (connectListener) this.once('connect', connectListener)
const options: SocketOptions = this.ssl ? { secureTransport: 'starttls' } : {}
const { connect } = await import('cloudflare:sockets')
const mod = await import('cloudflare:sockets')
const connect = mod.connect
this._cfSocket = connect(`${host}:${port}`, options)
this._cfWriter = this._cfSocket.writable.getWriter()
this._addClosedHandler()

View File

@ -1,12 +1,12 @@
{
"compilerOptions": {
"module": "ES2020",
"module": "node16",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"target": "ES2020",
"target": "es2020",
"noImplicitAny": true,
"moduleResolution": "node",
"moduleResolution": "node16",
"sourceMap": true,
"outDir": "dist",
"incremental": true,

View File

@ -0,0 +1,7 @@
// ESM wrapper for pg-connection-string
import connectionString from '../index.js'
// Re-export the parse function
export const parse = connectionString.parse
export const toClientConfig = connectionString.toClientConfig
export const parseIntoClientConfig = connectionString.parseIntoClientConfig

View File

@ -1,9 +1,17 @@
{
"name": "pg-connection-string",
"version": "2.7.0",
"version": "2.7.1-alpha.0",
"description": "Functions for dealing with a PostgresSQL connection string",
"main": "./index.js",
"types": "./index.d.ts",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./esm/index.mjs",
"require": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "istanbul cover _mocha && npm run check-coverage",
"check-coverage": "istanbul check-coverage --statements 100 --branches 100 --lines 100 --functions 100",
@ -34,6 +42,7 @@
},
"files": [
"index.js",
"index.d.ts"
"index.d.ts",
"esm"
]
}

View File

@ -0,0 +1,5 @@
// ESM wrapper for pg-cursor
import Cursor from '../index.js'
// Export as default only to match CJS module
export default Cursor

View File

@ -1,6 +1,7 @@
'use strict'
const Result = require('pg/lib/result.js')
const prepare = require('pg/lib/utils.js').prepareValue
const pg = require('pg')
const { Result, utils } = pg
const prepare = utils.prepareValue
const EventEmitter = require('events').EventEmitter
const util = require('util')

View File

@ -1,8 +1,15 @@
{
"name": "pg-cursor",
"version": "2.13.1",
"version": "2.13.2-alpha.1",
"description": "Query cursor extension for node-postgres",
"main": "index.js",
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./index.js",
"default": "./index.js"
}
},
"directories": {
"test": "test"
},
@ -18,9 +25,13 @@
"license": "MIT",
"devDependencies": {
"mocha": "^10.5.2",
"pg": "^8.14.1"
"pg": "^8.14.2-alpha.1"
},
"peerDependencies": {
"pg": "^8"
}
},
"files": [
"index.js",
"esm"
]
}

View File

@ -0,0 +1,26 @@
{
"name": "pg-esm-test",
"version": "1.0.1-alpha.1",
"description": "A test module for PostgreSQL with ESM support",
"main": "index.js",
"type": "module",
"scripts": {
"test": "node --test"
},
"keywords": [
"postgres",
"postgresql",
"esm",
"test"
],
"devDependencies": {
"pg": "^8.14.2-alpha.1",
"pg-cloudflare": "^1.1.2-alpha.1",
"pg-cursor": "^2.13.2-alpha.1",
"pg-native": "^3.3.1-alpha.0",
"pg-pool": "^3.8.1-alpha.1",
"pg-query-stream": "^4.8.2-alpha.1"
},
"author": "Brian M. Carlson <brian.m.carlson@gmail.com>",
"license": "MIT"
}

View File

@ -0,0 +1,9 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import { CloudflareSocket } from 'pg-cloudflare'
describe('pg-cloudflare', () => {
it('should export CloudflareSocket constructor', () => {
assert.ok(new CloudflareSocket())
})
})

View File

@ -0,0 +1,17 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import { parse, toClientConfig, parseIntoClientConfig } from 'pg-connection-string'
describe('pg-connection-string', () => {
it('should export parse function', () => {
assert.strictEqual(typeof parse, 'function')
})
it('should export toClientConfig function', () => {
assert.strictEqual(typeof toClientConfig, 'function')
})
it('should export parseIntoClientConfig function', () => {
assert.strictEqual(typeof parseIntoClientConfig, 'function')
})
})

View File

@ -0,0 +1,9 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import Cursor from 'pg-cursor'
describe('pg-cursor', () => {
it('should export Cursor constructor as default', () => {
assert.ok(new Cursor())
})
})

View File

@ -0,0 +1,9 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import Client from 'pg-native'
describe('pg-native', () => {
it('should export Client constructor', () => {
assert.ok(new Client())
})
})

View File

@ -0,0 +1,9 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import Pool from 'pg-pool'
describe('pg-pool', () => {
it('should export Pool constructor', () => {
assert.ok(new Pool())
})
})

View File

@ -0,0 +1,9 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import QueryStream from 'pg-query-stream'
describe('pg-query-stream', () => {
it('should export QueryStream constructor as default', () => {
assert.ok(new QueryStream())
})
})

View File

@ -0,0 +1,17 @@
import assert from 'node:assert'
import { describe, it } from 'node:test'
import pg, { Client, Pool } from 'pg'
describe('pg', () => {
it('should export Client constructor', () => {
assert.ok(new Client())
})
it('should export Pool constructor', () => {
assert.ok(new Pool())
})
it('should still provide default export', () => {
assert.ok(new pg.Pool())
})
})

View File

@ -0,0 +1,5 @@
// ESM wrapper for pg-native
import Client from '../index.js'
// Export as default only to match CJS module
export default Client

View File

@ -1,8 +1,15 @@
{
"name": "pg-native",
"version": "3.3.0",
"version": "3.3.1-alpha.0",
"description": "A slightly nicer interface to Postgres over node-libpq",
"main": "index.js",
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "mocha"
},
@ -34,5 +41,9 @@
"node-gyp": ">=10.x",
"okay": "^0.3.0",
"semver": "^4.1.0"
}
},
"files": [
"index.js",
"esm"
]
}

View File

@ -0,0 +1,5 @@
// ESM wrapper for pg-pool
import Pool from '../index.js'
// Export as default only to match CJS module
export default Pool

View File

@ -1,8 +1,15 @@
{
"name": "pg-pool",
"version": "3.8.0",
"version": "3.8.1-alpha.1",
"description": "Connection pool for node-postgres",
"main": "index.js",
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./index.js",
"default": "./index.js"
}
},
"directories": {
"test": "test"
},
@ -32,9 +39,13 @@
"expect.js": "0.3.1",
"lodash": "^4.17.11",
"mocha": "^10.5.2",
"pg-cursor": "^1.3.0"
"pg-cursor": "^2.13.2-alpha.1"
},
"peerDependencies": {
"pg": ">=8.0"
}
},
"files": [
"index.js",
"esm"
]
}

View File

@ -0,0 +1,11 @@
// ESM wrapper for pg-protocol
import protocol from '../dist/index.js'
// Re-export all the properties
export const DatabaseError = protocol.DatabaseError
export const SASL = protocol.SASL
export const serialize = protocol.serialize
export const parse = protocol.parse
// Re-export the default
export default protocol

View File

@ -1,9 +1,16 @@
{
"name": "pg-protocol",
"version": "1.8.0",
"version": "1.8.1-alpha.0",
"description": "The postgres client/server binary protocol, implemented in TypeScript",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"license": "MIT",
"devDependencies": {
"@types/chai": "^4.2.7",
@ -29,6 +36,7 @@
},
"files": [
"/dist/*{js,ts,map}",
"/src"
"/src",
"/esm"
]
}

View File

@ -1,12 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"module": "node16",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"moduleResolution": "node16",
"sourceMap": true,
"outDir": "dist",
"incremental": true,

View File

@ -0,0 +1,5 @@
// ESM wrapper for pg-query-stream
import QueryStream from '../dist/index.js'
// Export as default only to match CJS module
export default QueryStream

View File

@ -1,9 +1,16 @@
{
"name": "pg-query-stream",
"version": "4.8.1",
"version": "4.8.2-alpha.1",
"description": "Postgres query result returned as readable stream",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"scripts": {
"test": "mocha -r ts-node/register test/**/*.ts"
},
@ -21,7 +28,8 @@
],
"files": [
"/dist/*{js,ts,map}",
"/src"
"/src",
"/esm"
],
"author": "Brian M. Carlson",
"license": "MIT",
@ -37,7 +45,7 @@
"concat-stream": "~1.0.1",
"eslint-plugin-promise": "^6.0.1",
"mocha": "^10.5.2",
"pg": "^8.14.1",
"pg": "^8.14.2-alpha.1",
"stream-spec": "~0.3.5",
"ts-node": "^8.5.4",
"typescript": "^4.0.3"
@ -46,6 +54,6 @@
"pg": "^8"
},
"dependencies": {
"pg-cursor": "^2.13.1"
"pg-cursor": "^2.13.2-alpha.1"
}
}

View File

@ -1,12 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"module": "node16",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"target": "es6",
"noImplicitAny": false,
"moduleResolution": "node",
"moduleResolution": "node16",
"sourceMap": true,
"pretty": true,
"outDir": "dist",

View File

@ -54,5 +54,11 @@ test-pool:
@find test/integration/connection-pool -name "*.js" | $(node-command) binary
test-worker:
@echo "***Testing Cloudflare Worker support***"
@node test/worker/src/index.test.js
# this command only runs in node 18.x and above since there are
# worker specific items missing from the node environment in lower versions
@if [[ $(shell node --version | sed 's/v//' | cut -d'.' -f1) -ge 18 ]]; then \
echo "***Testing Cloudflare Worker support***"; \
yarn vitest run -c test/vitest.config.mts test/cloudflare/ --no-watch -- $(params); \
else \
echo "Skipping test-worker: Node.js version is less than 18."; \
fi

18
packages/pg/esm/index.mjs Normal file
View File

@ -0,0 +1,18 @@
// ESM wrapper for pg
import pg from '../lib/index.js'
// Re-export all the properties
export const Client = pg.Client
export const Pool = pg.Pool
export const Connection = pg.Connection
export const types = pg.types
export const Query = pg.Query
export const DatabaseError = pg.DatabaseError
export const escapeIdentifier = pg.escapeIdentifier
export const escapeLiteral = pg.escapeLiteral
// Also export the defaults
export const defaults = pg.defaults
// Re-export the default
export default pg

View File

@ -3,6 +3,8 @@
var Client = require('./client')
var defaults = require('./defaults')
var Connection = require('./connection')
var Result = require('./result')
var utils = require('./utils')
var Pool = require('pg-pool')
const { DatabaseError } = require('pg-protocol')
const { escapeIdentifier, escapeLiteral } = require('./utils')
@ -26,6 +28,8 @@ var PG = function (clientConstructor) {
this.DatabaseError = DatabaseError
this.escapeIdentifier = escapeIdentifier
this.escapeLiteral = escapeLiteral
this.Result = Result
this.utils = utils
}
if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {

View File

@ -1,6 +1,6 @@
{
"name": "pg",
"version": "8.14.1",
"version": "8.14.2-alpha.1",
"description": "PostgreSQL client - pure javascript & libpq with the same API",
"keywords": [
"database",
@ -19,25 +19,34 @@
},
"author": "Brian Carlson <brian.m.carlson@gmail.com>",
"main": "./lib",
"exports": {
".": {
"import": "./esm/index.mjs",
"require": "./lib/index.js",
"default": "./lib/index.js"
}
},
"dependencies": {
"pg-connection-string": "^2.7.0",
"pg-pool": "^3.8.0",
"pg-protocol": "^1.8.0",
"pg-connection-string": "^2.7.1-alpha.0",
"pg-pool": "^3.8.1-alpha.1",
"pg-protocol": "^1.8.1-alpha.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "0.8.12",
"@cloudflare/workers-types": "^4.20230404.0",
"async": "2.6.4",
"bluebird": "3.7.2",
"co": "4.6.0",
"pg-copy-streams": "0.3.0",
"typescript": "^4.0.3",
"vitest": "~3.0.9",
"workerd": "^1.20230419.0",
"wrangler": "3.58.0"
"wrangler": "^3.x"
},
"optionalDependencies": {
"pg-cloudflare": "^1.1.1"
"pg-cloudflare": "^1.1.2-alpha.1"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
@ -52,6 +61,7 @@
},
"files": [
"lib",
"esm",
"SPONSORS.md"
],
"license": "MIT",

View File

@ -0,0 +1,11 @@
import { Pool } from 'pg'
import { test } from 'vitest'
import assert from 'node:assert'
import args from '../cli'
test('default', async () => {
const pool = new Pool(args)
const result = await pool.query('SELECT $1::text as name', ['cloudflare'])
assert(result.rows[0].name === 'cloudflare')
pool.end()
})

View File

@ -16,111 +16,6 @@ process.on('uncaughtException', function (d) {
}
process.exit(-1)
})
assert.same = function (actual, expected) {
for (var key in expected) {
assert.equal(actual[key], expected[key])
}
}
assert.emits = function (item, eventName, callback, message) {
var called = false
var id = setTimeout(function () {
test("Should have called '" + eventName + "' event", function () {
assert.ok(called, message || "Expected '" + eventName + "' to be called.")
})
}, 5000)
item.once(eventName, function () {
if (eventName === 'error') {
// belt and braces test to ensure all error events return an error
assert.ok(
arguments[0] instanceof Error,
'Expected error events to throw instances of Error but found: ' + sys.inspect(arguments[0])
)
}
called = true
clearTimeout(id)
assert.ok(true)
if (callback) {
callback.apply(item, arguments)
}
})
}
assert.UTCDate = function (actual, year, month, day, hours, min, sec, milisecond) {
var actualYear = actual.getUTCFullYear()
assert.equal(actualYear, year, 'expected year ' + year + ' but got ' + actualYear)
var actualMonth = actual.getUTCMonth()
assert.equal(actualMonth, month, 'expected month ' + month + ' but got ' + actualMonth)
var actualDate = actual.getUTCDate()
assert.equal(actualDate, day, 'expected day ' + day + ' but got ' + actualDate)
var actualHours = actual.getUTCHours()
assert.equal(actualHours, hours, 'expected hours ' + hours + ' but got ' + actualHours)
var actualMin = actual.getUTCMinutes()
assert.equal(actualMin, min, 'expected min ' + min + ' but got ' + actualMin)
var actualSec = actual.getUTCSeconds()
assert.equal(actualSec, sec, 'expected sec ' + sec + ' but got ' + actualSec)
var actualMili = actual.getUTCMilliseconds()
assert.equal(actualMili, milisecond, 'expected milisecond ' + milisecond + ' but got ' + actualMili)
}
const spit = function (actual, expected) {
console.log('')
console.log('actual ' + sys.inspect(actual))
console.log('expect ' + sys.inspect(expected))
console.log('')
}
assert.equalBuffers = function (actual, expected) {
if (actual.length != expected.length) {
spit(actual, expected)
assert.equal(actual.length, expected.length)
}
for (var i = 0; i < actual.length; i++) {
if (actual[i] != expected[i]) {
spit(actual, expected)
}
assert.equal(actual[i], expected[i])
}
}
assert.empty = function (actual) {
assert.lengthIs(actual, 0)
}
assert.success = function (callback) {
if (callback.length === 1 || callback.length === 0) {
return assert.calls(function (err, arg) {
if (err) {
console.log(err)
}
assert(!err)
callback(arg)
})
} else if (callback.length === 2) {
return assert.calls(function (err, arg1, arg2) {
if (err) {
console.log(err)
}
assert(!err)
callback(arg1, arg2)
})
} else {
throw new Error('need to preserve arrity of wrapped function')
}
}
assert.lengthIs = function (actual, expectedLength) {
assert.equal(actual.length, expectedLength)
}
var expect = function (callback, timeout) {
var executed = false
timeout = timeout || parseInt(process.env.TEST_TIMEOUT) || 5000
@ -156,13 +51,6 @@ var expect = function (callback, timeout) {
throw new Error('Unsupported arrity ' + callback.length)
}
}
assert.calls = expect
assert.isNull = function (item, message) {
message = message || 'expected ' + item + ' to be null'
assert.ok(item === null, message)
}
// print out the filename
process.stdout.write(require('path').basename(process.argv[1]))
if (args.binary) process.stdout.write(' (binary)')
@ -198,6 +86,119 @@ const rejection = (promise) =>
(error) => error
)
if (Object.isExtensible(assert)) {
assert.same = function (actual, expected) {
for (var key in expected) {
assert.equal(actual[key], expected[key])
}
}
assert.emits = function (item, eventName, callback, message) {
var called = false
var id = setTimeout(function () {
test("Should have called '" + eventName + "' event", function () {
assert.ok(called, message || "Expected '" + eventName + "' to be called.")
})
}, 5000)
item.once(eventName, function () {
if (eventName === 'error') {
// belt and braces test to ensure all error events return an error
assert.ok(
arguments[0] instanceof Error,
'Expected error events to throw instances of Error but found: ' + sys.inspect(arguments[0])
)
}
called = true
clearTimeout(id)
assert.ok(true)
if (callback) {
callback.apply(item, arguments)
}
})
}
assert.UTCDate = function (actual, year, month, day, hours, min, sec, milisecond) {
var actualYear = actual.getUTCFullYear()
assert.equal(actualYear, year, 'expected year ' + year + ' but got ' + actualYear)
var actualMonth = actual.getUTCMonth()
assert.equal(actualMonth, month, 'expected month ' + month + ' but got ' + actualMonth)
var actualDate = actual.getUTCDate()
assert.equal(actualDate, day, 'expected day ' + day + ' but got ' + actualDate)
var actualHours = actual.getUTCHours()
assert.equal(actualHours, hours, 'expected hours ' + hours + ' but got ' + actualHours)
var actualMin = actual.getUTCMinutes()
assert.equal(actualMin, min, 'expected min ' + min + ' but got ' + actualMin)
var actualSec = actual.getUTCSeconds()
assert.equal(actualSec, sec, 'expected sec ' + sec + ' but got ' + actualSec)
var actualMili = actual.getUTCMilliseconds()
assert.equal(actualMili, milisecond, 'expected milisecond ' + milisecond + ' but got ' + actualMili)
}
const spit = function (actual, expected) {
console.log('')
console.log('actual ' + sys.inspect(actual))
console.log('expect ' + sys.inspect(expected))
console.log('')
}
assert.equalBuffers = function (actual, expected) {
if (actual.length != expected.length) {
spit(actual, expected)
assert.equal(actual.length, expected.length)
}
for (var i = 0; i < actual.length; i++) {
if (actual[i] != expected[i]) {
spit(actual, expected)
}
assert.equal(actual[i], expected[i])
}
}
assert.empty = function (actual) {
assert.lengthIs(actual, 0)
}
assert.success = function (callback) {
if (callback.length === 1 || callback.length === 0) {
return assert.calls(function (err, arg) {
if (err) {
console.log(err)
}
assert(!err)
callback(arg)
})
} else if (callback.length === 2) {
return assert.calls(function (err, arg1, arg2) {
if (err) {
console.log(err)
}
assert(!err)
callback(arg1, arg2)
})
} else {
throw new Error('need to preserve arrity of wrapped function')
}
}
assert.lengthIs = function (actual, expectedLength) {
assert.equal(actual.length, expectedLength)
}
assert.calls = expect
assert.isNull = function (item, message) {
message = message || 'expected ' + item + ' to be null'
assert.ok(item === null, message)
}
}
module.exports = {
Suite: Suite,
pg: require('./../lib/'),

View File

@ -0,0 +1,12 @@
import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'
export default defineWorkersConfig({
test: {
watch: false,
poolOptions: {
workers: {
wrangler: { configPath: './wrangler.jsonc' },
},
},
},
})

View File

@ -1,32 +0,0 @@
if (parseInt(process.versions.node.split('.')[0]) < 20) {
process.exit(0)
}
var helper = require('../../test-helper')
const path = require('path')
const { unstable_dev } = require('wrangler')
var suite = new helper.Suite()
const assert = require('assert')
suite.testAsync('Can run in Cloudflare Worker?', test())
async function test() {
const worker = await unstable_dev(path.resolve(__dirname, './index.ts'), {
config: path.resolve(__dirname, '../wrangler.toml'),
vars: {
...process.env,
},
experimental: {
experimentalLocal: true,
disableExperimentalWarning: true,
},
logLevel: 'ERROR',
})
try {
const resp = await worker.fetch('/')
const { rows } = await resp.json()
assert.same(rows[0].text, 'Hello, World!')
} finally {
await worker.stop()
}
}

View File

@ -1,28 +0,0 @@
import { Client } from 'pg'
export interface Env {
USER: string
PGUSER: string
PGPASSWORD: string
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url)
if (url.pathname === '/favicon.ico') return new Response(null, { status: 404 })
const params = url.searchParams
const ssl = params.has('ssl')
var client = new Client({
user: env.PGUSER || env.USER,
password: env.PGPASSWORD,
ssl,
})
await client.connect()
const resp = Response.json(await client.query('SELECT $1::text', ['Hello, World!']))
// Clean up the client, ensuring we don't kill the worker before that is completed.
ctx.waitUntil(client.end())
return resp
},
}

View File

@ -1,22 +0,0 @@
{
"compilerOptions": {
"target": "es2021",
"lib": [
"es2021"
],
"module": "es2022",
"moduleResolution": "node",
"types": [
"@cloudflare/workers-types"
],
"resolveJsonModule": true,
"allowJs": true,
"checkJs": false,
"noEmit": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
}
}

View File

@ -1,5 +0,0 @@
name = "pg-cf-test"
main = "src/index.ts"
compatibility_date = "2023-04-04"
compatibility_flags = ["tcp_sockets_support"]
node_compat = true

View File

@ -0,0 +1,48 @@
/**
* For more details on how to configure Wrangler, refer to:
* https://developers.cloudflare.com/workers/wrangler/configuration/
*/
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-first-worker",
"main": "src/index.ts",
"compatibility_date": "2025-04-07",
"compatibility_flags": ["nodejs_compat"],
"observability": {
"enabled": true
}
/**
* t
* Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
*/
// "placement": { "mode": "smart" },
/**
* Bindings
* Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform, including
* databases, object storage, AI inference, real-time communication and more.
* https://developers.cloudflare.com/workers/runtime-apis/bindings/
*/
/**
* Environment Variables
* https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
*/
// "vars": { "MY_VARIABLE": "production_value" },
/**
* Note: Use secrets to store sensitive data.
* https://developers.cloudflare.com/workers/configuration/secrets/
*/
/**
* Static Assets
* https://developers.cloudflare.com/workers/static-assets/binding/
*/
// "assets": { "directory": "./public/", "binding": "ASSETS" },
/**
* Service Bindings (communicate between multiple Workers)
* https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
*/
// "services": [{ "binding": "MY_SERVICE", "service": "my-service" }]
}

1436
yarn.lock

File diff suppressed because it is too large Load Diff