@vxil/cli 0.1.1 → 0.2.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 +46 -2
- package/dist/config.d.ts +43 -3
- package/dist/vxil.js +8223 -2225
- package/package.json +4 -3
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { type Static, type TSchema } from '@sinclair/typebox';
|
|
2
2
|
export * from './_vxil-feature-configs-hooks.js';
|
|
3
3
|
export * from './readmodels.js';
|
|
4
|
+
export declare const RESERVED_CREDIT_TYPES: ReadonlySet<string>;
|
|
5
|
+
/** True when a credit_type is a vxil-COGS reserved type (grant/consume/config
|
|
6
|
+
* of which is restricted to internal platform machinery). */
|
|
7
|
+
export declare function isReservedCreditType(creditType: string): boolean;
|
|
4
8
|
export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
5
9
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
6
10
|
fromEmail: import("@sinclair/typebox").TString;
|
|
7
11
|
fromName: import("@sinclair/typebox").TString;
|
|
8
12
|
replyTo: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
13
|
resendApiKeyRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
14
|
+
webhookSecretRef: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
10
15
|
provider: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resend">, import("@sinclair/typebox").TLiteral<"mock">]>;
|
|
11
16
|
defaultLocale: import("@sinclair/typebox").TString;
|
|
12
|
-
retry: import("@sinclair/typebox").TObject<{
|
|
17
|
+
retry: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
13
18
|
maxAttempts: import("@sinclair/typebox").TInteger;
|
|
14
19
|
backoff: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"exponential">, import("@sinclair/typebox").TLiteral<"linear">]>;
|
|
15
|
-
}
|
|
20
|
+
}>>;
|
|
16
21
|
suppression: import("@sinclair/typebox").TObject<{
|
|
17
22
|
softBounceThreshold: import("@sinclair/typebox").TInteger;
|
|
18
23
|
}>;
|
|
@@ -25,8 +30,31 @@ export declare const NotificationsConfigSchema: import("@sinclair/typebox").TObj
|
|
|
25
30
|
}>;
|
|
26
31
|
/** in-app inbox channel (send with channel: 'inbox' | 'both') */
|
|
27
32
|
inboxEnabled: import("@sinclair/typebox").TBoolean;
|
|
33
|
+
/** §11b.5 broadcast campaigns channel. Optional bag (= 1 leaf): absent means
|
|
34
|
+
* disabled; per-campaign quiet_hours / freq_cap overrides live on the
|
|
35
|
+
* notifications.campaigns ROW (tenant data), not here. Folded into the
|
|
36
|
+
* canonical schema 2026-07-18 (M21/#4 — Value.Clean previously STRIPPED the
|
|
37
|
+
* worker-local extension, so campaigns 403'd via the real config path). */
|
|
38
|
+
broadcast: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
39
|
+
enabled: import("@sinclair/typebox").TBoolean;
|
|
40
|
+
/** tenant-default per-recipient quiet window (defer-not-drop); a
|
|
41
|
+
* per-campaign quiet_hours wins over it. Mirrors the campaigns-row shape
|
|
42
|
+
* (workers/notifications-v1 CampaignBody.quiet_hours). start/end are
|
|
43
|
+
* pattern-pinned to what the worker's parseHhMm actually parses — a
|
|
44
|
+
* looser string ('10pm') would validate but FAIL OPEN at runtime
|
|
45
|
+
* (quiet window silently ignored). */
|
|
46
|
+
defaultQuietHours: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
47
|
+
tz: import("@sinclair/typebox").TString;
|
|
48
|
+
start: import("@sinclair/typebox").TString;
|
|
49
|
+
end: import("@sinclair/typebox").TString;
|
|
50
|
+
}>>;
|
|
51
|
+
/** default rolling per-user-per-day campaign-send cap across campaigns */
|
|
52
|
+
freqCapPerUserPerDay: import("@sinclair/typebox").TInteger;
|
|
53
|
+
}>>;
|
|
28
54
|
}>;
|
|
29
55
|
export type NotificationsConfig = Static<typeof NotificationsConfigSchema>;
|
|
56
|
+
/** The §11b.5 broadcast bag as persisted (present ⇒ leaf defaults applied). */
|
|
57
|
+
export type BroadcastConfig = NonNullable<NotificationsConfig['broadcast']>;
|
|
30
58
|
export declare const JobsConfigSchema: import("@sinclair/typebox").TObject<{
|
|
31
59
|
enabled: import("@sinclair/typebox").TBoolean;
|
|
32
60
|
retry: import("@sinclair/typebox").TObject<{
|
|
@@ -585,3 +613,19 @@ export declare const MCP_MAX_PROMPTS = 32;
|
|
|
585
613
|
* validation below and the control-plane deploy clamp. */
|
|
586
614
|
export declare const DENY_FUNCTION_SCOPES: Set<string>;
|
|
587
615
|
export declare function validateFeatureConfig(feature: string, raw: unknown): ConfigValidation;
|
|
616
|
+
export declare const FEATURE_KEYS: readonly ["notifications", "jobs", "auth", "rate-limits", "files", "webhooks", "comments", "cms", "mcp", "realtime", "presence", "orgs", "activity-feed", "vector-search", "ai", "rag", "payments", "functions", "copilot"];
|
|
617
|
+
export type FeatureKey = (typeof FEATURE_KEYS)[number];
|
|
618
|
+
/** The hand-authored "when to use" intent a machine schema cannot convey.
|
|
619
|
+
* REQUIRED for every feature (Record key-closure): a feature added to
|
|
620
|
+
* FEATURE_KEYS without a hint is a compile error naming the missing key. */
|
|
621
|
+
export interface PlannerHint {
|
|
622
|
+
/** One or two sentences: when an app needs this feature. */
|
|
623
|
+
whenToUse: string;
|
|
624
|
+
/** Soft priors — words/needs that suggest the feature (NOT a matcher). */
|
|
625
|
+
signals: string[];
|
|
626
|
+
/** When NOT to pick it (disambiguation vs neighbors). */
|
|
627
|
+
notFor: string;
|
|
628
|
+
/** Features that must be enabled alongside (runtime substrate deps). */
|
|
629
|
+
dependsOn: FeatureKey[];
|
|
630
|
+
}
|
|
631
|
+
export declare const FEATURE_HINTS: Record<FeatureKey, PlannerHint>;
|
package/dist/config.d.ts
CHANGED
|
@@ -14,7 +14,39 @@ export interface FieldDef {
|
|
|
14
14
|
relationTo?: string;
|
|
15
15
|
computed?: boolean;
|
|
16
16
|
compute?: unknown;
|
|
17
|
+
/** Claims-table-enforced value uniqueness across live items (cms.md §9.3):
|
|
18
|
+
* a duplicate write is a clean 409 unique_violation. Scalar types only
|
|
19
|
+
* (string/int/float/datetime/relation/file). Carried on collection/field
|
|
20
|
+
* CREATE by `vxil push` and server apply; since 2026-07-17 `vxil push` also
|
|
21
|
+
* RECONCILES it on an existing same-type field (in-place alter via the REST
|
|
22
|
+
* field re-add — packages/cli/src/cms.ts FIELD_ATTRS); attributes push
|
|
23
|
+
* cannot reconcile surface as a visible plan warning, never a silent no-op. */
|
|
24
|
+
unique?: boolean;
|
|
25
|
+
/** Per-relation-field delete behavior (cms.md §11): bounded, atomic fan-out
|
|
26
|
+
* when the referenced item is deleted. Same carriage + reconcile behavior
|
|
27
|
+
* as `unique`. */
|
|
28
|
+
onDelete?: 'cascade' | 'set_null';
|
|
17
29
|
}
|
|
30
|
+
/** The CANONICAL field-attribute name set (config-side spelling), DERIVED from
|
|
31
|
+
* `FieldDef` itself so it can never drift from the authoring type: it is every
|
|
32
|
+
* key of `FieldDef` except `type` (which is required, not an optional carried
|
|
33
|
+
* attribute). This is the compile-time source of truth for the config-carriage
|
|
34
|
+
* completeness ratchet (audit 2026-07-15e #2, roadmap §4.5 P3): the CLI carriage
|
|
35
|
+
* table (`packages/cli/src/cms.ts` FIELD_ATTRS) and the server one
|
|
36
|
+
* (`workers/control-plane/src/handlers/apply.ts` FIELD_ATTR_DELTA) each pin
|
|
37
|
+
* `keyof` coverage against a set that equals this — so a 9th attribute added to
|
|
38
|
+
* `FieldDef` WITHOUT threading it through BOTH push paths is a tsc error naming
|
|
39
|
+
* the uncovered key, not a silent half-carriage. */
|
|
40
|
+
export type FieldAttrName = Exclude<keyof FieldDef, 'type'>;
|
|
41
|
+
/** Compile-time exact-key closure helper: resolves to `Set` iff `Covered`
|
|
42
|
+
* covers EVERY member of `Required` (i.e. `Required` is assignable to
|
|
43
|
+
* `Covered`), else to the specific uncovered key literal(s) — so a `satisfies`
|
|
44
|
+
* against the covered literal union produces a tsc error naming the field the
|
|
45
|
+
* developer forgot to thread through the carriage table. Used by both push
|
|
46
|
+
* paths' carriage tables to gate additions to `FieldAttrName`. */
|
|
47
|
+
export type CoversFieldAttrs<Covered extends FieldAttrName> = [
|
|
48
|
+
FieldAttrName
|
|
49
|
+
] extends [Covered] ? Covered : Exclude<FieldAttrName, Covered>;
|
|
18
50
|
/** A CMS collection-as-code: collection slug → fields. */
|
|
19
51
|
export interface CollectionDef {
|
|
20
52
|
singular?: string;
|
|
@@ -23,9 +55,17 @@ export interface CollectionDef {
|
|
|
23
55
|
* existing `string` field on this collection that holds the owner (end-user)
|
|
24
56
|
* id. When set, the cms worker auto-scopes owned reads/writes to the VERIFIED
|
|
25
57
|
* end-user principal in end-user mode (default-deny) — and is a no-op in
|
|
26
|
-
* server-caller mode.
|
|
27
|
-
* typed worker consults. Omit for shared/reference collections. */
|
|
58
|
+
* server-caller mode. Not a hard-isolation predicate; a single declarative
|
|
59
|
+
* flag the typed worker consults. Omit for shared/reference collections. */
|
|
28
60
|
ownerField?: string;
|
|
61
|
+
/** Public delivery (roadmap §4.4): when true, this collection's PUBLISHED items
|
|
62
|
+
* are servable through the keyless, edge-cached GET /v1/cms/public/:tenantId/
|
|
63
|
+
* :collection lane (no API key). Owner-UNSCOPED (public content, not per-user);
|
|
64
|
+
* the owner_field is stripped from every served row. Default false. Carried by
|
|
65
|
+
* BOTH push paths (the `vxil push` cms reconciler AND control-plane /v1/apply)
|
|
66
|
+
* with a regression test on each — an attribute read by no enforcing path ships
|
|
67
|
+
* inert (the validation.unique / owner_field precedent). */
|
|
68
|
+
public?: boolean;
|
|
29
69
|
}
|
|
30
70
|
/** A function trigger (the §7.3 crossing). cmsHook fires on a CMS write;
|
|
31
71
|
* authHook is the post-signup hook (fires on `auth.user.created`,
|
|
@@ -77,7 +117,7 @@ export interface FunctionDef {
|
|
|
77
117
|
}
|
|
78
118
|
/** A secret REFERENCE (never a value). `vxil secrets set <name>` writes the value. */
|
|
79
119
|
export interface SecretRef {
|
|
80
|
-
/** which feature
|
|
120
|
+
/** which feature the value is encrypted at rest under. */
|
|
81
121
|
feature: string;
|
|
82
122
|
description?: string;
|
|
83
123
|
}
|