spaps 0.8.2 → 0.9.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.
@@ -10,7 +10,7 @@ services:
10
10
  - "127.0.0.1:${SPAPS_LOCAL_PORT:-3301}:8000"
11
11
  environment:
12
12
  ENV: dev
13
- DATABASE_URL: postgresql+asyncpg://postgres:postgres@spaps-dev-db:5432/spaps
13
+ DATABASE_URL: postgresql+asyncpg://postgres:${SPAPS_LOCAL_POSTGRES_PASSWORD:?Set SPAPS_LOCAL_POSTGRES_PASSWORD}@spaps-dev-db:5432/spaps
14
14
  REDIS_URL: redis://spaps-dev-redis:6379/0
15
15
  SPAPS_LOCAL_MODE: "${SPAPS_LOCAL_MODE:-true}"
16
16
  JWT_SECRET: "${JWT_SECRET:-spaps_local_dev_jwt_secret}"
@@ -40,7 +40,7 @@ services:
40
40
  restart: unless-stopped
41
41
  environment:
42
42
  POSTGRES_USER: postgres
43
- POSTGRES_PASSWORD: postgres
43
+ POSTGRES_PASSWORD: ${SPAPS_LOCAL_POSTGRES_PASSWORD:?Set SPAPS_LOCAL_POSTGRES_PASSWORD}
44
44
  POSTGRES_DB: spaps
45
45
  volumes:
46
46
  - spaps-dev-pgdata:/var/lib/postgresql/data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spaps",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Sweet Potato Authentication & Payment Service CLI - Docker Compose orchestrator for local Python/FastAPI SPAPS server with built-in admin middleware",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -12,6 +12,7 @@ const axios = require('axios');
12
12
  const os = require('os');
13
13
  const path = require('path');
14
14
  const fs = require('fs');
15
+ const crypto = require('crypto');
15
16
 
16
17
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
17
18
  const BUNDLED_RUNTIME_ROOT = path.join(PACKAGE_ROOT, 'assets', 'local-runtime');
@@ -127,11 +128,42 @@ function ensureBundledRuntime(runtimeDir) {
127
128
  }
128
129
  }
129
130
 
130
- function buildComposeEnv({ port, authBaseUrl }) {
131
+ function readOrCreateRuntimeSecret(runtimeDir, envName, fileName) {
132
+ const envValue = process.env[envName];
133
+ if (envValue) {
134
+ return envValue;
135
+ }
136
+
137
+ const secretPath = path.join(runtimeDir, fileName);
138
+ if (fs.existsSync(secretPath)) {
139
+ const existing = fs.readFileSync(secretPath, 'utf8').trim();
140
+ if (existing) {
141
+ return existing;
142
+ }
143
+ }
144
+
145
+ fs.mkdirSync(runtimeDir, { recursive: true });
146
+ const generated = crypto.randomBytes(32).toString('hex');
147
+ fs.writeFileSync(secretPath, `${generated}\n`, { mode: 0o600 });
148
+ fs.chmodSync(secretPath, 0o600);
149
+ return generated;
150
+ }
151
+
152
+ function buildComposeEnv({ port, authBaseUrl, runtimeDir = null, runtimeMode = 'repo' }) {
131
153
  const manifest = readBundledRuntimeManifest();
132
154
  const portableRuntime = manifest.portable_runtime || {};
133
- return {
155
+ const composeEnv = {
134
156
  ...process.env,
157
+ };
158
+ if (runtimeMode === 'bundle' && runtimeDir) {
159
+ composeEnv.SPAPS_LOCAL_POSTGRES_PASSWORD = readOrCreateRuntimeSecret(
160
+ runtimeDir,
161
+ 'SPAPS_LOCAL_POSTGRES_PASSWORD',
162
+ '.spaps-local-postgres-password'
163
+ );
164
+ }
165
+ return {
166
+ ...composeEnv,
135
167
  SPAPS_LOCAL_PORT: String(port),
136
168
  SPAPS_LOCAL_MODE: String(process.env.SPAPS_LOCAL_MODE ?? portableRuntime.default_local_mode ?? true),
137
169
  SPAPS_AUTH_BASE_URL:
@@ -177,7 +209,7 @@ function resolveLocalRuntime({
177
209
  runtimeDir: repoRoot,
178
210
  cwd: repoRoot,
179
211
  composeFile: path.join(repoRoot, 'docker-compose.spaps-dev.yml'),
180
- composeEnv: buildComposeEnv({ port, authBaseUrl }),
212
+ composeEnv: buildComposeEnv({ port, authBaseUrl, runtimeDir: repoRoot, runtimeMode: 'repo' }),
181
213
  projectName: path.basename(repoRoot),
182
214
  };
183
215
  }
@@ -192,7 +224,12 @@ function resolveLocalRuntime({
192
224
  runtimeDir: resolvedRuntimeDir,
193
225
  cwd: resolvedRuntimeDir,
194
226
  composeFile: path.join(resolvedRuntimeDir, 'docker-compose.yml'),
195
- composeEnv: buildComposeEnv({ port, authBaseUrl }),
227
+ composeEnv: buildComposeEnv({
228
+ port,
229
+ authBaseUrl,
230
+ runtimeDir: resolvedRuntimeDir,
231
+ runtimeMode: 'bundle',
232
+ }),
196
233
  projectName: `spaps-local-${port}`,
197
234
  };
198
235
  }