@vxil/cli 0.36.0 → 0.36.1
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/_vxil-feature-configs.d.ts +19 -0
- package/dist/vxil-main.js +26 -12
- package/package.json +3 -3
|
@@ -73,6 +73,24 @@ export declare const SNS_TOPIC_ARN_PATTERN = "^arn:aws(-[a-z]+)?:sns:[a-z0-9-]+:
|
|
|
73
73
|
* a list so a newly launched SES region needs no vxil release; a typo still
|
|
74
74
|
* fails at `vxil push` (TypeBox), never as a DNS error on the first send. */
|
|
75
75
|
export declare const SES_REGION_PATTERN = "^[a-z]{2}(-[a-z]+)+-\\d$";
|
|
76
|
+
/** (w45 W44-WEBHOOK-SECRETREF-PATTERN) the ONE pattern every webhook secret
|
|
77
|
+
* ref shares (notifications `webhookSecretRef`, payments `stripe` / `paddle`
|
|
78
|
+
* / `revenuecat` `webhookSecretRef`): a secret-store name, letters, digits or
|
|
79
|
+
* '_', at most 64, with the optional `secret:` prefix both resolvers strip
|
|
80
|
+
* (payments-v1 resolveProviderSecrets, notifications-v1
|
|
81
|
+
* resolveTenantSecretRef). Stored secret names are lowercase-only
|
|
82
|
+
* (control-plane SECRET_NAME_RE), so both resolvers LOWERCASE the name after
|
|
83
|
+
* the strip: a capital ref reads its lowercase row. Upper case is accepted
|
|
84
|
+
* (founder decision D-k2-1 option (a), parked; built per the w45 brief) so
|
|
85
|
+
* this pattern refuses no stored config: the w45 read-only count found
|
|
86
|
+
* stored refs with capitals on staging, which never resolved before the
|
|
87
|
+
* lowercasing (so they were not live). A typo shape (a space, '-', '.', a
|
|
88
|
+
* path, an empty or over-long name) is refused at push instead of failing
|
|
89
|
+
* closed only when a webhook arrives. */
|
|
90
|
+
export declare const WEBHOOK_SECRET_REF_PATTERN = "^(secret:)?[A-Za-z0-9_]{1,64}$";
|
|
91
|
+
/** The validator's message for a ref that misses WEBHOOK_SECRET_REF_PATTERN
|
|
92
|
+
* (TypeBox's own reads "Expected string to match '…'"). */
|
|
93
|
+
export declare const WEBHOOK_SECRET_REF_MESSAGE = "a secret ref is the name of a stored secret: lowercase letters, numbers or '_' (capitals are read as lowercase), at most 64 characters, optionally prefixed 'secret:'";
|
|
76
94
|
export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
77
95
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
78
96
|
fromEmail: import("@sinclair/typebox").TString;
|
|
@@ -834,6 +852,7 @@ export declare const PaymentsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
|
834
852
|
webhookSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
835
853
|
acceptSandbox: import("@sinclair/typebox").TBoolean;
|
|
836
854
|
sandboxUsers: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
855
|
+
testStore: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"accept">, import("@sinclair/typebox").TLiteral<"reject">]>>;
|
|
837
856
|
}>>;
|
|
838
857
|
paypal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
839
858
|
clientIdRef: import("@sinclair/typebox").TString;
|
package/dist/vxil-main.js
CHANGED
|
@@ -5322,7 +5322,7 @@ function isDeclaredOnOwnerErase(v) {
|
|
|
5322
5322
|
function onOwnerEraseWidens(declared, remote) {
|
|
5323
5323
|
return declared === "delete" && remote !== "delete";
|
|
5324
5324
|
}
|
|
5325
|
-
var FN_RETRY_MAX_ATTEMPTS, FN_FORWARD_HEADERS_MAX, FN_SERVER_SCOPES_MAX, NOTIF_OVERRIDE_SUBJECT_MAX, NOTIF_OVERRIDE_BODY_MAX, NOTIF_OVERRIDE_MAX_BYTES, SNS_TOPIC_ARN_PATTERN, SES_REGION_PATTERN, NotificationsConfigSchema, GENERATION_DEFAULTS, GENERATION_BOUNDS, JobsConfigSchema, OAuthRefsSchema, AppleRefsSchema, OidcProviderSchema, REDIRECT_ORIGIN_PATTERN, AuthConfigSchema, RL_POLICY_NAME_PATTERN, RL_MAX_DECLARED_POLICIES, DeclaredRlPolicySchema, RateLimitsConfigSchema, FilesConfigSchema, DeclaredWebhookSubscriptionSchema, WebhooksConfigSchema, CommentsConfigSchema, CMS_MAX_COLLECTIONS_CEILING, CMS_QUERY_DEFAULTS, CmsConfigSchema, McpConfigSchema, RealtimeConfigSchema, PresenceConfigSchema, DeclaredOrgRoleSchema, OrgsConfigSchema, ActivityFeedConfigSchema, SEARCH_COLLECTION_DECLARED_CAP, SEARCH_COLLECTION_DIMS, DeclaredSearchCollectionSchema, HybridLaneWeights, VectorSearchConfigSchema, AI_TEMPLATE_NAME_PATTERN, AI_MAX_DECLARED_TEMPLATES, DeclaredAiTemplateSchema, AiConfigSchema, RagConfigSchema, PaymentsConfigSchema, FunctionsConfigSchema, CopilotConfigSchema, DENY_FUNCTION_SCOPES, FEATURE_KEYS, CMS_RETAIN_DAYS_MAX, CMS_DELETED_RETAIN_DAYS_MAX, CMS_DELETED_RETAIN_DAYS_DEFAULT;
|
|
5325
|
+
var FN_RETRY_MAX_ATTEMPTS, FN_FORWARD_HEADERS_MAX, FN_SERVER_SCOPES_MAX, NOTIF_OVERRIDE_SUBJECT_MAX, NOTIF_OVERRIDE_BODY_MAX, NOTIF_OVERRIDE_MAX_BYTES, SNS_TOPIC_ARN_PATTERN, SES_REGION_PATTERN, WEBHOOK_SECRET_REF_PATTERN, webhookSecretRef, NotificationsConfigSchema, GENERATION_DEFAULTS, GENERATION_BOUNDS, JobsConfigSchema, OAuthRefsSchema, AppleRefsSchema, OidcProviderSchema, REDIRECT_ORIGIN_PATTERN, AuthConfigSchema, RL_POLICY_NAME_PATTERN, RL_MAX_DECLARED_POLICIES, DeclaredRlPolicySchema, RateLimitsConfigSchema, FilesConfigSchema, DeclaredWebhookSubscriptionSchema, WebhooksConfigSchema, CommentsConfigSchema, CMS_MAX_COLLECTIONS_CEILING, CMS_QUERY_DEFAULTS, CmsConfigSchema, McpConfigSchema, RealtimeConfigSchema, PresenceConfigSchema, DeclaredOrgRoleSchema, OrgsConfigSchema, ActivityFeedConfigSchema, SEARCH_COLLECTION_DECLARED_CAP, SEARCH_COLLECTION_DIMS, DeclaredSearchCollectionSchema, HybridLaneWeights, VectorSearchConfigSchema, AI_TEMPLATE_NAME_PATTERN, AI_MAX_DECLARED_TEMPLATES, DeclaredAiTemplateSchema, AiConfigSchema, RagConfigSchema, PaymentsConfigSchema, FunctionsConfigSchema, CopilotConfigSchema, DENY_FUNCTION_SCOPES, FEATURE_KEYS, CMS_RETAIN_DAYS_MAX, CMS_DELETED_RETAIN_DAYS_MAX, CMS_DELETED_RETAIN_DAYS_DEFAULT;
|
|
5326
5326
|
var init_src = __esm({
|
|
5327
5327
|
"../feature-configs/src/index.ts"() {
|
|
5328
5328
|
"use strict";
|
|
@@ -5354,6 +5354,8 @@ var init_src = __esm({
|
|
|
5354
5354
|
NOTIF_OVERRIDE_MAX_BYTES = 64 * 1024;
|
|
5355
5355
|
SNS_TOPIC_ARN_PATTERN = "^arn:aws(-[a-z]+)?:sns:[a-z0-9-]+:\\d{12}:[A-Za-z0-9_-]{1,256}$";
|
|
5356
5356
|
SES_REGION_PATTERN = "^[a-z]{2}(-[a-z]+)+-\\d$";
|
|
5357
|
+
WEBHOOK_SECRET_REF_PATTERN = "^(secret:)?[A-Za-z0-9_]{1,64}$";
|
|
5358
|
+
webhookSecretRef = () => Type.String({ pattern: WEBHOOK_SECRET_REF_PATTERN });
|
|
5357
5359
|
NotificationsConfigSchema = Type.Object({
|
|
5358
5360
|
enabled: Type.Boolean({ default: true }),
|
|
5359
5361
|
fromEmail: Type.String({ format: "email" }),
|
|
@@ -5369,7 +5371,7 @@ var init_src = __esm({
|
|
|
5369
5371
|
// instead of the platform-wide PROVIDER_WEBHOOK_SECRET, binding the signature
|
|
5370
5372
|
// to the tenant so a signed event for tenant A can never validate at tenant
|
|
5371
5373
|
// B's webhook URL (mirrors payments revenuecat.webhookSecretRef).
|
|
5372
|
-
webhookSecretRef: Type.Optional(
|
|
5374
|
+
webhookSecretRef: Type.Optional(webhookSecretRef()),
|
|
5373
5375
|
// 'mock' exists for staging/e2e (deterministic provider); 'resend' is MVP;
|
|
5374
5376
|
// 'ses' (2026-09-19) is the second real provider — Amazon SES v2, BYO IAM
|
|
5375
5377
|
// keys, same delivery/suppression/preference pipeline as resend.
|
|
@@ -6722,12 +6724,12 @@ var init_src = __esm({
|
|
|
6722
6724
|
// "configure it or not", not each inner ref — guide ch. 6, auth).
|
|
6723
6725
|
stripe: Type.Optional(Type.Object({
|
|
6724
6726
|
secretKeyRef: Type.String(),
|
|
6725
|
-
webhookSecretRef:
|
|
6727
|
+
webhookSecretRef: webhookSecretRef(),
|
|
6726
6728
|
taxEnabled: Type.Boolean({ default: false })
|
|
6727
6729
|
})),
|
|
6728
6730
|
paddle: Type.Optional(Type.Object({
|
|
6729
6731
|
apiKeyRef: Type.String(),
|
|
6730
|
-
webhookSecretRef:
|
|
6732
|
+
webhookSecretRef: webhookSecretRef(),
|
|
6731
6733
|
sandbox: Type.Boolean({ default: false })
|
|
6732
6734
|
})),
|
|
6733
6735
|
revenuecat: Type.Optional(Type.Object({
|
|
@@ -6743,7 +6745,7 @@ var init_src = __esm({
|
|
|
6743
6745
|
// verification, it fails CLOSED: every delivery is 401 bad_signature with a
|
|
6744
6746
|
// `sig_failed` row that can never be reprocessed. Mirrors stripe/paddle
|
|
6745
6747
|
// webhookSecretRef.
|
|
6746
|
-
webhookSecretRef: Type.Optional(
|
|
6748
|
+
webhookSecretRef: Type.Optional(webhookSecretRef()),
|
|
6747
6749
|
// Environment integrity. RevenueCat posts SANDBOX
|
|
6748
6750
|
// and PRODUCTION events to the SAME webhook with the same auth header, so a
|
|
6749
6751
|
// sandbox purchase would otherwise fold into production entitlements. A
|
|
@@ -6761,7 +6763,19 @@ var init_src = __esm({
|
|
|
6761
6763
|
// TestFlight purchase and is refused by the CLI's production promotion
|
|
6762
6764
|
// gate). No default on purpose (Value.Default would materialize it into
|
|
6763
6765
|
// every RC manifest); absent = an empty list.
|
|
6764
|
-
sandboxUsers: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 256 }), { maxItems: 20 }))
|
|
6766
|
+
sandboxUsers: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 256 }), { maxItems: 20 })),
|
|
6767
|
+
// (2026-11-03) RevenueCat Test Store purchases.
|
|
6768
|
+
// A Test Store purchase is SANDBOX data that needs no store account,
|
|
6769
|
+
// invite or license tester (anyone with the app's public `test_` key can
|
|
6770
|
+
// make one), so `acceptSandbox: true` on a production project would fold
|
|
6771
|
+
// it. 'reject' refuses every delivery whose RAW RevenueCat event says
|
|
6772
|
+
// `store: TEST_STORE` (and every sync/restore snapshot from the Test
|
|
6773
|
+
// Store) BEFORE any other environment rule, `sandboxUsers` included: the
|
|
6774
|
+
// delivery is kept as outcome 'rejected_test_store' (200, never folded).
|
|
6775
|
+
// Absent = 'accept' (today's behaviour). No schema default on purpose
|
|
6776
|
+
// (the sandboxUsers rule: Value.Default would materialize it into every RC
|
|
6777
|
+
// manifest); the reader (payments-v1 environmentAccepted) owns the default.
|
|
6778
|
+
testStore: Type.Optional(Type.Union([Type.Literal("accept"), Type.Literal("reject")]))
|
|
6765
6779
|
})),
|
|
6766
6780
|
paypal: Type.Optional(Type.Object({
|
|
6767
6781
|
clientIdRef: Type.String(),
|
|
@@ -9031,9 +9045,9 @@ var init_lib = __esm({
|
|
|
9031
9045
|
timeoutMs: { min: 1e3, max: 12e4 }
|
|
9032
9046
|
};
|
|
9033
9047
|
CONFIG_FILENAMES = ["vxil.config.ts", "vxil.config.mjs", "vxil.config.js"];
|
|
9034
|
-
VXIL_CONFIG_PKG_VERSION = "0.
|
|
9035
|
-
VXIL_SDK_PKG_VERSION = "0.35.
|
|
9036
|
-
VXIL_CLI_PKG_VERSION = "0.36.
|
|
9048
|
+
VXIL_CONFIG_PKG_VERSION = "0.27.0";
|
|
9049
|
+
VXIL_SDK_PKG_VERSION = "0.35.3";
|
|
9050
|
+
VXIL_CLI_PKG_VERSION = "0.36.1";
|
|
9037
9051
|
SCAFFOLD_NODE_TYPES_RANGE = "^24.0.0";
|
|
9038
9052
|
SCAFFOLD_TSCONFIG = {
|
|
9039
9053
|
compilerOptions: {
|
|
@@ -13341,7 +13355,7 @@ function promotionRefusals(cfg, allowed) {
|
|
|
13341
13355
|
out.push({
|
|
13342
13356
|
kind: "sandbox",
|
|
13343
13357
|
flag: PROMOTION_OVERRIDE_FLAGS.sandbox,
|
|
13344
|
-
message: `sandbox provider flags [${sandboxes.join(", ")}] would ship to a live money path (a sandbox key signs with the wrong secret; revenuecat.acceptSandbox folds EVERY TestFlight / test-track purchase into live entitlements \u2014 for store review, list the reviewer app_user_ids in revenuecat.sandboxUsers instead, which a production push allows). Set them false, or override with --${PROMOTION_OVERRIDE_FLAGS.sandbox}.`
|
|
13358
|
+
message: `sandbox provider flags [${sandboxes.join(", ")}] would ship to a live money path (a sandbox key signs with the wrong secret; revenuecat.acceptSandbox folds EVERY TestFlight / test-track purchase into live entitlements \u2014 for store review, list the reviewer app_user_ids in revenuecat.sandboxUsers instead, which a production push allows; if you override it for testers, also set revenuecat.testStore: 'reject', or anyone with the Test Store key folds a purchase). Set them false, or override with --${PROMOTION_OVERRIDE_FLAGS.sandbox}.`
|
|
13345
13359
|
});
|
|
13346
13360
|
}
|
|
13347
13361
|
const devOrigins = devRedirectOrigins(redirectOrigins(cfg));
|
|
@@ -17505,13 +17519,13 @@ var TOOLS = [
|
|
|
17505
17519
|
{
|
|
17506
17520
|
name: "payments_list_webhook_events",
|
|
17507
17521
|
feature: "payments",
|
|
17508
|
-
description: "List provider webhook deliveries from the event log, newest-first: outcome (received|processed|error|sig_failed|parse_failed|reprocessed|ignored|unowned|rejected_environment), the provider-reported environment (production|sandbox), signature status, error, and timestamps per delivery. Use it to diagnose billing sync issues (e.g. an unmapped price or product, or a RevenueCat entitlement id that is not a ledger.tierMap key (with no ledger.priceMap hit) \u2192 outcome error, a misconfigured webhook secret producing sig_failed rows, sandbox deliveries landing as rejected_environment). An unmapped one-off product lands `error` unless you set ledger.unmappedProduct:'ignore', which lands it `ignored` instead. Read-only \u2014 needs payments:read. Server-side key only (403 server_only on a thin-client/end-user key) \u2014 the log is tenant-wide and carries provider payloads. Payloads are detail-only (console surface).",
|
|
17522
|
+
description: "List provider webhook deliveries from the event log, newest-first: outcome (received|processed|error|sig_failed|parse_failed|reprocessed|ignored|unowned|rejected_environment|rejected_test_store), the provider-reported environment (production|sandbox), signature status, error, and timestamps per delivery. Use it to diagnose billing sync issues (e.g. an unmapped price or product, or a RevenueCat entitlement id that is not a ledger.tierMap key (with no ledger.priceMap hit) \u2192 outcome error, a misconfigured webhook secret producing sig_failed rows, sandbox deliveries landing as rejected_environment, RevenueCat Test Store purchases refused under revenuecat.testStore 'reject' landing as rejected_test_store). An unmapped one-off product lands `error` unless you set ledger.unmappedProduct:'ignore', which lands it `ignored` instead. Read-only \u2014 needs payments:read. Server-side key only (403 server_only on a thin-client/end-user key) \u2014 the log is tenant-wide and carries provider payloads. Payloads are detail-only (console surface).",
|
|
17509
17523
|
inputSchema: {
|
|
17510
17524
|
type: "object",
|
|
17511
17525
|
properties: {
|
|
17512
17526
|
provider: { type: "string", enum: ["mock", "stripe", "paddle", "revenuecat", "paypal"] },
|
|
17513
17527
|
event_type: { type: "string", description: "Exact event type filter, e.g. 'subscription.updated'." },
|
|
17514
|
-
outcome: { type: "string", enum: ["received", "processed", "error", "sig_failed", "parse_failed", "reprocessed", "ignored", "unowned", "rejected_environment"] },
|
|
17528
|
+
outcome: { type: "string", enum: ["received", "processed", "error", "sig_failed", "parse_failed", "reprocessed", "ignored", "unowned", "rejected_environment", "rejected_test_store"] },
|
|
17515
17529
|
environment: { type: "string", enum: ["production", "sandbox"], description: "The provider-reported environment of the delivery (a separate axis from the API key label)." },
|
|
17516
17530
|
provider_charge_id: { type: "string", maxLength: 200, description: "Exact match on the normalised charge id (the same provider_charge_id a payments.charge.* event carries): the delivery that recorded that charge plus any refund/dispute against it \u2014 usually one row, so ONE detail read (GET /v1/payments/webhook-events/{eventId}) fetches the verified payload. Rows received before 2026-09-19 carry no charge id." },
|
|
17517
17531
|
provider_evt_id: { type: "string", maxLength: 200, description: "Exact match on the provider's own event id (the provider_evt_id every row shows)." },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vxil/cli",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The vxil CLI — init, quickstart, push, gen, secrets, keys, migrate, doctor, diff, functions, payments; installs the `vxil` command (npm i -g @vxil/cli).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@vxil/config": "0.
|
|
49
|
-
"@vxil/feature-configs": "0.
|
|
48
|
+
"@vxil/config": "0.27.0",
|
|
49
|
+
"@vxil/feature-configs": "0.24.0",
|
|
50
50
|
"@vxil/runtime": "0.0.1",
|
|
51
51
|
"@vxil/types": "0.0.1",
|
|
52
52
|
"miniflare": "^4.20260730.0"
|