run402 3.5.5 → 3.5.7

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/README.md CHANGED
@@ -170,6 +170,8 @@ run402 email send --to user@example.com --subject "Welcome" --html "<h1>Hi</h1>"
170
170
  run402 email send --to user@example.com --template notification --var project_name="My App"
171
171
  ```
172
172
 
173
+ For Run402 Core, use the same commands after `run402 init --api-base=http://my-core:4020`. The Core gateway operator must configure an outbound provider such as SES first; `run402 email mailboxes` surfaces `provider_readiness`, `can_send`, `send_blocked_reason`, and `next_actions` when setup is missing. Core's first email slice supports raw outbound mail with attachments; managed templates, inbound reply handling, sender-domain automation, and delivery operations may remain Cloud-only until the Core gateway adds those capabilities.
174
+
173
175
  ### Image generation
174
176
 
175
177
  ```bash
@@ -191,11 +191,28 @@ export function getApiTargetKind() {
191
191
  const cfg = readApiTargetConfig();
192
192
  return cfg?.target_kind ?? "unknown";
193
193
  }
194
+ function stripTrailingSlashes(value) {
195
+ return value.replace(/\/+$/, "");
196
+ }
197
+ function isExplicitHttpCoreTarget(apiBase) {
198
+ if (stripTrailingSlashes(apiBase) === stripTrailingSlashes(DEFAULT_API_BASE))
199
+ return false;
200
+ try {
201
+ return new URL(apiBase).protocol === "http:";
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ }
194
207
  export function isCoreApiTarget() {
208
+ const apiBase = getApiBase();
195
209
  const cfg = readApiTargetConfig();
196
- if (cfg?.target_kind !== "core" || !cfg.api_base)
197
- return false;
198
- return getApiBase().replace(/\/+$/, "") === cfg.api_base.replace(/\/+$/, "");
210
+ if (cfg?.target_kind === "core" && cfg.api_base) {
211
+ return stripTrailingSlashes(apiBase) === stripTrailingSlashes(cfg.api_base);
212
+ }
213
+ if (process.env.RUN402_API_BASE !== undefined && isExplicitHttpCoreTarget(apiBase))
214
+ return true;
215
+ return false;
199
216
  }
200
217
  export function getAllowancePath() {
201
218
  if (process.env.RUN402_ALLOWANCE_PATH)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "3.5.5",
3
+ "version": "3.5.7",
4
4
  "description": "CLI for Run402 — provision Postgres databases, deploy static sites, generate images, and manage wallets via x402 and MPP micropayments.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -191,11 +191,28 @@ export function getApiTargetKind() {
191
191
  const cfg = readApiTargetConfig();
192
192
  return cfg?.target_kind ?? "unknown";
193
193
  }
194
+ function stripTrailingSlashes(value) {
195
+ return value.replace(/\/+$/, "");
196
+ }
197
+ function isExplicitHttpCoreTarget(apiBase) {
198
+ if (stripTrailingSlashes(apiBase) === stripTrailingSlashes(DEFAULT_API_BASE))
199
+ return false;
200
+ try {
201
+ return new URL(apiBase).protocol === "http:";
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ }
194
207
  export function isCoreApiTarget() {
208
+ const apiBase = getApiBase();
195
209
  const cfg = readApiTargetConfig();
196
- if (cfg?.target_kind !== "core" || !cfg.api_base)
197
- return false;
198
- return getApiBase().replace(/\/+$/, "") === cfg.api_base.replace(/\/+$/, "");
210
+ if (cfg?.target_kind === "core" && cfg.api_base) {
211
+ return stripTrailingSlashes(apiBase) === stripTrailingSlashes(cfg.api_base);
212
+ }
213
+ if (process.env.RUN402_API_BASE !== undefined && isExplicitHttpCoreTarget(apiBase))
214
+ return true;
215
+ return false;
199
216
  }
200
217
  export function getAllowancePath() {
201
218
  if (process.env.RUN402_ALLOWANCE_PATH)
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
@@ -658,6 +658,16 @@ function contentRefToWire(ref) {
658
658
  ...(ref.integrity ? { integrity: ref.integrity } : {}),
659
659
  };
660
660
  }
661
+ function contentRefToCoreSpec(ref) {
662
+ const maybeWire = ref;
663
+ const contentType = ref.contentType ?? maybeWire.content_type;
664
+ return {
665
+ sha256: ref.sha256,
666
+ size: ref.size,
667
+ ...(contentType ? { contentType } : {}),
668
+ ...(ref.integrity ? { integrity: ref.integrity } : {}),
669
+ };
670
+ }
661
671
  function requireContentRef(ref, resource) {
662
672
  if (ref)
663
673
  return ref;
@@ -675,6 +685,12 @@ function fileSetToWire(map) {
675
685
  out[path] = contentRefToWire(ref);
676
686
  return out;
677
687
  }
688
+ function fileSetToCoreSpec(map) {
689
+ const out = {};
690
+ for (const [path, ref] of Object.entries(map))
691
+ out[path] = contentRefToCoreSpec(ref);
692
+ return out;
693
+ }
678
694
  function requireRoleToWire(gate) {
679
695
  return {
680
696
  table: gate.table,
@@ -686,6 +702,21 @@ function requireRoleToWire(gate) {
686
702
  ...(gate.signInPath !== undefined ? { sign_in_path: gate.signInPath } : {}),
687
703
  };
688
704
  }
705
+ function functionToCoreSpec(fn) {
706
+ return {
707
+ ...(fn.runtime !== undefined ? { runtime: fn.runtime } : {}),
708
+ ...(fn.source !== undefined ? { source: contentRefToCoreSpec(fn.source) } : {}),
709
+ ...(fn.files !== undefined ? { files: fileSetToCoreSpec(fn.files) } : {}),
710
+ ...(fn.entrypoint !== undefined ? { entrypoint: fn.entrypoint } : {}),
711
+ ...(fn.config !== undefined ? { config: fn.config } : {}),
712
+ ...(fn.deps !== undefined ? { deps: fn.deps } : {}),
713
+ ...(fn.schedule !== undefined ? { schedule: fn.schedule } : {}),
714
+ ...(fn.requireAuth !== undefined ? { requireAuth: fn.requireAuth } : {}),
715
+ ...(fn.requireRole !== undefined ? { requireRole: fn.requireRole } : {}),
716
+ ...(fn.class !== undefined ? { class: fn.class } : {}),
717
+ ...(fn.capabilities !== undefined ? { capabilities: fn.capabilities } : {}),
718
+ };
719
+ }
689
720
  function functionToWire(fn) {
690
721
  return {
691
722
  ...(fn.runtime !== undefined ? { runtime: fn.runtime } : {}),
@@ -716,6 +747,25 @@ function functionMapToWire(map) {
716
747
  out[name] = functionToWire(fn);
717
748
  return out;
718
749
  }
750
+ function functionMapToCoreSpec(map) {
751
+ const out = {};
752
+ for (const [name, fn] of Object.entries(map))
753
+ out[name] = functionToCoreSpec(fn);
754
+ return out;
755
+ }
756
+ function functionsToCoreSpec(functions) {
757
+ return {
758
+ ...(functions.replace !== undefined ? { replace: functionMapToCoreSpec(functions.replace) } : {}),
759
+ ...(functions.patch !== undefined
760
+ ? {
761
+ patch: {
762
+ ...(functions.patch.set !== undefined ? { set: functionMapToCoreSpec(functions.patch.set) } : {}),
763
+ ...(functions.patch.delete !== undefined ? { delete: functions.patch.delete } : {}),
764
+ },
765
+ }
766
+ : {}),
767
+ };
768
+ }
719
769
  function databaseToWire(database) {
720
770
  return {
721
771
  ...(database.expose !== undefined ? { expose: database.expose } : {}),
@@ -734,6 +784,24 @@ function databaseToWire(database) {
734
784
  : {}),
735
785
  };
736
786
  }
787
+ function databaseToCoreSpec(database) {
788
+ return {
789
+ ...(database.expose !== undefined ? { expose: database.expose } : {}),
790
+ ...(database.zero_downtime !== undefined ? { zero_downtime: database.zero_downtime } : {}),
791
+ ...(database.migrations !== undefined
792
+ ? {
793
+ migrations: database.migrations.map((m) => ({
794
+ id: m.id,
795
+ checksum: m.checksum,
796
+ ...(m.sql !== undefined
797
+ ? { sql: m.sql }
798
+ : { sql_ref: contentRefToCoreSpec(requireContentRef(m.sql_ref, `database.migrations.${m.id}.sql_ref`)) }),
799
+ ...(m.transaction !== undefined ? { transaction: m.transaction } : {}),
800
+ })),
801
+ }
802
+ : {}),
803
+ };
804
+ }
737
805
  function functionsToWire(functions) {
738
806
  return {
739
807
  ...(functions.replace !== undefined ? { replace: functionMapToWire(functions.replace) } : {}),
@@ -747,6 +815,24 @@ function functionsToWire(functions) {
747
815
  : {}),
748
816
  };
749
817
  }
818
+ function siteToCoreSpec(site) {
819
+ if ("replace" in site && site.replace) {
820
+ return {
821
+ replace: fileSetToCoreSpec(site.replace),
822
+ ...(site.public_paths ? { public_paths: site.public_paths } : {}),
823
+ };
824
+ }
825
+ if ("patch" in site && site.patch) {
826
+ return {
827
+ patch: {
828
+ ...(site.patch.put ? { put: fileSetToCoreSpec(site.patch.put) } : {}),
829
+ ...(site.patch.delete ? { delete: site.patch.delete } : {}),
830
+ },
831
+ ...(site.public_paths ? { public_paths: site.public_paths } : {}),
832
+ };
833
+ }
834
+ return { public_paths: site.public_paths };
835
+ }
750
836
  function siteToWire(site) {
751
837
  if ("replace" in site && site.replace) {
752
838
  return {
@@ -773,6 +859,21 @@ function i18nToWire(i18n) {
773
859
  ...(i18n.unknownLocalePolicy !== undefined ? { unknown_locale_policy: i18n.unknownLocalePolicy } : {}),
774
860
  };
775
861
  }
862
+ function releaseSpecToCoreSpec(spec) {
863
+ return {
864
+ project: spec.project,
865
+ ...(spec.base !== undefined ? { base: spec.base } : {}),
866
+ ...(spec.database !== undefined ? { database: databaseToCoreSpec(spec.database) } : {}),
867
+ ...(spec.secrets !== undefined ? { secrets: spec.secrets } : {}),
868
+ ...(spec.functions !== undefined ? { functions: functionsToCoreSpec(spec.functions) } : {}),
869
+ ...(spec.site !== undefined ? { site: siteToCoreSpec(spec.site) } : {}),
870
+ ...(spec.subdomains !== undefined ? { subdomains: spec.subdomains } : {}),
871
+ ...(spec.routes !== undefined ? { routes: spec.routes } : {}),
872
+ ...(spec.checks !== undefined ? { checks: spec.checks } : {}),
873
+ ...(spec.assets !== undefined ? { assets: spec.assets } : {}),
874
+ ...(spec.i18n !== undefined ? { i18n: spec.i18n } : {}),
875
+ };
876
+ }
776
877
  function releaseSpecToWire(spec) {
777
878
  return {
778
879
  project_id: spec.project,
@@ -799,12 +900,13 @@ async function planInternal(client, spec, idempotencyKey, dryRun = false, target
799
900
  });
800
901
  if (!isCore)
801
902
  await preflightTierFunctionLimits(client, normalized, ciCredentials);
802
- const wireSpec = releaseSpecToWire(normalized);
803
- // The gateway expects { spec, manifest_ref?, idempotency_key? } with
804
- // snake_case ReleaseSpec wire JSON. For oversized specs the SDK uploads
805
- // the manifest JSON to CAS first and references it; the gateway still
806
- // needs `spec` in the body (with at least the project), so we keep a
807
- // minimal stub there.
903
+ const wireSpec = isCore ? releaseSpecToCoreSpec(normalized) : releaseSpecToWire(normalized);
904
+ // The gateway expects { spec, manifest_ref?, idempotency_key? }. Cloud
905
+ // receives the legacy snake_case apply wire shape; Core receives the
906
+ // open ReleaseSpec shape from @run402/release. For oversized Cloud specs
907
+ // the SDK uploads the manifest JSON to CAS first and references it; the
908
+ // gateway still needs `spec` in the body (with at least the project), so
909
+ // we keep a minimal stub there.
808
910
  const inlineBody = { spec: wireSpec };
809
911
  if (idempotencyKey && !dryRun)
810
912
  inlineBody.idempotency_key = idempotencyKey;