@volter/world-runtime 2.0.2 → 2.0.3

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.
package/dist/src/init.js CHANGED
@@ -632,6 +632,29 @@ export function planWorldInit(name, repoPath, options = {}) {
632
632
  const mintedEnv = [];
633
633
  const infraSignals = new Map();
634
634
  const infraEntries = [];
635
+ // SMTP's host and port under the names this app declares: apps name them their own way (twenty's EMAIL_SMTP_HOST/
636
+ // EMAIL_SMTP_PORT beside nodemailer's SMTP_HOST), and a raw-TCP twin is reached only through the env the app reads,
637
+ // so every declared `…SMTP_HOST` / `…SMTP_PORT` points at the smtp twin (twenty lane: its mail went to the log). A World
638
+ // regenerated with --force keeps its saved smtp service as it was: remove it from the config to pick these names up
639
+ const smtp = services.find((service) => service.id === 'smtp' && service.type === 'twin');
640
+ if (smtp) {
641
+ const templates = { ...(smtp.injectEnvTemplates ?? {}) };
642
+ // not the app's outbound mail: a server it listens on (INBOUND_) or a local catcher it runs (MAILHOG_, MAILPIT_)
643
+ const notOutbound = /^(?:INBOUND|INCOMING|MAILHOG|MAILPIT|MAILCATCHER|MAILDEV)_/;
644
+ for (const { name } of repoEnvEntries(repo)) {
645
+ if (name in templates || notOutbound.test(name))
646
+ continue;
647
+ if (/^(?:[A-Z0-9]+_)*SMTP_HOST$/.test(name))
648
+ templates[name] = '${host}';
649
+ else if (/^(?:[A-Z0-9]+_)*SMTP_PORT$/.test(name))
650
+ templates[name] = '${port}';
651
+ // the twin speaks plain SMTP on its port: a secure/TLS flag beside an injected host would make the app open
652
+ // implicit TLS to it and fail, so the flag says plain
653
+ else if (/^(?:[A-Z0-9]+_)*SMTP_(?:SECURE|TLS|SSL)$/.test(name))
654
+ templates[name] = 'false';
655
+ }
656
+ smtp.injectEnvTemplates = templates;
657
+ }
635
658
  // Every name a twin service above injects at boot (its endpoint env and templates).
636
659
  const worldInjected = new Set([
637
660
  ...(existing?.services ?? []),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/world-runtime",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "World configs for twins: boot named local runtimes, allocate ports, generate world.env/instance.json, and run apps against fake-key twin worlds.",
5
5
  "keywords": [
6
6
  "twin",
@@ -68,12 +68,12 @@
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@volter/world-core": "2.0.2",
71
- "@volter/world-console": "2.0.2"
71
+ "@volter/world-console": "2.0.3"
72
72
  },
73
73
  "dependencies": {
74
74
  "@electric-sql/pglite": "0.5.8",
75
75
  "@electric-sql/pglite-pgvector": "0.0.9",
76
- "@volter/world-access": "2.0.0",
76
+ "@volter/world-access": "2.0.1",
77
77
  "@volter/world-core": "2.0.2",
78
78
  "pg-gateway": "0.3.0-beta.4",
79
79
  "smol-toml": "^1.8.0"
package/src/init.ts CHANGED
@@ -831,6 +831,25 @@ export function planWorldInit(name: string, repoPath: string, options: InitOptio
831
831
  const mintedEnv: string[] = [];
832
832
  const infraSignals = new Map<string, string[]>();
833
833
  const infraEntries: Array<{ name: string; source: string; kind: string }> = [];
834
+ // SMTP's host and port under the names this app declares: apps name them their own way (twenty's EMAIL_SMTP_HOST/
835
+ // EMAIL_SMTP_PORT beside nodemailer's SMTP_HOST), and a raw-TCP twin is reached only through the env the app reads,
836
+ // so every declared `…SMTP_HOST` / `…SMTP_PORT` points at the smtp twin (twenty lane: its mail went to the log). A World
837
+ // regenerated with --force keeps its saved smtp service as it was: remove it from the config to pick these names up
838
+ const smtp = services.find((service) => service.id === 'smtp' && service.type === 'twin');
839
+ if (smtp) {
840
+ const templates = { ...(smtp.injectEnvTemplates ?? {}) };
841
+ // not the app's outbound mail: a server it listens on (INBOUND_) or a local catcher it runs (MAILHOG_, MAILPIT_)
842
+ const notOutbound = /^(?:INBOUND|INCOMING|MAILHOG|MAILPIT|MAILCATCHER|MAILDEV)_/;
843
+ for (const { name } of repoEnvEntries(repo)) {
844
+ if (name in templates || notOutbound.test(name)) continue;
845
+ if (/^(?:[A-Z0-9]+_)*SMTP_HOST$/.test(name)) templates[name] = '${host}';
846
+ else if (/^(?:[A-Z0-9]+_)*SMTP_PORT$/.test(name)) templates[name] = '${port}';
847
+ // the twin speaks plain SMTP on its port: a secure/TLS flag beside an injected host would make the app open
848
+ // implicit TLS to it and fail, so the flag says plain
849
+ else if (/^(?:[A-Z0-9]+_)*SMTP_(?:SECURE|TLS|SSL)$/.test(name)) templates[name] = 'false';
850
+ }
851
+ smtp.injectEnvTemplates = templates;
852
+ }
834
853
  // Every name a twin service above injects at boot (its endpoint env and templates).
835
854
  const worldInjected = new Set([
836
855
  ...(existing?.services ?? []),