Skip to content

Commit 710a8dd

Browse files
authored
Merge branch 'main' into bwilmoth/internal-external-sources
2 parents 40011cc + af01346 commit 710a8dd

File tree

5 files changed

+144
-8
lines changed

5 files changed

+144
-8
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ build/Release
5353

5454
node_modules/
5555
jspm_packages/
56+
.pnpm-lock.yaml
57+
\*.package-lock.json
5658

5759
# Snowpack dependency directory (https://snowpack.dev/)
5860

install.sh

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Function to check for jq and install if necessary
5+
check_and_install_jq() {
6+
if ! command -v jq &> /dev/null; then
7+
# Try to install jq based on the system package manager
8+
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
9+
sudo apt-get update && sudo apt-get install -y jq > /dev/null
10+
elif [[ "$OSTYPE" == "darwin"* ]]; then
11+
brew install jq > /dev/null
12+
else
13+
echo "Please install jq manually: https://stedolan.github.io/jq/download/"
14+
exit 1
15+
fi
16+
fi
17+
}
18+
19+
echo " "
20+
echo "=========================================="
21+
echo "Welcome to the StarbaseDB installation script!"
22+
echo " "
23+
echo "This script will deploy a Cloudflare Worker and create an Outerbase Starlink session."
24+
echo "If you don't have a paid Cloudflare account, your deployment will fail."
25+
echo " "
26+
echo "IMPORTANT: You _MUST_ have a paid Cloudflare account to use SQLite in Durable Objects."
27+
echo "=========================================="
28+
echo " "
29+
30+
# Step 1: Check if jq is installed
31+
check_and_install_jq
32+
33+
# Step 2: Clone the repository
34+
if ! command -v git &> /dev/null; then
35+
echo "Git is not installed. Please install Git and try again."
36+
exit 1
37+
fi
38+
39+
echo "Cloning the repository..."
40+
git clone https://github.com/Brayden/starbasedb.git > /dev/null 2>&1 || { echo "Error: Failed to clone the repository. Please check your internet connection and try again."; exit 1; }
41+
cd starbasedb || { echo "Error: Failed to change to the starbasedb directory. The clone might have failed."; exit 1; }
42+
43+
# Step 3: Generate a secure AUTHORIZATION_TOKEN and update wrangler.toml
44+
os=$(uname -s)
45+
PLATFORM_SED="sed -i ''"
46+
47+
# choose correct version of sed utility for platform
48+
case "$os" in
49+
Linux*)
50+
# GNU utilities
51+
PLATFORM_SED="sed -i"
52+
;;
53+
Darwin*)
54+
# BSD utilities (macOS)
55+
PLATFORM_SED="sed -i ''"
56+
;;
57+
*BSD*)
58+
# Other BSD variants (FreeBSD, OpenBSD, etc)
59+
PLATFORM_SED="sed -i ''"
60+
;;
61+
*)
62+
echo "Unknown operating system: $os"
63+
exit 1
64+
;;
65+
esac
66+
67+
AUTHORIZATION_TOKEN=$(openssl rand -hex 16)
68+
$PLATFORM_SED "s/AUTHORIZATION_TOKEN = \"[^\"]*\"/AUTHORIZATION_TOKEN = \"$AUTHORIZATION_TOKEN\"/" wrangler.toml
69+
70+
# Step 4: Prompt the user for Cloudflare account_id (force interaction)
71+
echo " "
72+
echo "Please enter your Cloudflare account_id (from 'wrangler whoami' or the Cloudflare dashboard):"
73+
read -r ACCOUNT_ID </dev/tty
74+
$PLATFORM_SED "s/^account_id = .*/account_id = \"$ACCOUNT_ID\"/" wrangler.toml || echo "account_id = \"$ACCOUNT_ID\"" >> wrangler.toml
75+
76+
# Step 5: Create an Outerbase Studio account
77+
ADMIN_USER="admin"
78+
ADMIN_PASS=$(openssl rand -hex 16)
79+
80+
# Step 6: Update the wrangler.toml with generated STUDIO_USER and STUDIO_PASS
81+
$PLATFORM_SED 's/# STUDIO_USER = "admin"/STUDIO_USER = "'"$ADMIN_USER"'"/' wrangler.toml
82+
$PLATFORM_SED 's/# STUDIO_PASS = "123456"/STUDIO_PASS = "'"$ADMIN_PASS"'"/' wrangler.toml
83+
84+
# Step 7: Run typegen command
85+
npm install > /dev/null 2>&1
86+
npm run cf-typegen > /dev/null 2>&1
87+
88+
# Step 8: Deploy the worker
89+
echo " "
90+
echo "Deploying your worker..."
91+
# DEPLOY_OUTPUT=$(npm run deploy 2>&1) # This will hide the output
92+
DEPLOY_OUTPUT=$(npm run deploy)
93+
94+
# Step 9: Extract the URL from the deploy output
95+
HOST_URL=$(echo "$DEPLOY_OUTPUT" | grep -oE 'https://[a-zA-Z0-9.-]+\.workers\.dev')
96+
if [ -n "$HOST_URL" ]; then
97+
echo "Worker deployed successfully at $HOST_URL."
98+
else
99+
echo "Error: Failed to extract the worker URL."
100+
echo "Verify that you are using a paid Cloudflare account and try again."
101+
exit 1
102+
fi
103+
104+
STARLINK_URL="$HOST_URL/studio"
105+
106+
# Step 10: Enjoy :)
107+
if [ -n "$STARLINK_URL" ]; then
108+
echo " "
109+
echo "=========================================="
110+
echo " "
111+
echo "Outerbase Studio user account created!"
112+
echo "Use the following URL to view your database:"
113+
echo
114+
echo "$STARLINK_URL"
115+
echo
116+
echo "Username: $ADMIN_USER"
117+
echo "Password: $ADMIN_PASS"
118+
echo
119+
echo "NOTE: You can change your Outerbase Studio password in the wrangler.toml file and redeploy."
120+
echo
121+
echo "=========================================="
122+
else
123+
echo "Error: Failed to create Outerbase Starlink session."
124+
fi

src/index.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ const DURABLE_OBJECT_ID = 'sql-durable-object';
99
export interface Env {
1010
AUTHORIZATION_TOKEN: string;
1111
DATABASE_DURABLE_OBJECT: DurableObjectNamespace;
12-
12+
REGION: string;
13+
1314
// Studio credentials
1415
STUDIO_USER?: string;
1516
STUDIO_PASS?: string;
16-
17+
1718
// External database source details
1819
EXTERNAL_DB_TYPE?: string;
1920
EXTERNAL_DB_HOST?: string;
2021
EXTERNAL_DB_NAME?: string;
2122
EXTERNAL_DB_USER?: string;
2223
EXTERNAL_DB_PASS?: string;
2324
EXTERNAL_DB_PORT?: string;
24-
25+
2526
// ## DO NOT REMOVE: TEMPLATE INTERFACE ##
2627
}
2728

@@ -100,8 +101,9 @@ export default {
100101
* Retrieve the Durable Object identifier from the environment bindings and instantiate a
101102
* Durable Object stub to interact with the Durable Object.
102103
*/
103-
let id: DurableObjectId = env.DATABASE_DURABLE_OBJECT.idFromName(DURABLE_OBJECT_ID);
104-
let stub = env.DATABASE_DURABLE_OBJECT.get(id);
104+
const region = env.REGION ?? RegionLocationHint.AUTO;
105+
const id: DurableObjectId = env.DATABASE_DURABLE_OBJECT.idFromName(DURABLE_OBJECT_ID);
106+
const stub = region !== RegionLocationHint.AUTO ? env.DATABASE_DURABLE_OBJECT.get(id, { locationHint: region as DurableObjectLocationHint }) : env.DATABASE_DURABLE_OBJECT.get(id);
105107

106108
const source: Source = request.headers.get('X-Starbase-Source') as Source ?? url.searchParams.get('source') as Source ?? 'internal';
107109
const dataSource: DataSource = {

src/operation.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ export type RawQueryResponse = {
1919

2020
export type QueryResponse = any[] | RawQueryResponse;
2121

22+
async function afterQuery(sql: string, result: any, isRaw: boolean, dataSource?: DataSource): Promise<any> {
23+
// ## DO NOT REMOVE: TEMPLATE AFTER QUERY HOOK ##
24+
25+
return result;
26+
}
27+
2228
export async function executeQuery(sql: string, params: any | undefined, isRaw: boolean, dataSource?: DataSource): Promise<QueryResponse> {
2329
if (!dataSource) {
2430
console.error('Data source not found.')
@@ -49,7 +55,7 @@ export async function executeQuery(sql: string, params: any | undefined, isRaw:
4955

5056
let results: any = await response.json();
5157
let items = results.response.results?.items;
52-
return items;
58+
return this.afterQuery(sql, items, isRaw, dataSource);
5359
}
5460
}
5561

@@ -85,7 +91,8 @@ export async function executeTransaction(queries: { sql: string; params?: any[]
8591
});
8692

8793
const result: any = await response.json();
88-
results.push(result.response.results?.items);
94+
const items = result.response.results?.items;
95+
results.push(this.afterQuery(query.sql, items, isRaw, dataSource));
8996
}
9097

9198
return results;

wrangler.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ class_name = "DatabaseDurableObject"
2424
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations
2525
[[migrations]]
2626
tag = "v1"
27-
new_sqlite_classes = ["DatabaseDurableObject"] # Array of new classes
27+
new_sqlite_classes = ["DatabaseDurableObject"]
2828

2929
[vars]
3030
AUTHORIZATION_TOKEN = "ABC123"
31+
REGION = "auto"
3132

3233
# Uncomment the section below to create a user for logging into your database UI.
3334
# You can access the Studio UI at: https://your_endpoint/studio

0 commit comments

Comments
 (0)