@stacksjs/defaults 0.74.28 → 0.74.29

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.
@@ -102,7 +102,6 @@ generated model types stay precise.
102
102
  | `useApi` | Generates REST actions and routes: `{ uri, routes, middleware? }` |
103
103
  | `useSearch` (alias `searchable`) | Search-engine indexing: `{ displayable, searchable, sortable, filterable }` |
104
104
  | `useSocials` | OAuth identities, e.g. `['github']` |
105
- | `useActivityLog` | Writes an `Activity` row per change |
106
105
  | `observe` | Emits `{model}:created` / `:updated` / `:deleted` events |
107
106
  | `billable` | Stripe methods (`checkout()`, `activeSubscription()`, ...) |
108
107
  | `taggable` / `categorizable` / `commentable` / `likeable` | Pivot tables and their relation methods |
@@ -63,6 +63,8 @@ const CSRF_SECURE_TRANSPORT = Symbol.for('@stacksjs/router:csrf-secure-transport
63
63
  const CSRF_HEADER_NAME = 'x-csrf-token'
64
64
  const CSRF_COOKIE_PREFIX = `${CSRF_COOKIE_NAME}=`
65
65
  const LEGACY_CSRF_COOKIE_PREFIX = 'csrf-token='
66
+ const CSRF_COOKIE_SUFFIX = '; Path=/; SameSite=Lax; Max-Age=7200'
67
+ const CSRF_COOKIE_SECURE_SUFFIX = `${CSRF_COOKIE_SUFFIX}; Secure`
66
68
  const TOKEN_BYTES = 32
67
69
  const TOKEN_HEX_LENGTH = TOKEN_BYTES * 2
68
70
  const TOKEN_RANDOM_BYTES = Buffer.allocUnsafe(TOKEN_BYTES)
@@ -81,7 +83,7 @@ const RIGHT_TOKEN_BYTES = new Uint8Array(TOKEN_HEX_LENGTH)
81
83
  */
82
84
  export function generateCsrfToken(): string {
83
85
  crypto.getRandomValues(TOKEN_RANDOM_BYTES)
84
- return TOKEN_RANDOM_BYTES.toString('hex')
86
+ return TOKEN_RANDOM_BYTES.toHex()
85
87
  }
86
88
 
87
89
  /**
@@ -131,10 +133,10 @@ function responseAlreadySeeds(response: Response): boolean {
131
133
  export function createCsrfCookie(req: Request, minted?: string): string {
132
134
  const token = minted || generateCsrfToken()
133
135
  const knownSecureTransport = (req as unknown as Record<symbol, unknown>)[CSRF_SECURE_TRANSPORT]
134
- const secure = knownSecureTransport === true || (knownSecureTransport === undefined && req.url.startsWith('https://'))
135
- ? '; Secure'
136
- : ''
137
- return `${CSRF_COOKIE_NAME}=${token}; Path=/; SameSite=Lax; Max-Age=7200${secure}`
136
+ const suffix = knownSecureTransport === true || (knownSecureTransport === undefined && req.url.startsWith('https://'))
137
+ ? CSRF_COOKIE_SECURE_SUFFIX
138
+ : CSRF_COOKIE_SUFFIX
139
+ return `${CSRF_COOKIE_PREFIX}${token}${suffix}`
138
140
  }
139
141
 
140
142
  export function seedCsrfCookieIfMissing(req: Request, response: Response, minted?: string, responseHasNoCookies = false): Response {
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.74.28",
5
+ "version": "0.74.29",
6
6
  "description": "A modern Stacks development environment.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/defaults",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.74.28",
5
+ "version": "0.74.29",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -55,7 +55,7 @@
55
55
  "dependencies": {
56
56
  "@iconify-json/f7": "^1.2.2",
57
57
  "@iconify-json/hugeicons": "^1.2.27",
58
- "@stacksjs/mobile": "^0.74.28",
58
+ "@stacksjs/mobile": "^0.74.29",
59
59
  "@stacksjs/sanitizer": "^0.2.113",
60
60
  "ts-qr-codes": "^0.1.8"
61
61
  }
@@ -19,7 +19,48 @@ const candidates = [
19
19
  join(process.cwd(), 'node_modules/@stacksjs/components/src/ui'),
20
20
  ].filter((dir): dir is string => Boolean(dir))
21
21
 
22
+ const library = candidates.find(dir => existsSync(dir)) ?? candidates[candidates.length - 1]
23
+
24
+ /**
25
+ * Component directories contributed by installed packages.
26
+ *
27
+ * Wrapped on its own rather than left to the plugin loader's catch. stx wraps
28
+ * plugin loading in `try { … } catch { console.warn(…) }`, so an exception
29
+ * raised here would drop the WHOLE plugin - and this plugin is what supplies
30
+ * the dashboard's sidebar. Degrading to "no package components" keeps the
31
+ * library and the framework defaults working.
32
+ *
33
+ * `@stacksjs/config` is imported for the resolution rather than re-implemented,
34
+ * because it carries the guard that refuses a path escaping the package.
35
+ */
36
+ function packageDirs(): string[] {
37
+ try {
38
+ // eslint-disable-next-line ts/no-require-imports
39
+ const { packageComponentRoots } = require('@stacksjs/config')
40
+ return packageComponentRoots().map((root: { dir: string }) => root.dir)
41
+ }
42
+ catch {
43
+ return []
44
+ }
45
+ }
46
+
22
47
  export default {
23
48
  name: '@stacksjs/components',
24
- components: candidates.find(dir => existsSync(dir)) ?? candidates[candidates.length - 1],
49
+ /*
50
+ * Order is the precedence, because stx searches this list and takes the
51
+ * first match.
52
+ *
53
+ * The framework's own components are listed explicitly, ahead of any
54
+ * package's. They already resolve today through stx's fallback directory, so
55
+ * naming them here changes nothing on its own - what it does is put a floor
56
+ * under the package roots, making an installed package purely ADDITIVE. A
57
+ * package shipping its own `Button.stx` gets it used where nothing else
58
+ * defines `<Button />`, and cannot quietly replace the framework's.
59
+ */
60
+ components: [
61
+ library,
62
+ // Relative to this file, which is what stx resolves plugin entries against.
63
+ 'resources/components',
64
+ ...packageDirs(),
65
+ ],
25
66
  }