Skip to content

Commit 4e47108

Browse files
local supabase vol 1
1 parent 60b9e6b commit 4e47108

File tree

12 files changed

+731
-1
lines changed

12 files changed

+731
-1
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,78 @@ Add screenshots or GIFs here to showcase the reader and admin interfaces.
5858
- Node.js (v18 or later)
5959
- npm (v10 or later)
6060
- Angular CLI (v19 or later)
61+
- Docker (for local Supabase setup)
6162

6263
### Installation Steps
6364
1. Clone the repository:
6465
```bash
6566
git clone https://github.com/Lukecsharpwalker/angularBlog.git
6667
cd angularBlog
68+
```
69+
70+
2. Install dependencies:
71+
```bash
72+
npm install
73+
```
74+
75+
3. Set up local Supabase (optional, but recommended for development):
76+
77+
**For Unix/macOS users:**
78+
```bash
79+
npm run setup:local-supabase
80+
```
81+
82+
**For Windows users:**
83+
```powershell
84+
npm run setup:local-supabase:win
85+
```
86+
87+
This command will:
88+
- Initialize a local Supabase instance using Docker
89+
- Create the necessary database tables
90+
- Create an admin user for testing (email: admin@example.com, password: admin123)
91+
92+
4. Start the application with local Supabase:
93+
```bash
94+
npm run start:local
95+
```
96+
Or use the cloud Supabase instance:
97+
```bash
98+
npm start
99+
```
100+
101+
### Supabase Management
102+
- To stop the local Supabase instance:
103+
```bash
104+
supabase stop
105+
```
106+
- To start it again:
107+
```bash
108+
supabase start
109+
```
110+
- To access Supabase Studio (admin interface):
111+
Open http://localhost:54323 in your browser
112+
113+
### Syncing from Cloud Supabase
114+
You can sync your local Supabase instance with the cloud instance to get the latest schema, policies, and data:
115+
116+
**For Unix/macOS users:**
117+
```bash
118+
npm run sync:cloud-supabase
119+
```
120+
121+
**For Windows users:**
122+
```powershell
123+
npm run sync:cloud-supabase:win
124+
```
125+
126+
This command will:
127+
- Link your local Supabase project to the remote project
128+
- Pull the database schema and policies from the cloud
129+
- Dump data from the remote database
130+
- Apply the schema and data to your local instance
131+
132+
This is useful for:
133+
- Getting the latest database structure during development
134+
- Testing with real data from the production environment
135+
- Ensuring your local environment matches the cloud environment

angular.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@
7474
"with": "src/environments/environment.development.ts"
7575
}
7676
]
77+
},
78+
"local": {
79+
"optimization": false,
80+
"extractLicenses": false,
81+
"sourceMap": true,
82+
"fileReplacements": [
83+
{
84+
"replace": "src/environments/environment.ts",
85+
"with": "src/environments/environment.local.ts"
86+
}
87+
]
7788
}
7889
},
7990
"defaultConfiguration": "production"
@@ -86,6 +97,9 @@
8697
},
8798
"development": {
8899
"buildTarget": "angularblogapp:build:development"
100+
},
101+
"local": {
102+
"buildTarget": "angularblogapp:build:local"
89103
}
90104
},
91105
"defaultConfiguration": "development"

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
"test": "ng test",
1010
"serve:ssr:AngularBlogApp": "node dist/angular-blog-app/server/server.mjs",
1111
"build:stats": "ng build --stats-json",
12-
"analyze": "webpack-bundle-analyzer dist/angular-blog-app/stats.json"
12+
"analyze": "webpack-bundle-analyzer dist/angular-blog-app/stats.json",
13+
"setup:local-supabase": "bash scripts/setup-local-supabase.sh",
14+
"setup:local-supabase:win": "powershell -ExecutionPolicy Bypass -File scripts/setup-local-supabase.ps1",
15+
"sync:cloud-supabase": "bash scripts/sync-from-cloud-supabase.sh",
16+
"sync:cloud-supabase:win": "powershell -ExecutionPolicy Bypass -File scripts/sync-from-cloud-supabase.ps1",
17+
"start:local": "ng serve --configuration=local"
1318
},
1419
"private": true,
1520
"dependencies": {

reset-password.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"use strict";
2+
/**********************************************************************
3+
* reset-password.ts
4+
* -------------------------------------------------
5+
* Resets a Supabase user’s password via the Admin API.
6+
* -------------------------------------------------
7+
* USAGE (bash):
8+
* export SUPABASE_URL="https://aqdbdmepncxxuanlymwr.supabase.co"
9+
* export SERVICE_ROLE_KEY="YOUR_SERVICE_ROLE_KEY_HERE"
10+
* npx ts-node reset-password.ts \
11+
* a3b3cf93-6956-41c7-bec0-1qwqwd42f26 'N3w-Pa$$w0rd!'
12+
*********************************************************************/
13+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15+
return new (P || (P = Promise))(function (resolve, reject) {
16+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19+
step((generator = generator.apply(thisArg, _arguments || [])).next());
20+
});
21+
};
22+
var __generator = (this && this.__generator) || function (thisArg, body) {
23+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25+
function verb(n) { return function (v) { return step([n, v]); }; }
26+
function step(op) {
27+
if (f) throw new TypeError("Generator is already executing.");
28+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
29+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30+
if (y = 0, t) op = [op[0] & 2, t.value];
31+
switch (op[0]) {
32+
case 0: case 1: t = op; break;
33+
case 4: _.label++; return { value: op[1], done: false };
34+
case 5: _.label++; y = op[1]; op = [0]; continue;
35+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
36+
default:
37+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41+
if (t[2]) _.ops.pop();
42+
_.trys.pop(); continue;
43+
}
44+
op = body.call(thisArg, _);
45+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47+
}
48+
};
49+
Object.defineProperty(exports, "__esModule", { value: true });
50+
var supabase_js_1 = require("@supabase/supabase-js");
51+
var _a = process.argv, userId = _a[2], newPassword = _a[3];
52+
if (!userId || !newPassword) {
53+
console.error('Usage: ts-node reset-password.ts <userId> <newPassword>');
54+
process.exit(1);
55+
}
56+
var SUPABASE_URL = process.env.SUPABASE_URL;
57+
var SERVICE_ROLE_KEY = process.env.SERVICE_ROLE_KEY;
58+
if (!SUPABASE_URL || !SERVICE_ROLE_KEY) {
59+
console.error('Set SUPABASE_URL and SERVICE_ROLE_KEY environment variables.');
60+
process.exit(1);
61+
}
62+
(function () { return __awaiter(void 0, void 0, void 0, function () {
63+
var admin, _a, data, error;
64+
return __generator(this, function (_b) {
65+
switch (_b.label) {
66+
case 0:
67+
admin = (0, supabase_js_1.createClient)(SUPABASE_URL, SERVICE_ROLE_KEY, {
68+
auth: { autoRefreshToken: false, persistSession: false },
69+
});
70+
return [4 /*yield*/, admin.auth.admin.updateUserById(userId, {
71+
password: newPassword,
72+
})];
73+
case 1:
74+
_a = _b.sent(), data = _a.data, error = _a.error;
75+
if (error) {
76+
console.error('❌ Failed to reset password:', error.message);
77+
process.exit(1);
78+
}
79+
console.log("\u2705 Password updated for user ".concat(data === null || data === void 0 ? void 0 : data.id));
80+
return [2 /*return*/];
81+
}
82+
});
83+
}); })();

scripts/setup-local-supabase.ps1

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# PowerShell script for setting up local Supabase instance for Angular Blog App
2+
# Windows-compatible version of setup-local-supabase.sh
3+
#
4+
# Note: If running this script directly (not through npm), you may need to change the execution policy:
5+
# Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
6+
7+
# Stop on error
8+
$ErrorActionPreference = "Stop"
9+
10+
Write-Host "Setting up local Supabase instance for Angular Blog App..."
11+
12+
# Check if Supabase CLI is installed
13+
try {
14+
$null = Get-Command supabase -ErrorAction Stop
15+
Write-Host "Supabase CLI is already installed."
16+
} catch {
17+
Write-Host "Supabase CLI is not installed. Installing..."
18+
npm install -g supabase
19+
}
20+
21+
# Check if Docker is running
22+
try {
23+
$null = docker info
24+
} catch {
25+
Write-Host "Docker is not running. Please start Docker and try again."
26+
exit 1
27+
}
28+
29+
# Initialize Supabase if not already initialized
30+
if (-not (Test-Path "supabase\.branches")) {
31+
Write-Host "Initializing Supabase..."
32+
supabase init
33+
}
34+
35+
# Start Supabase
36+
Write-Host "Starting Supabase..."
37+
supabase start
38+
39+
# Wait for Supabase to be ready
40+
Write-Host "Waiting for Supabase to be ready..."
41+
Start-Sleep -Seconds 5
42+
43+
# Apply schema
44+
Write-Host "Applying database schema..."
45+
supabase db reset --db-url postgresql://postgres:postgres@localhost:54322/postgres
46+
47+
# Create a local environment file for development
48+
if (-not (Test-Path "src\environments\environment.local.ts")) {
49+
Write-Host "Creating local environment file..."
50+
$envContent = @"
51+
export const environment = {
52+
production: false,
53+
supabaseUrl: 'http://localhost:54321',
54+
supabaseKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
55+
};
56+
"@
57+
Set-Content -Path "src\environments\environment.local.ts" -Value $envContent
58+
}
59+
60+
# Print success message
61+
Write-Host "Local Supabase instance is now running!"
62+
Write-Host "Admin user credentials:"
63+
Write-Host " Email: admin@example.com"
64+
Write-Host " Password: admin123"
65+
Write-Host ""
66+
Write-Host "Supabase Studio: http://localhost:54323"
67+
Write-Host "API URL: http://localhost:54321"
68+
Write-Host ""
69+
Write-Host "To use the local Supabase instance in your Angular app, run:"
70+
Write-Host " ng serve --configuration=local"
71+
Write-Host ""
72+
Write-Host "To stop Supabase, run:"
73+
Write-Host " supabase stop"

scripts/setup-local-supabase.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
#!/bin/bash
3+
4+
# Exit on error
5+
set -e
6+
7+
echo "Setting up local Supabase instance for Angular Blog App..."
8+
9+
# Check if Supabase CLI is installed
10+
if ! command -v supabase &> /dev/null; then
11+
echo "Supabase CLI is not installed. Installing..."
12+
npm install -g supabase
13+
fi
14+
15+
# Check if Docker is running
16+
if ! docker info &> /dev/null; then
17+
echo "Docker is not running. Please start Docker and try again."
18+
exit 1
19+
fi
20+
21+
# Initialize Supabase if not already initialized
22+
if [ ! -f "supabase/.branches" ]; then
23+
echo "Initializing Supabase..."
24+
supabase init
25+
fi
26+
27+
# Start Supabase
28+
echo "Starting Supabase..."
29+
supabase start
30+
31+
# Wait for Supabase to be ready
32+
echo "Waiting for Supabase to be ready..."
33+
sleep 5
34+
35+
# Apply schema
36+
echo "Applying database schema..."
37+
supabase db reset --db-url postgresql://postgres:postgres@localhost:54322/postgres
38+
39+
# Create a local environment file for development
40+
if [ ! -f "src/environments/environment.local.ts" ]; then
41+
echo "Creating local environment file..."
42+
cat > src/environments/environment.local.ts << EOL
43+
export const environment = {
44+
production: false,
45+
supabaseUrl: 'http://localhost:54321',
46+
supabaseKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
47+
};
48+
EOL
49+
fi
50+
51+
# Print success message
52+
echo "Local Supabase instance is now running!"
53+
echo "Admin user credentials:"
54+
echo " Email: admin@example.com"
55+
echo " Password: admin123"
56+
echo ""
57+
echo "Supabase Studio: http://localhost:54323"
58+
echo "API URL: http://localhost:54321"
59+
echo ""
60+
echo "To use the local Supabase instance in your Angular app, run:"
61+
echo " ng serve --configuration=local"
62+
echo ""
63+
echo "To stop Supabase, run:"
64+
echo " supabase stop"
65+
66+
# Make the script executable
67+
chmod +x scripts/setup-local-supabase.sh

0 commit comments

Comments
 (0)