@cosmicdrift/kumiko-dev-server 0.377.0 → 0.378.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.
@@ -4,6 +4,7 @@ import { type BillingFoundationOptions } from "@cosmicdrift/kumiko-bundled-featu
4
4
  import { type CreateCapOverviewOptions } from "@cosmicdrift/kumiko-bundled-features/cap-overview";
5
5
  import { type LegalPagesOptions } from "@cosmicdrift/kumiko-bundled-features/legal-pages";
6
6
  import { type SubscriptionMollieOptions } from "@cosmicdrift/kumiko-bundled-features/subscription-mollie";
7
+ import { type TemplateResolverOptions } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
7
8
  import { type CreateTierEngineOptions } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
8
9
  import { type UserDataRightsOptions } from "@cosmicdrift/kumiko-bundled-features/user-data-rights";
9
10
  import { type WaitlistOptions } from "@cosmicdrift/kumiko-bundled-features/waitlist";
@@ -72,6 +73,8 @@ export type RendererStackOptions = {
72
73
  readonly mailFooter?: MailFooterResolver;
73
74
  /** Word after the tenant name in the mail's brand row, e.g. "Status". */
74
75
  readonly mailBrandSuffix?: MailBrandSuffixResolver;
76
+ /** Passed to createTemplateResolverFeature, e.g. `tenantEditable` to let a TenantAdmin edit chosen templates. */
77
+ readonly templateResolver?: TemplateResolverOptions;
75
78
  };
76
79
  export declare function composeRendererStack(options?: RendererStackOptions): FeatureDefinition[];
77
80
  /** Tenant mail transports reach users through channel-email, so the stack needs `mail`. */
@@ -32,7 +32,7 @@ import { createRateLimitingFeature } from "@cosmicdrift/kumiko-bundled-features/
32
32
  import { createRendererFoundationFeature } from "@cosmicdrift/kumiko-bundled-features/renderer-foundation";
33
33
  import { createSessionsFeature } from "@cosmicdrift/kumiko-bundled-features/sessions";
34
34
  import { createSubscriptionMollieFeature, } from "@cosmicdrift/kumiko-bundled-features/subscription-mollie";
35
- import { createTemplateResolverFeature } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
35
+ import { createTemplateResolverFeature, } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
36
36
  import { createTenantLifecycleFeature } from "@cosmicdrift/kumiko-bundled-features/tenant-lifecycle";
37
37
  import { createTierEngineFeature, } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
38
38
  import { createUserDataRightsFeature, } from "@cosmicdrift/kumiko-bundled-features/user-data-rights";
@@ -64,7 +64,7 @@ export function composePagesStack(options = {}) {
64
64
  }
65
65
  export function composeRendererStack(options = {}) {
66
66
  return [
67
- createTemplateResolverFeature(),
67
+ createTemplateResolverFeature(options.templateResolver),
68
68
  createRendererFoundationFeature(),
69
69
  createRendererMailHtmlFeature({
70
70
  ...(options.mailFooter !== undefined && { footer: options.mailFooter }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.377.0",
3
+ "version": "0.378.0",
4
4
  "description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding. Its compose-stacks/env-schema subpaths are consumed at prod boot too — see @cosmicdrift/kumiko-server-runtime for the prod runner itself.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -77,14 +77,14 @@
77
77
  "kumiko-upgrade": "./bin/kumiko-upgrade.ts"
78
78
  },
79
79
  "dependencies": {
80
- "@cosmicdrift/kumiko-bundled-features": "0.377.0",
81
- "@cosmicdrift/kumiko-framework": "0.377.0",
82
- "@cosmicdrift/kumiko-renderer": "0.377.0",
83
- "@cosmicdrift/kumiko-renderer-mail-html": "0.377.0",
84
- "@cosmicdrift/kumiko-guards": "0.377.0",
85
- "@cosmicdrift/kumiko-server-runtime": "0.377.0",
86
- "@cosmicdrift/kumiko-testing": "0.377.0",
87
- "@cosmicdrift/kumiko-types": "0.377.0",
80
+ "@cosmicdrift/kumiko-bundled-features": "0.378.0",
81
+ "@cosmicdrift/kumiko-framework": "0.378.0",
82
+ "@cosmicdrift/kumiko-renderer": "0.378.0",
83
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.378.0",
84
+ "@cosmicdrift/kumiko-guards": "0.378.0",
85
+ "@cosmicdrift/kumiko-server-runtime": "0.378.0",
86
+ "@cosmicdrift/kumiko-testing": "0.378.0",
87
+ "@cosmicdrift/kumiko-types": "0.378.0",
88
88
  "bun-types": "^1.3.13",
89
89
  "ts-morph": "^28.0.0",
90
90
  "zod": "^4.4.3"
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.378.0",
4
+ "type": "improvement",
5
+ "title": "composeRendererStack forwards templateResolver options",
6
+ "detail": "RendererStackOptions.templateResolver is passed to createTemplateResolverFeature, so an app can set tenantEditable."
7
+ },
2
8
  {
3
9
  "version": "0.376.0",
4
10
  "type": "improvement",
@@ -8,15 +8,35 @@ fi
8
8
  # Walk up so a worktree without its own node_modules resolves via the parent
9
9
  # install, but not past an enclosing repository: a bin above that boundary
10
10
  # belongs to another project. `[ -x ]` also skips a broken (uninstalled) symlink.
11
+ # A bin in an ancestor that is owned by someone else or group/world-writable
12
+ # (/tmp, /Users/Shared) is attacker-plantable and must never be exec'd, and
13
+ # $HOME is the upper trust boundary (inclusive), compared by physical path
14
+ # because git prints REPO_ROOT resolved: a trailing slash or a symlinked home
15
+ # would otherwise never match and the walk would continue to /.
16
+ HOME_BOUND=""
17
+ if [ -n "$HOME" ] && [ -d "$HOME" ]; then
18
+ HOME_BOUND="$(cd "$HOME" 2>/dev/null && pwd -P)"
19
+ fi
11
20
  BIN=""
12
21
  DIR="$REPO_ROOT"
13
22
  while true; do
14
- CANDIDATE="$DIR/node_modules/.bin/kumiko-pre-push"
15
- if [ -x "$CANDIDATE" ]; then
16
- BIN="$CANDIDATE"
17
- break
23
+ TRUSTED=1
24
+ if [ "$DIR" != "$REPO_ROOT" ]; then
25
+ if [ ! -O "$DIR" ] || [ -n "$(find "$DIR" -maxdepth 0 \( -perm -0020 -o -perm -0002 \) -print 2>/dev/null)" ]; then
26
+ TRUSTED=0
27
+ fi
28
+ fi
29
+ if [ "$TRUSTED" = 1 ]; then
30
+ BIN_DIR="$DIR/node_modules/.bin"
31
+ CANDIDATE="$BIN_DIR/kumiko-pre-push"
32
+ # The bin dir itself must be user-owned and not group/world-writable, or a
33
+ # planted entry could replace the real bin.
34
+ if [ -x "$CANDIDATE" ] && [ -O "$BIN_DIR" ] && [ -z "$(find "$BIN_DIR" -maxdepth 0 \( -perm -0020 -o -perm -0002 \) -print 2>/dev/null)" ]; then
35
+ BIN="$CANDIDATE"
36
+ break
37
+ fi
18
38
  fi
19
- if [ "$DIR" = "/" ]; then
39
+ if [ "$DIR" = "/" ] || { [ -n "$HOME_BOUND" ] && [ "$DIR" = "$HOME_BOUND" ]; }; then
20
40
  break
21
41
  fi
22
42
  if [ "$DIR" != "$REPO_ROOT" ] && [ -e "$DIR/.git" ]; then