@everystack/server 0.4.5 → 0.4.6

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.
Files changed (3) hide show
  1. package/package.json +7 -3
  2. package/src/db.ts +10 -0
  3. package/src/plugin.ts +13 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everystack/server",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "Server runtime primitives for Lambda — event adapters, routing, SSR, image processing",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Scalable Technology, Inc. <licensing@scalable.technology>",
@@ -61,6 +61,10 @@
61
61
  "types": "./src/plugin.ts",
62
62
  "default": "./src/plugin.ts"
63
63
  },
64
+ "./provision": {
65
+ "types": "./src/provision.ts",
66
+ "default": "./src/provision.ts"
67
+ },
64
68
  "./cdn": {
65
69
  "types": "./src/cdn/index.ts",
66
70
  "default": "./src/cdn/index.ts"
@@ -152,8 +156,8 @@
152
156
  "ts-jest": "29.4.9",
153
157
  "typescript": "5.9.3",
154
158
  "@everystack/auth": "0.4.0",
155
- "@everystack/cli": "0.4.19",
156
- "@everystack/pg-tools": "0.4.0"
159
+ "@everystack/pg-tools": "0.4.0",
160
+ "@everystack/cli": "0.4.20"
157
161
  },
158
162
  "scripts": {
159
163
  "test": "jest",
package/src/db.ts CHANGED
@@ -32,6 +32,16 @@ function sstLink<T = Record<string, any>>(name: string): T | undefined {
32
32
  }
33
33
  }
34
34
 
35
+ /**
36
+ * Read ANY SST-linked resource by name, without importing `sst` — the
37
+ * bundler-safe replacement for `Resource.<Name>` (e.g. `sstResource('Updates')?.name`
38
+ * for the ssrPlugin's updatesStorage bucket). Undefined when the link is absent,
39
+ * so callers can fall through to process.env or their own config.
40
+ */
41
+ export function sstResource<T = Record<string, any>>(name: string): T | undefined {
42
+ return sstLink<T>(name);
43
+ }
44
+
35
45
  export function getDatabaseUrl(): string {
36
46
  // An EXPLICIT DATABASE_URL wins over the component-derived master. This is what
37
47
  // lets the API connection be a least-privilege role (`authenticator`) while the SST
package/src/plugin.ts CHANGED
@@ -460,8 +460,9 @@ export function ssrPlugin(options: SsrPluginOptions = {}): (ctx: PluginContext)
460
460
  // --- Database Actions Plugin ---
461
461
 
462
462
  export interface DbPluginOptions {
463
- /** Absolute path to drizzle migrations folder */
464
- migrationsFolder: string;
463
+ /** Absolute path to drizzle migrations folder. Optional — a db:sync app has no migrations;
464
+ * migrate/db:reset then answer with a clear error while provision/console/psql still work. */
465
+ migrationsFolder?: string;
465
466
  /** App-provided seed function — action only registered if provided */
466
467
  seed?: (db: any, schema: any) => Promise<any>;
467
468
  /** PostgreSQL schemas to drop during db:reset (default: ['public', 'drizzle']) */
@@ -553,8 +554,15 @@ export function dbPlugin(options: DbPluginOptions): Plugin {
553
554
  return { deps: { bucket, region: options.backupRegion ?? process.env.AWS_REGION, adminUrl } };
554
555
  };
555
556
 
557
+ // The migration-backed actions stay in the inventory even without a migrationsFolder —
558
+ // an explanatory error beats "Unknown action" pointing the operator the wrong way.
559
+ const NO_MIGRATIONS_ERROR =
560
+ 'no migrationsFolder configured — this app has no migrations (db:sync manages its schema). '
561
+ + 'To use migrations, pass migrationsFolder to dbPlugin.';
562
+
556
563
  // --- migrate ---
557
564
  actions.migrate = async (_payload, _ctx) => {
565
+ if (!options.migrationsFolder) return { error: NO_MIGRATIONS_ERROR };
558
566
  const { runMigrations } = await import('./migrate');
559
567
  return await runMigrations(opsDb, options.migrationsFolder);
560
568
  };
@@ -575,6 +583,9 @@ export function dbPlugin(options: DbPluginOptions): Plugin {
575
583
  if (ctx.environment !== 'dev') {
576
584
  return { error: 'db:reset is only available in dev environment' };
577
585
  }
586
+ // Refuse BEFORE the drop: reset replays migrations after wiping the schemas — with no
587
+ // migrations there is nothing to rebuild from, and the drop would strand the database.
588
+ if (!options.migrationsFolder) return { error: NO_MIGRATIONS_ERROR };
578
589
  const { sql } = await import('drizzle-orm');
579
590
  const schemas = options.schemas ?? ['public', 'drizzle'];
580
591
  const dropStatements = schemas