@getstrata/bootstrap 0.2.16 → 0.2.18

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.
@@ -0,0 +1,99 @@
1
+ // @bun
2
+ // ../../src/bootstrap/web/session.ts
3
+ import { createHash, randomBytes } from "crypto";
4
+
5
+ // ../../src/core/http/cookies.ts
6
+ function readRequestCookie(request, name) {
7
+ const cookies = request.cookies;
8
+ if (cookies && typeof cookies.get === "function") {
9
+ const value = cookies.get(name);
10
+ if (value) {
11
+ return value;
12
+ }
13
+ }
14
+ const header = request.headers.get("cookie");
15
+ if (!header) {
16
+ return null;
17
+ }
18
+ for (const part of header.split(";")) {
19
+ const idx = part.indexOf("=");
20
+ if (idx === -1)
21
+ continue;
22
+ const cookieName = part.slice(0, idx).trim();
23
+ if (cookieName !== name)
24
+ continue;
25
+ return decodeURIComponent(part.slice(idx + 1).trim());
26
+ }
27
+ return null;
28
+ }
29
+
30
+ // ../../src/bootstrap/web/session.ts
31
+ class CookieSessionStore {
32
+ sql;
33
+ secret;
34
+ cookieName;
35
+ maxAgeSeconds;
36
+ constructor(sql, secret, cookieName = "strata_session", maxAgeSeconds = 60 * 60 * 24 * 14) {
37
+ this.sql = sql;
38
+ this.secret = secret;
39
+ this.cookieName = cookieName;
40
+ this.maxAgeSeconds = maxAgeSeconds;
41
+ }
42
+ cookieHeader(_user, sessionId) {
43
+ const payload = `${sessionId}.${this.sign(sessionId)}`;
44
+ return this.withSecureFlag(`${this.cookieName}=${payload}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${this.maxAgeSeconds}`);
45
+ }
46
+ clearCookieHeader() {
47
+ return this.withSecureFlag(`${this.cookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`);
48
+ }
49
+ withSecureFlag(header) {
50
+ if (true) {
51
+ return header;
52
+ }
53
+ return header.includes("Secure") ? header : `${header}; Secure`;
54
+ }
55
+ async create(user) {
56
+ const id = randomBytes(32).toString("hex");
57
+ const expires = new Date(Date.now() + this.maxAgeSeconds * 1000);
58
+ await this.sql.unsafe(`INSERT INTO sessions (id, user_id, expires_at) VALUES ($1, $2, $3)`, [
59
+ id,
60
+ user.id,
61
+ expires
62
+ ]);
63
+ return id;
64
+ }
65
+ async destroy(sessionId) {
66
+ await this.sql.unsafe(`DELETE FROM sessions WHERE id = $1`, [sessionId]);
67
+ }
68
+ async read(request) {
69
+ const cookie = readRequestCookie(request, this.cookieName);
70
+ const raw = cookie ?? null;
71
+ if (!raw)
72
+ return null;
73
+ const [sessionId, signature] = raw.split(".");
74
+ if (!sessionId || !signature || signature !== this.sign(sessionId)) {
75
+ return null;
76
+ }
77
+ const rows = await this.sql.unsafe(`SELECT s.id, s.user_id, s.expires_at, u.name, u.email, u.learn_subscriber,
78
+ COALESCE(u.is_admin, false) AS is_admin
79
+ FROM sessions s
80
+ INNER JOIN users u ON u.id = s.user_id
81
+ WHERE s.id = $1 AND s.expires_at > NOW()`, [sessionId]);
82
+ const row = rows[0];
83
+ if (!row)
84
+ return null;
85
+ return {
86
+ id: row.user_id,
87
+ name: row.name,
88
+ email: row.email,
89
+ learn_subscriber: row.learn_subscriber,
90
+ is_admin: row.is_admin
91
+ };
92
+ }
93
+ sign(value) {
94
+ return createHash("sha256").update(`${value}.${this.secret}`).digest("hex").slice(0, 32);
95
+ }
96
+ }
97
+ export {
98
+ CookieSessionStore
99
+ };
@@ -0,0 +1,8 @@
1
+ // @bun
2
+ // ../../src/bootstrap/web/slug.ts
3
+ function slugify(value) {
4
+ return value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
5
+ }
6
+ export {
7
+ slugify
8
+ };
@@ -2,8 +2,6 @@
2
2
  * Stable framework surface for application modules and future package extraction.
3
3
  * Import from `@getstrata/core` (workspace) or `src/framework/public-api`.
4
4
  */
5
- export type { ServiceProvider } from "../bootstrap/contracts.ts";
6
- export { ConfigStore, resolveService, ServiceContainer, } from "../bootstrap/contracts.ts";
7
5
  export type { AdminColumn, AdminColumnType, AdminResource, AdminResourceDefinition, AdminResourceHandlers, } from "../core/admin/index.ts";
8
6
  export { AdminResourceRegistry, formatAdminValue, } from "../core/admin/index.ts";
9
7
  export type { AbilityChecker } from "../core/auth/abilityChecker.ts";
@@ -21,6 +19,9 @@ export { createScimAuthMiddleware } from "../core/auth/scimAuthMiddleware.ts";
21
19
  export { type CacheDriver, type CreateCacheStoreOptions, createCacheStore, } from "../core/cache/createCacheStore.ts";
22
20
  export { default as CacheRepository } from "../core/cache/repository.ts";
23
21
  export { CACHE_TAGS } from "../core/cache/tags.ts";
22
+ export { ConfigStore, ServiceContainer } from "../core/contracts/container.ts";
23
+ export type { ServiceProvider } from "../core/contracts/di.ts";
24
+ export { resolveService } from "../core/contracts/di.ts";
24
25
  export type { DatabaseConnection } from "../core/database/baseRepository.ts";
25
26
  export { default as BaseRepository } from "../core/database/baseRepository.ts";
26
27
  export { bindDatabaseConnection } from "../core/database/bindConnection.ts";
package/dist/index.js CHANGED
@@ -503,15 +503,27 @@ async function scheduleRunCommand() {
503
503
  }
504
504
  await runDueScheduledTasks(appSchedule);
505
505
  }
506
- // ../../src/core/contracts/applicationContext.ts
506
+ // ../../src/core/contracts/di.ts
507
+ var requiredDependencyKeys = [
508
+ "container",
509
+ "cache",
510
+ "storage"
511
+ ];
507
512
  function getRequiredDependency(dependencies, key) {
508
513
  const dependency = dependencies[key];
509
514
  if (dependency === undefined) {
510
- throw new Error(`Required dependency "${String(key)}" is not registered.`);
515
+ throw new Error(`Required dependency "${key}" is not registered.`);
511
516
  }
512
517
  return dependency;
513
518
  }
514
-
519
+ function assertAppDependenciesComplete(dependencies) {
520
+ for (const key of requiredDependencyKeys) {
521
+ getRequiredDependency(dependencies, key);
522
+ }
523
+ }
524
+ function resolveService(dependencies, token) {
525
+ return dependencies.container.resolve(token);
526
+ }
515
527
  // ../../src/core/contracts/serviceTokens.ts
516
528
  var CORE_CONFIG_TOKEN = "core.config";
517
529
  var CORE_CACHE_TOKEN = "core.cache";
@@ -595,7 +607,7 @@ var DEFAULT_CACHE_MAX_ENTRIES = 100;
595
607
  var DEFAULT_CACHE_DRIVER = "array";
596
608
  var DEFAULT_API_TOKEN = "";
597
609
  var DEFAULT_QUEUE_DRIVER = "sync";
598
- // ../../src/bootstrap/contracts.ts
610
+ // ../../src/core/contracts/container.ts
599
611
  class ServiceContainer {
600
612
  services = new Map;
601
613
  singletonFactories = new Map;
@@ -659,26 +671,6 @@ class ConfigStore {
659
671
  return this.values.has(key);
660
672
  }
661
673
  }
662
- var requiredDependencyKeys = [
663
- "container",
664
- "cache",
665
- "storage"
666
- ];
667
- function getRequiredDependency2(dependencies, key) {
668
- const dependency = dependencies[key];
669
- if (dependency === undefined) {
670
- throw new Error(`Required dependency "${key}" is not registered.`);
671
- }
672
- return dependency;
673
- }
674
- function assertAppDependenciesComplete(dependencies) {
675
- for (const key of requiredDependencyKeys) {
676
- getRequiredDependency2(dependencies, key);
677
- }
678
- }
679
- function resolveService(dependencies, token) {
680
- return dependencies.container.resolve(token);
681
- }
682
674
  // ../../src/config/auth.ts
683
675
  var authConfig = {
684
676
  allowDevHeaders: (process.env.AUTH_DEV_HEADERS ?? "true") !== "false",
@@ -5291,7 +5283,7 @@ export {
5291
5283
  prefixRouteMap,
5292
5284
  parseFormBody,
5293
5285
  mergeWebRoutes,
5294
- getRequiredDependency2 as getRequiredDependency,
5286
+ getRequiredDependency,
5295
5287
  discoverModelTableNames,
5296
5288
  createWebServer,
5297
5289
  createWebRoutes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/bootstrap",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,6 +20,11 @@
20
20
  "import": "./dist/entries/applicationRegistry.js",
21
21
  "default": "./dist/entries/applicationRegistry.js"
22
22
  },
23
+ "./cache/modelCacheTags": {
24
+ "types": "./dist/bootstrap/cache/modelCacheTags.d.ts",
25
+ "import": "./dist/entries/cache/modelCacheTags.js",
26
+ "default": "./dist/entries/cache/modelCacheTags.js"
27
+ },
23
28
  "./config": {
24
29
  "types": "./dist/bootstrap/config.d.ts",
25
30
  "import": "./dist/entries/config.js",
@@ -69,6 +74,31 @@
69
74
  "types": "./dist/bootstrap/providers/view/index.d.ts",
70
75
  "import": "./dist/entries/providers/view.js",
71
76
  "default": "./dist/entries/providers/view.js"
77
+ },
78
+ "./web/forms": {
79
+ "types": "./dist/bootstrap/web/forms.d.ts",
80
+ "import": "./dist/entries/web/forms.js",
81
+ "default": "./dist/entries/web/forms.js"
82
+ },
83
+ "./web/routing": {
84
+ "types": "./dist/bootstrap/web/routing.d.ts",
85
+ "import": "./dist/entries/web/routing.js",
86
+ "default": "./dist/entries/web/routing.js"
87
+ },
88
+ "./web/server": {
89
+ "types": "./dist/bootstrap/web/server.d.ts",
90
+ "import": "./dist/entries/web/server.js",
91
+ "default": "./dist/entries/web/server.js"
92
+ },
93
+ "./web/session": {
94
+ "types": "./dist/bootstrap/web/session.d.ts",
95
+ "import": "./dist/entries/web/session.js",
96
+ "default": "./dist/entries/web/session.js"
97
+ },
98
+ "./web/slug": {
99
+ "types": "./dist/bootstrap/web/slug.d.ts",
100
+ "import": "./dist/entries/web/slug.js",
101
+ "default": "./dist/entries/web/slug.js"
72
102
  }
73
103
  },
74
104
  "main": "./dist/index.js",
@@ -82,14 +112,14 @@
82
112
  "build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
83
113
  "build:types": "tsc -p tsconfig.types.json",
84
114
  "prepublishOnly": "bun run build",
85
- "build:subpaths": "bun build entries/applicationRegistry.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
115
+ "build:subpaths": "bun build entries/applicationRegistry.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts entries/web/forms.ts entries/web/routing.ts entries/web/server.ts entries/web/session.ts entries/web/slug.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
86
116
  "build:shims": "true"
87
117
  },
88
118
  "publishConfig": {
89
119
  "access": "public"
90
120
  },
91
121
  "peerDependencies": {
92
- "@getstrata/core": "^0.5.24",
122
+ "@getstrata/core": "^0.5.26",
93
123
  "typescript": "^5.9.0"
94
124
  }
95
125
  }