@cookiemunch/cli 0.7.0 → 0.8.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.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `cookiemunch` — the Developer API from a terminal or a CI job.
3
+ *
4
+ * cookiemunch config pull --site <cbid> [--out file]
5
+ * cookiemunch config diff --site <cbid> <file> [--replace] [--exit-code]
6
+ * cookiemunch config push --site <cbid> <file> [--replace] [--strict]
7
+ * cookiemunch config validate --site <cbid> <file> [--replace] [--strict]
8
+ * cookiemunch preview --site <cbid> [--url <url>] [--region eu] [--lang de] [--ttl 900] [--open]
9
+ * cookiemunch executors test <id> --email <email> [--operation locate]
10
+ * cookiemunch executors webhook-test <id> --headers-file <json> --body-file <file>
11
+ * cookiemunch executors deliveries <id>
12
+ * cookiemunch executors presets
13
+ * cookiemunch executors conformance <baseUrl> --secret-env <NAME> [--canary-email <addr>] [--prefix /privacy] [--json]
14
+ * cookiemunch executors conformance --connection <id> [--json]
15
+ * cookiemunch executors roll-completion-secret <id>
16
+ * cookiemunch executors upgrade-preset <id> [--preset <name>] [--version <n>] [--org-id <id>] [--atlas-id-app-id <id>]
17
+ * [--revoke-atlas-id-grant] [--accept-preset <path> …] [--dry-run]
18
+ * cookiemunch executors recheck <id>
19
+ * cookiemunch executors health <id> [--limit <n>]
20
+ * cookiemunch rights-page pull|diff|push|publish --site <cbid> [<file>] [--base <updatedAt>] [--yes]
21
+ * cookiemunch scan --site <cbid> [--wait] [--timeout <seconds>]
22
+ * cookiemunch cookies presets|preset|unpreset|delete-observed|purge-observed --site <cbid> …
23
+ * cookiemunch site update --site <cbid> [--domain <host>] [--name <name>] [--aliases a,b] [--dry-run]
24
+ * cookiemunch site brand --site <cbid> [--url <https URL> | <brand.json>] [--dry-run]
25
+ * cookiemunch health [--site <cbid>] [--json] [--fail-on error|warning|never]
26
+ * cookiemunch provision <file> [--dry-run]
27
+ * cookiemunch partners list|link|unlink --site <cbid> …
28
+ * cookiemunch consent-sync status|rotate|remove|token --site <cbid> …
29
+ * cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]
30
+ *
31
+ * Everything goes through the typed SDK (@cookiemunch/sdk) except where the SDK has no
32
+ * method yet; those calls go through `rawRequest` with the same key and base URL. All I/O
33
+ * is injected, so the whole CLI is testable with a mocked fetch.
34
+ */
35
+ export declare const DEFAULT_BASE_URL = "https://api.cookiemunch.net";
36
+ export interface CliIo {
37
+ env: Record<string, string | undefined>;
38
+ fetch: typeof fetch;
39
+ stdout: (text: string) => void;
40
+ stderr: (text: string) => void;
41
+ readFile: (path: string) => Promise<string>;
42
+ /** `mode` is the file mode for a new file (0o600 for anything holding a secret). */
43
+ writeFile: (path: string, data: string, mode?: number) => Promise<void>;
44
+ /** Open a URL in the user's browser. */
45
+ openUrl: (url: string) => Promise<void>;
46
+ /**
47
+ * Ask a yes/no question. Present only when a person can answer (an interactive terminal);
48
+ * absent, a command that needs confirmation refuses unless given --yes.
49
+ */
50
+ confirm?: (question: string) => Promise<boolean>;
51
+ }
52
+ export declare const USAGE = "cookiemunch \u2014 Cookie Munch from the command line\n\nUsage:\n cookiemunch config pull --site <cbid> [--out <file>]\n Write the site's config as JSON (to stdout, or to <file>).\n cookiemunch config diff --site <cbid> <file> [--replace] [--exit-code]\n Show what pushing <file> would change (the server's dry run; nothing is stored).\n Read-only fields a pulled file carries (effective, designWarnings, ...) are ignored.\n cookiemunch config push --site <cbid> <file> [--replace] [--strict]\n Apply <file>. Default: merged over the stored config (PATCH) \u2014 fields the file\n leaves out keep their value, and a field set to null is removed (it takes its\n default). --replace sends it whole (PUT): a top-level field the file leaves out\n reverts to its default. Prints any design warnings the server found. --strict\n checks the file first and does not push it (exit 1) when Accept all is pushed\n harder than Reject all anywhere \u2014 for CI.\n cookiemunch config validate --site <cbid> <file> [--replace] [--strict]\n Check <file> for consent-button parity on the server, without writing: is Accept\n all more prominent than Reject all (colour, size, placement, copy, custom CSS)?\n Merged over the stored config like push; --replace checks it as sent. --strict\n exits 1 when there is any warning (notices never fail).\n cookiemunch preview --site <cbid> [--url <page>] [--region <eu|de|us-ca\u2026>] [--lang <de\u2026>]\n [--ttl <seconds>] [--open]\n Print (and with --open, open) a link showing the banner as a visitor in that\n region and language sees it. Works in headless browsers; nothing is recorded.\n cookiemunch executors test <id> (--email <email> | --canary) [--operation <locate|export|erase>]\n Try a connected system against one person without filing a request.\n --operation defaults to locate (lookup is accepted as another name for it).\n --canary uses the organisation's canary address instead: no real person, and\n a canary locate also updates the connection's health. Exits 1 when not ok.\n cookiemunch executors webhook-test <id> --headers-file <json> --body-file <file>\n Would this webhook delivery verify? Sends the headers (a JSON object) and the\n body file byte for byte to the receiver's check; nothing is acted on. Prints\n { verified, stage, reason } and exits 1 when it does not verify.\n cookiemunch executors deliveries <id>\n The last 50 deliveries to that connection's webhook, each with its reason.\n cookiemunch executors presets\n The versioned presets, which are usable now and which wait on another\n platform, and the organisation's canary address.\n cookiemunch executors conformance <baseUrl> --secret-env <NAME> [--canary-email <addr>]\n [--prefix /privacy] [--json]\n Check any system against the open cm-standard-v2 executor contract, rule by\n rule, using only the canary subject. The credential is read from the\n environment variable NAME, never from the command line. Without\n --canary-email the organisation's canary address is fetched (needs\n COOKIEMUNCH_API_KEY); with it, no Cookie Munch key is needed at all.\n Exits 1 when any rule fails.\n cookiemunch executors conformance --connection <id> [--json]\n The same suite, run by Cookie Munch against a connected system.\n cookiemunch executors roll-completion-secret <id>\n A new completion secret for that connection, printed once; the old one keeps\n verifying for 24 hours.\n cookiemunch executors upgrade-preset <id> [--preset <name>] [--version <n>]\n [--org-id <id>] [--atlas-id-app-id <id>] [--revoke-atlas-id-grant]\n [--accept-preset <path> \u2026] [--dry-run]\n Rebuild a connection from its preset's latest version (or --version), keeping\n its id and credentials; --preset adopts one on a hand-written connection.\n Your hand edits are kept (the diff marks them kept or conflict); --accept-preset\n (repeatable) takes the preset's value for that path. Prints the diff; --dry-run\n changes nothing. A pinned connection is refused.\n cookiemunch executors recheck <id>\n Re-check a connection now (a canary test that records its health): the hook to\n run after deploying that system's rights API. Exits 1 when it is not ok.\n cookiemunch executors health <id> [--limit <n>]\n The connection's last health checks, newest first (up to 50).\n cookiemunch rights-page pull --site <cbid> [--out <file>]\n Write the site's rights page draft as JSON, and print its updatedAt for --base.\n cookiemunch rights-page diff --site <cbid> <file> [--exit-code]\n Validate <file> on the server (dry run) and show what pushing it would change.\n cookiemunch rights-page push --site <cbid> <file> [--base <updatedAt>]\n Replace the draft with <file>. Nothing is live until publish. Refused (exit 1)\n if the draft changed since the diff, or since --base (the updatedAt pull printed).\n cookiemunch rights-page publish --site <cbid> [--yes] [--base <updatedAt>]\n Publish the draft (it goes live at once). Asks first; --yes skips the question\n and is required when there is no terminal to ask in. Prints why when the page\n cannot go live. Refused (exit 1) if the draft changed after it was read (or\n since --base); --yes never overrides that.\n\n cookiemunch scan --site <cbid> [--wait] [--timeout <seconds>]\n Start a cookie crawl of the site and print its state (JSON). --wait holds on\n until it is done or failed (default up to 120 s, --timeout to change) and exits\n 1 when it failed or is still running at the end. A scan already running is\n waited on rather than started twice.\n\n cookiemunch cookies presets --site <cbid>\n The declaration presets (atlas, forumulate, chatly, cookiemunch, referalli, firstpromoter,\n partnerstack, tapfiliate, impact; referally is the deprecated old name of referalli): what each takes,\n what it declared on this site, and whether the vendor's own manifest exists yet.\n cookiemunch cookies preset <vendor> --site <cbid> [--param k=v \u2026] [--dry-run]\n Declare what that platform writes (cookies and browser storage), marked as\n declared by it; run again to re-sync. Atlas: --param frontendApiHost=auth.example.com\n [--param crossSubdomainCookies=false]. Chatly: --param publicId=ch_web_\u2026 .\n Referral and affiliate presets (referalli, firstpromoter, partnerstack, tapfiliate, impact):\n [--param cookieDomain=.example.com] [--param cookieDays=60] [--param category=\u2026];\n referalli [--param legacyName=false], impact [--param campaignId=\u2026]. A row filed under a\n disabled category prints a warning and a suggestedConfigPatch. Any other vendor is\n declared with the API (PUT /v1/sites/{cbid}/cookies).\n cookiemunch cookies unpreset <vendor> --site <cbid> [--dry-run]\n Remove every declaration that vendor's preset made.\n cookiemunch cookies import-manifest <url> --site <cbid> [--file <manifest.json>] [--dry-run]\n Declare any vendor's cookies and storage from its embed manifest\n (/.well-known/<product>-embed.json), by URL or from a file. Remove it with\n cookies unpreset <product>.\n cookiemunch cookies suggestions --site <cbid>\n What to declare: the platforms detected on the site and each undeclared row.\n cookiemunch cookies declare-suggestions --site <cbid> [--names a,b] [--dry-run]\n Declare them: detected vendors' presets, then every other suggestion with a purpose.\n cookiemunch cookies delete-observed <name> --site <cbid> [--dry-run]\n Remove every stored row of that name (a name the site never sets). A declaration stays.\n cookiemunch cookies purge-observed --site <cbid> --since <time> [--until <time>] [--dry-run]\n Remove every row a real visit first reported in that window (ISO-8601 or epoch ms).\n Crawled rows and declarations stay. Run with --dry-run first.\n cookiemunch site update --site <cbid> [--domain <host>] [--name <name> | --clear-name]\n [--aliases <a,b>] [--dry-run]\n Rename or move a site. The cbid and consent ledger stay; a domain move clears\n verification. --dry-run prints the diff and its effects without saving.\n cookiemunch site brand --site <cbid> [--url <https URL> | <brand.json>] [--dry-run]\n Import a brand.json into the banner theme (the rights page uses it too). Values the\n site set itself are kept. With neither --url nor a file, prints the last import.\n cookiemunch consent-sync status --site <cbid>\n Whether hosted consent sync is set up (the secret's last four characters, when it was minted).\n cookiemunch consent-sync rotate --site <cbid>\n Mint the site's consent-sync signing secret, or replace it (the old one stops at once).\n Prints the secret alone on stdout, so it can be piped into your secret store: it is shown once.\n cookiemunch consent-sync remove --site <cbid> --yes\n Remove it: hosted consent sync stops for every visitor.\n cookiemunch consent-sync token --site <cbid> --subject <id> [--ttl <seconds>]\n Sign a test token locally with COOKIEMUNCH_CONSENT_SYNC_SECRET (nothing is sent), e.g. to try\n GET /api/v1/<cbid>/profile with curl.\n cookiemunch health [--site <cbid>] [--json] [--fail-on error|warning|never]\n Every link the site's privacy wiring depends on, with a fix hint for each that\n fails. Exits 1 when a check fails (checks that could not run, or are waived, do not count).\n --fail-on error ignores warnings; --fail-on never always exits 0.\n cookiemunch provision <file> [--dry-run]\n Wire a product's privacy in one call (site, connections, Atlas, Forumulate) from\n a JSON file without secrets: the Atlas key and Forumulate token come from\n COOKIEMUNCH_ATLAS_SECRET_KEY and COOKIEMUNCH_FORUMULATE_TOKEN. Re-running is a\n no-op. Exits 1 when a step failed.\n cookiemunch keys report [--unused-days <n>] [--expiring-days <n>] [--json]\n Key hygiene: keys unused for n days (default 90), keys with broad access, and\n keys expiring within n days (default 14). Needs a full-access key.\n cookiemunch partners list|link|unlink --site <cbid> [--partner <id>]\n [--external-id <id>] [--label <text>] [<linkId>]\n Grant a partner platform the site's consent events (no secret is created), list\n the grants, or revoke one. Any partner this deployment knows (forumulate, atlas, chatly,\n referalli, or one registered for it).\n cookiemunch token exchange --subject-token-env NAME --scope <a,b> --resource org:<id>|site:<cbid> [--expires-in <s>]\n Swap your identity provider's token (read from the variable NAME) for a short-lived, scoped\n API key (at most 1 hour); prints the key alone. Needs no API key.\n cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]\n One Content-Security-Policy from several products' embed manifests\n (/.well-known/<product>-embed.json): cookiemunch, atlas, chatly, forumulate,\n referalli, or any manifest URL. --framework prints it for next.config.js,\n Express or nginx; without it, the header value. --site uses your site's own\n Cookie Munch manifest (its logo, fonts, sync endpoint). Needs no API key. Exits 1\n when a named product has not published a manifest (the rest are still merged).\n cookiemunch cookies diff|push <file> --site <cbid> [--replace] [--exit-code]\n Declarations as a file ({\"cookies\": [...]}), through the server's dry run. push applies\n only when something differs; --replace also removes declarations the file leaves out.\n cookiemunch executors pull [<file>] | diff <file> | push <file> [--secret-env NAME]\n Connected systems as a file. The file never carries a secret: a new connection's API key\n comes from the environment variable --secret-env names.\n cookiemunch dsar test [--types access,deletion] [--with-cbid --site <cbid>] [--without-cbid]\n [--email <addr>] [--cleanup]\n File TEST rights requests and read each back. --cleanup deletes exactly the ones this run\n filed (by id; it never deletes by listing).\n cookiemunch doctor [--site <cbid>] [--org <id>]\n The key (and whose org it is, against --org or COOKIEMUNCH_ORG), its expiry, the CLI\n version against the latest, and integration health. Exits 1 when a check fails.\n cookiemunch keys vend --scopes <a,b> --ttl <1h|30m|seconds> [--cbids <x,y>] [--name <n>]\n A short-lived key (at most 12 h) within this key's own scopes; prints the key alone.\n Needs keys:write (or a full-access key).\n cookiemunch keys self | rotate-self\n This key's own prefix, scopes and expiry; or rotate it (the new key is printed once).\n cookiemunch sandbox [show] | create [--key-name <n>] | delete [--yes]\n The organisation's sandbox: a separate test organisation with the same people and plan\n features, never billed; its keys are test keys and its rights requests are all tests.\n create makes it (or reuses it) and prints a new key for it alone; delete erases it and\n everything in it, after asking. create and delete need a full-access key or orgs:create.\n cookiemunch plan [cookiemunch.json] [--exit-code] [--json]\n cookiemunch apply [cookiemunch.json] [--secret-env NAME] [--secrets-out <file>]\n One file for a site: {site, config, cookies, presets, executors, webhooks, rightsPage,\n partners}, no secrets. plan prints the server's dry run of every part (\"No changes\" when\n it matches); apply applies them in dependency order and logs each. New webhook secrets\n go to --secrets-out (mode 0600).\n cookiemunch --version | version [--json]\n The CLI version; --json adds the API version the server documents.\n\nEvery command takes --json for machine-readable output.\n\nExit codes:\n 0 ok, or nothing to change\n 1 a difference (with --exit-code), a failure, or a failed check\n 2 a usage mistake\n\nEnvironment:\n COOKIEMUNCH_API_KEY an API key (cookiemunch_live_\u2026, or a legacy fck_\u2026). Required.\n COOKIEMUNCH_BASE_URL the API origin. Default https://api.cookiemunch.net.\n COOKIEMUNCH_SITE default for --site.\n COOKIEMUNCH_STRICT_FIELDS=1 send Prefer: strict-unknown-fields on writes: a field the\n API does not know is refused (400 unknown_field), not ignored.\n COOKIEMUNCH_SECRET_RECIPIENT=x25519:<base64> answers carry once-shown secrets sealed to\n this key (sealed_secret), never in plaintext.\n COOKIEMUNCH_ORG the org id doctor checks the key against.\n --idempotency-key <k> send Idempotency-Key on writes: a retry replays the first answer.\n";
53
+ interface Parsed {
54
+ positional: string[];
55
+ flags: Record<string, string | true>;
56
+ }
57
+ export declare function parseArgs(argv: string[]): Parsed;
58
+ /** This package's version, sent in the default User-Agent (a test pins it to package.json). */
59
+ export declare const CLI_VERSION = "0.8.0";
60
+ /** Run the CLI. Returns the process exit code: 0 ok, 1 failed, 2 usage. */
61
+ export declare function run(argv: string[], io: CliIo): Promise<number>;
62
+ export {};
package/dist/csp.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ /**
2
+ * `cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]`
3
+ *
4
+ * One Content-Security-Policy from several products' embed manifests
5
+ * (`/.well-known/<product>-embed.json`, schema https://cookiemunch.net/schemas/embed-v1.json):
6
+ * each manifest lists its origins by directive (`csp`) and the non-origin sources it needs
7
+ * (`requires`); the policy is their union, plus `'self'`.
8
+ *
9
+ * Vendor-neutral: `--merge` takes any manifest URL. The names below are first-class shortcuts
10
+ * for products whose manifest host is known — the same host map the API's importer uses
11
+ * (packages/server/src/manifest-importer.ts; a test keeps the two equal). A product that has not
12
+ * published its manifest yet is reported, and the policy is built from the rest.
13
+ *
14
+ * Needs no API key: every manifest is public, `--site` included (`GET /v1/embed?cbid=`).
15
+ */
16
+ /** Where a known product publishes its manifest: the apex first, then its API host. */
17
+ export declare const KNOWN_MANIFEST_HOSTS: Readonly<Record<string, readonly string[]>>;
18
+ export declare const CSP_FRAMEWORKS: readonly ["next", "express", "nginx"];
19
+ export type CspFramework = (typeof CSP_FRAMEWORKS)[number];
20
+ type Surface = {
21
+ csp?: Record<string, unknown>;
22
+ requires?: Record<string, unknown>;
23
+ };
24
+ type Manifest = {
25
+ product?: unknown;
26
+ surfaces?: Record<string, Surface>;
27
+ };
28
+ export interface ManifestSource {
29
+ /** What the user named: a vendor or a URL. */
30
+ label: string;
31
+ /** URLs to try, in order. */
32
+ urls: string[];
33
+ product?: string;
34
+ }
35
+ /** `atlas,chatly,https://x/.well-known/x-embed.json` → sources to fetch. */
36
+ export declare function manifestSources(list: string, opts: {
37
+ site?: string;
38
+ apiBase: string;
39
+ }): {
40
+ sources: ManifestSource[];
41
+ unknown: string[];
42
+ };
43
+ /** The union of every surface's origins and requirements, by directive; `'self'` first. */
44
+ export declare function mergeManifests(manifests: Manifest[]): Map<string, string[]>;
45
+ /** Placeholders a manifest left for the tenant to fill in: reported, never guessed. */
46
+ export declare function placeholders(manifests: Manifest[]): string[];
47
+ export declare function policyString(policy: Map<string, string[]>): string;
48
+ /** The policy as the framework writes it. */
49
+ export declare function renderPolicy(policy: Map<string, string[]>, framework?: CspFramework): string;
50
+ /** Fetch one manifest, trying each URL in turn. */
51
+ export declare function fetchManifest(src: ManifestSource, fetchImpl: typeof fetch): Promise<{
52
+ ok: true;
53
+ manifest: Manifest;
54
+ url: string;
55
+ } | {
56
+ ok: false;
57
+ error: string;
58
+ }>;
59
+ export interface CspIo {
60
+ fetch: typeof fetch;
61
+ stdout: (text: string) => void;
62
+ stderr: (text: string) => void;
63
+ }
64
+ export declare function cspCommand(opts: {
65
+ merge?: string;
66
+ framework?: string;
67
+ site?: string;
68
+ apiBase: string;
69
+ }, io: CspIo, usage: (message: string) => Error): Promise<number>;
70
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Consent-button parity findings, as terminal text: one line per finding (severity, code,
3
+ * where), then its explanation and fix, indented. See /docs/fair-consent-buttons.
4
+ */
5
+ import type { ButtonParityFinding } from '@cookiemunch/sdk';
6
+ export declare function formatDesignWarnings(findings: ButtonParityFinding[]): string;
7
+ export declare function countBySeverity(findings: ButtonParityFinding[]): {
8
+ warnings: number;
9
+ notices: number;
10
+ };
11
+ export declare function summaryLine(findings: ButtonParityFinding[]): string;
package/dist/diff.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * What a config push would change, computed on this side of the wire.
3
+ *
4
+ * `mergeLikeServer` mirrors the server's `PATCH /v1/sites/{cbid}/config` semantics exactly
5
+ * (JSON Merge Patch, RFC 7386 — packages/server/src/site-config-write.ts mergePatch): the
6
+ * patch wins, nested plain objects merge, arrays and primitives replace wholesale, and a
7
+ * `null` removes the key. A diff computed against any other merge would describe a change
8
+ * the server is not going to make.
9
+ */
10
+ export type Json = null | boolean | number | string | Json[] | {
11
+ [k: string]: Json;
12
+ };
13
+ export interface Change {
14
+ /** Dotted path; array indices in brackets: `banner.content.title`, `geoRules[0].mode`. */
15
+ path: string;
16
+ kind: 'added' | 'removed' | 'changed';
17
+ from?: Json;
18
+ to?: Json;
19
+ }
20
+ /**
21
+ * Returned by a config read, never a setting; the server drops them from a write
22
+ * (packages/server/src/site-config-write.ts READ_ONLY_CONFIG_FIELDS, pinned by a test).
23
+ */
24
+ export declare const READ_ONLY_CONFIG_FIELDS: readonly ["effective", "warnings", "designWarnings", "region", "regulation", "copy", "rightsFormUrl", "version", "observeToken", "sdkBoot", "originEnv"];
25
+ /** A copy of a config without its read-only fields, so a pulled file diffs clean against the server. */
26
+ export declare function withoutReadOnly(cfg: Record<string, unknown>): Record<string, unknown>;
27
+ export declare function isPlainObject(v: unknown): v is Record<string, unknown>;
28
+ export declare function mergeLikeServer(base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown>;
29
+ /** Every leaf that differs between `before` and `after`, in a stable order. */
30
+ export declare function diffJson(before: unknown, after: unknown, path?: string): Change[];
31
+ /** A unified-diff-ish rendering: one line per change. */
32
+ export declare function formatChanges(changes: Change[]): string;
package/dist/index.d.ts CHANGED
@@ -1,165 +1,4 @@
1
- import { CookieMunchClient } from '@cookiemunch/sdk';
2
-
3
- /**
4
- * `cookiemunch` — the Developer API from a terminal or a CI job.
5
- *
6
- * cookiemunch config pull --site <cbid> [--out file]
7
- * cookiemunch config diff --site <cbid> <file> [--replace] [--exit-code]
8
- * cookiemunch config push --site <cbid> <file> [--replace] [--strict]
9
- * cookiemunch config validate --site <cbid> <file> [--replace] [--strict]
10
- * cookiemunch preview --site <cbid> [--url <url>] [--region eu] [--lang de] [--ttl 900] [--open]
11
- * cookiemunch executors test <id> --email <email> [--operation locate]
12
- * cookiemunch executors webhook-test <id> --headers-file <json> --body-file <file>
13
- * cookiemunch executors deliveries <id>
14
- * cookiemunch executors presets
15
- * cookiemunch executors conformance <baseUrl> --secret-env <NAME> [--canary-email <addr>] [--prefix /privacy] [--json]
16
- * cookiemunch executors conformance --connection <id> [--json]
17
- * cookiemunch executors roll-completion-secret <id>
18
- * cookiemunch executors upgrade-preset <id> [--preset <name>] [--version <n>] [--org-id <id>] [--atlas-id-app-id <id>]
19
- * [--revoke-atlas-id-grant] [--accept-preset <path> …] [--dry-run]
20
- * cookiemunch executors recheck <id>
21
- * cookiemunch executors health <id> [--limit <n>]
22
- * cookiemunch rights-page pull|diff|push|publish --site <cbid> [<file>] [--base <updatedAt>] [--yes]
23
- * cookiemunch scan --site <cbid> [--wait] [--timeout <seconds>]
24
- * cookiemunch cookies presets|preset|unpreset|delete-observed|purge-observed --site <cbid> …
25
- * cookiemunch site update --site <cbid> [--domain <host>] [--name <name>] [--aliases a,b] [--dry-run]
26
- * cookiemunch site brand --site <cbid> [--url <https URL> | <brand.json>] [--dry-run]
27
- * cookiemunch health [--site <cbid>] [--json] [--fail-on error|warning|never]
28
- * cookiemunch provision <file> [--dry-run]
29
- * cookiemunch partners list|link|unlink --site <cbid> …
30
- * cookiemunch consent-sync status|rotate|remove|token --site <cbid> …
31
- * cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]
32
- *
33
- * Everything goes through the typed SDK (@cookiemunch/sdk) except where the SDK has no
34
- * method yet; those calls go through `rawRequest` with the same key and base URL. All I/O
35
- * is injected, so the whole CLI is testable with a mocked fetch.
36
- */
37
- declare const DEFAULT_BASE_URL = "https://api.cookiemunch.net";
38
- interface CliIo {
39
- env: Record<string, string | undefined>;
40
- fetch: typeof fetch;
41
- stdout: (text: string) => void;
42
- stderr: (text: string) => void;
43
- readFile: (path: string) => Promise<string>;
44
- /** `mode` is the file mode for a new file (0o600 for anything holding a secret). */
45
- writeFile: (path: string, data: string, mode?: number) => Promise<void>;
46
- /** Open a URL in the user's browser. */
47
- openUrl: (url: string) => Promise<void>;
48
- /**
49
- * Ask a yes/no question. Present only when a person can answer (an interactive terminal);
50
- * absent, a command that needs confirmation refuses unless given --yes.
51
- */
52
- confirm?: (question: string) => Promise<boolean>;
53
- }
54
- declare const USAGE = "cookiemunch \u2014 Cookie Munch from the command line\n\nUsage:\n cookiemunch config pull --site <cbid> [--out <file>]\n Write the site's config as JSON (to stdout, or to <file>).\n cookiemunch config diff --site <cbid> <file> [--replace] [--exit-code]\n Show what pushing <file> would change (the server's dry run; nothing is stored).\n Read-only fields a pulled file carries (effective, designWarnings, ...) are ignored.\n cookiemunch config push --site <cbid> <file> [--replace] [--strict]\n Apply <file>. Default: merged over the stored config (PATCH) \u2014 fields the file\n leaves out keep their value, and a field set to null is removed (it takes its\n default). --replace sends it whole (PUT): a top-level field the file leaves out\n reverts to its default. Prints any design warnings the server found. --strict\n checks the file first and does not push it (exit 1) when Accept all is pushed\n harder than Reject all anywhere \u2014 for CI.\n cookiemunch config validate --site <cbid> <file> [--replace] [--strict]\n Check <file> for consent-button parity on the server, without writing: is Accept\n all more prominent than Reject all (colour, size, placement, copy, custom CSS)?\n Merged over the stored config like push; --replace checks it as sent. --strict\n exits 1 when there is any warning (notices never fail).\n cookiemunch preview --site <cbid> [--url <page>] [--region <eu|de|us-ca\u2026>] [--lang <de\u2026>]\n [--ttl <seconds>] [--open]\n Print (and with --open, open) a link showing the banner as a visitor in that\n region and language sees it. Works in headless browsers; nothing is recorded.\n cookiemunch executors test <id> (--email <email> | --canary) [--operation <locate|export|erase>]\n Try a connected system against one person without filing a request.\n --operation defaults to locate (lookup is accepted as another name for it).\n --canary uses the organisation's canary address instead: no real person, and\n a canary locate also updates the connection's health. Exits 1 when not ok.\n cookiemunch executors webhook-test <id> --headers-file <json> --body-file <file>\n Would this webhook delivery verify? Sends the headers (a JSON object) and the\n body file byte for byte to the receiver's check; nothing is acted on. Prints\n { verified, stage, reason } and exits 1 when it does not verify.\n cookiemunch executors deliveries <id>\n The last 50 deliveries to that connection's webhook, each with its reason.\n cookiemunch executors presets\n The versioned presets, which are usable now and which wait on another\n platform, and the organisation's canary address.\n cookiemunch executors conformance <baseUrl> --secret-env <NAME> [--canary-email <addr>]\n [--prefix /privacy] [--json]\n Check any system against the open cm-standard-v2 executor contract, rule by\n rule, using only the canary subject. The credential is read from the\n environment variable NAME, never from the command line. Without\n --canary-email the organisation's canary address is fetched (needs\n COOKIEMUNCH_API_KEY); with it, no Cookie Munch key is needed at all.\n Exits 1 when any rule fails.\n cookiemunch executors conformance --connection <id> [--json]\n The same suite, run by Cookie Munch against a connected system.\n cookiemunch executors roll-completion-secret <id>\n A new completion secret for that connection, printed once; the old one keeps\n verifying for 24 hours.\n cookiemunch executors upgrade-preset <id> [--preset <name>] [--version <n>]\n [--org-id <id>] [--atlas-id-app-id <id>] [--revoke-atlas-id-grant]\n [--accept-preset <path> \u2026] [--dry-run]\n Rebuild a connection from its preset's latest version (or --version), keeping\n its id and credentials; --preset adopts one on a hand-written connection.\n Your hand edits are kept (the diff marks them kept or conflict); --accept-preset\n (repeatable) takes the preset's value for that path. Prints the diff; --dry-run\n changes nothing. A pinned connection is refused.\n cookiemunch executors recheck <id>\n Re-check a connection now (a canary test that records its health): the hook to\n run after deploying that system's rights API. Exits 1 when it is not ok.\n cookiemunch executors health <id> [--limit <n>]\n The connection's last health checks, newest first (up to 50).\n cookiemunch rights-page pull --site <cbid> [--out <file>]\n Write the site's rights page draft as JSON, and print its updatedAt for --base.\n cookiemunch rights-page diff --site <cbid> <file> [--exit-code]\n Validate <file> on the server (dry run) and show what pushing it would change.\n cookiemunch rights-page push --site <cbid> <file> [--base <updatedAt>]\n Replace the draft with <file>. Nothing is live until publish. Refused (exit 1)\n if the draft changed since the diff, or since --base (the updatedAt pull printed).\n cookiemunch rights-page publish --site <cbid> [--yes] [--base <updatedAt>]\n Publish the draft (it goes live at once). Asks first; --yes skips the question\n and is required when there is no terminal to ask in. Prints why when the page\n cannot go live. Refused (exit 1) if the draft changed after it was read (or\n since --base); --yes never overrides that.\n\n cookiemunch scan --site <cbid> [--wait] [--timeout <seconds>]\n Start a cookie crawl of the site and print its state (JSON). --wait holds on\n until it is done or failed (default up to 120 s, --timeout to change) and exits\n 1 when it failed or is still running at the end. A scan already running is\n waited on rather than started twice.\n\n cookiemunch cookies presets --site <cbid>\n The declaration presets (atlas, forumulate, chatly, cookiemunch, referalli, firstpromoter,\n partnerstack, tapfiliate, impact; referally is the deprecated old name of referalli): what each takes,\n what it declared on this site, and whether the vendor's own manifest exists yet.\n cookiemunch cookies preset <vendor> --site <cbid> [--param k=v \u2026] [--dry-run]\n Declare what that platform writes (cookies and browser storage), marked as\n declared by it; run again to re-sync. Atlas: --param frontendApiHost=auth.example.com\n [--param crossSubdomainCookies=false]. Chatly: --param publicId=ch_web_\u2026 .\n Referral and affiliate presets (referalli, firstpromoter, partnerstack, tapfiliate, impact):\n [--param cookieDomain=.example.com] [--param cookieDays=60] [--param category=\u2026];\n referalli [--param legacyName=false], impact [--param campaignId=\u2026]. A row filed under a\n disabled category prints a warning and a suggestedConfigPatch. Any other vendor is\n declared with the API (PUT /v1/sites/{cbid}/cookies).\n cookiemunch cookies unpreset <vendor> --site <cbid> [--dry-run]\n Remove every declaration that vendor's preset made.\n cookiemunch cookies import-manifest <url> --site <cbid> [--file <manifest.json>] [--dry-run]\n Declare any vendor's cookies and storage from its embed manifest\n (/.well-known/forgedeck-embed.json), by URL or from a file. Remove it with\n cookies unpreset <product>.\n cookiemunch cookies suggestions --site <cbid>\n What to declare: the platforms detected on the site and each undeclared row.\n cookiemunch cookies declare-suggestions --site <cbid> [--names a,b] [--dry-run]\n Declare them: detected vendors' presets, then every other suggestion with a purpose.\n cookiemunch cookies delete-observed <name> --site <cbid> [--dry-run]\n Remove every stored row of that name (a name the site never sets). A declaration stays.\n cookiemunch cookies purge-observed --site <cbid> --since <time> [--until <time>] [--dry-run]\n Remove every row a real visit first reported in that window (ISO-8601 or epoch ms).\n Crawled rows and declarations stay. Run with --dry-run first.\n cookiemunch site update --site <cbid> [--domain <host>] [--name <name> | --clear-name]\n [--aliases <a,b>] [--dry-run]\n Rename or move a site. The cbid and consent ledger stay; a domain move clears\n verification. --dry-run prints the diff and its effects without saving.\n cookiemunch site brand --site <cbid> [--url <https URL> | <brand.json>] [--dry-run]\n Import a brand.json into the banner theme (the rights page uses it too). Values the\n site set itself are kept. With neither --url nor a file, prints the last import.\n cookiemunch consent-sync status --site <cbid>\n Whether hosted consent sync is set up (the secret's last four characters, when it was minted).\n cookiemunch consent-sync rotate --site <cbid>\n Mint the site's consent-sync signing secret, or replace it (the old one stops at once).\n Prints the secret alone on stdout, so it can be piped into your secret store: it is shown once.\n cookiemunch consent-sync remove --site <cbid> --yes\n Remove it: hosted consent sync stops for every visitor.\n cookiemunch consent-sync token --site <cbid> --subject <id> [--ttl <seconds>]\n Sign a test token locally with COOKIEMUNCH_CONSENT_SYNC_SECRET (nothing is sent), e.g. to try\n GET /api/v1/<cbid>/profile with curl.\n cookiemunch health [--site <cbid>] [--json] [--fail-on error|warning|never]\n Every link the site's privacy wiring depends on, with a fix hint for each that\n fails. Exits 1 when a check fails (checks that could not run, or are waived, do not count).\n --fail-on error ignores warnings; --fail-on never always exits 0.\n cookiemunch provision <file> [--dry-run]\n Wire a product's privacy in one call (site, connections, Atlas, Forumulate) from\n a JSON file without secrets: the Atlas key and Forumulate token come from\n COOKIEMUNCH_ATLAS_SECRET_KEY and COOKIEMUNCH_FORUMULATE_TOKEN. Re-running is a\n no-op. Exits 1 when a step failed.\n cookiemunch keys report [--unused-days <n>] [--expiring-days <n>] [--json]\n Key hygiene: keys unused for n days (default 90), keys with broad access, and\n keys expiring within n days (default 14). Needs a full-access key.\n cookiemunch partners list|link|unlink --site <cbid> [--partner <id>]\n [--external-id <id>] [--label <text>] [<linkId>]\n Grant a partner platform the site's consent events (no secret is created), list\n the grants, or revoke one. Any partner this deployment knows (forumulate, atlas, chatly,\n referalli, or one registered for it).\n cookiemunch token exchange --subject-token-env NAME --scope <a,b> --resource org:<id>|site:<cbid> [--expires-in <s>]\n Swap your identity provider's token (read from the variable NAME) for a short-lived, scoped\n API key (at most 1 hour); prints the key alone. Needs no API key.\n cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]\n One Content-Security-Policy from several products' embed manifests\n (/.well-known/forgedeck-embed.json): cookiemunch, atlas, chatly, forumulate,\n referalli, or any manifest URL. --framework prints it for next.config.js,\n Express or nginx; without it, the header value. --site uses your site's own\n Cookie Munch manifest (its logo, fonts, sync endpoint). Needs no API key. Exits 1\n when a named product has not published a manifest (the rest are still merged).\n cookiemunch cookies diff|push <file> --site <cbid> [--replace] [--exit-code]\n Declarations as a file ({\"cookies\": [...]}), through the server's dry run. push applies\n only when something differs; --replace also removes declarations the file leaves out.\n cookiemunch executors pull [<file>] | diff <file> | push <file> [--secret-env NAME]\n Connected systems as a file. The file never carries a secret: a new connection's API key\n comes from the environment variable --secret-env names.\n cookiemunch dsar test [--types access,deletion] [--with-cbid --site <cbid>] [--without-cbid]\n [--email <addr>] [--cleanup]\n File TEST rights requests and read each back. --cleanup deletes exactly the ones this run\n filed (by id; it never deletes by listing).\n cookiemunch doctor [--site <cbid>] [--org <id>]\n The key (and whose org it is, against --org or COOKIEMUNCH_ORG), its expiry, the CLI\n version against the latest, and integration health. Exits 1 when a check fails.\n cookiemunch keys vend --scopes <a,b> --ttl <1h|30m|seconds> [--cbids <x,y>] [--name <n>]\n A short-lived key (at most 12 h) within this key's own scopes; prints the key alone.\n Needs keys:write (or a full-access key).\n cookiemunch keys self | rotate-self\n This key's own prefix, scopes and expiry; or rotate it (the new key is printed once).\n cookiemunch sandbox [show] | create [--key-name <n>] | delete [--yes]\n The organisation's sandbox: a separate test organisation with the same people and plan\n features, never billed; its keys are test keys and its rights requests are all tests.\n create makes it (or reuses it) and prints a new key for it alone; delete erases it and\n everything in it, after asking. create and delete need a full-access key or orgs:create.\n cookiemunch plan [cookiemunch.json] [--exit-code] [--json]\n cookiemunch apply [cookiemunch.json] [--secret-env NAME] [--secrets-out <file>]\n One file for a site: {site, config, cookies, presets, executors, webhooks, rightsPage,\n partners}, no secrets. plan prints the server's dry run of every part (\"No changes\" when\n it matches); apply applies them in dependency order and logs each. New webhook secrets\n go to --secrets-out (mode 0600).\n cookiemunch --version | version [--json]\n The CLI version; --json adds the API version the server documents.\n\nEvery command takes --json for machine-readable output.\n\nExit codes:\n 0 ok, or nothing to change\n 1 a difference (with --exit-code), a failure, or a failed check\n 2 a usage mistake\n\nEnvironment:\n COOKIEMUNCH_API_KEY an API key (cookiemunch_live_\u2026, or a legacy fck_\u2026). Required.\n COOKIEMUNCH_BASE_URL the API origin. Default https://api.cookiemunch.net.\n COOKIEMUNCH_SITE default for --site.\n COOKIEMUNCH_STRICT_FIELDS=1 send Prefer: strict-unknown-fields on writes: a field the\n API does not know is refused (400 unknown_field), not ignored.\n COOKIEMUNCH_SECRET_RECIPIENT=x25519:<base64> answers carry once-shown secrets sealed to\n this key (sealed_secret), never in plaintext.\n COOKIEMUNCH_ORG the org id doctor checks the key against.\n --idempotency-key <k> send Idempotency-Key on writes: a retry replays the first answer.\n";
55
- interface Parsed {
56
- positional: string[];
57
- flags: Record<string, string | true>;
58
- }
59
- declare function parseArgs(argv: string[]): Parsed;
60
- /** Run the CLI. Returns the process exit code: 0 ok, 1 failed, 2 usage. */
61
- declare function run(argv: string[], io: CliIo): Promise<number>;
62
-
63
- /**
64
- * What a config push would change, computed on this side of the wire.
65
- *
66
- * `mergeLikeServer` mirrors the server's `PATCH /v1/sites/{cbid}/config` semantics exactly
67
- * (JSON Merge Patch, RFC 7386 — packages/server/src/site-config-write.ts mergePatch): the
68
- * patch wins, nested plain objects merge, arrays and primitives replace wholesale, and a
69
- * `null` removes the key. A diff computed against any other merge would describe a change
70
- * the server is not going to make.
71
- */
72
- type Json = null | boolean | number | string | Json[] | {
73
- [k: string]: Json;
74
- };
75
- interface Change {
76
- /** Dotted path; array indices in brackets: `banner.content.title`, `geoRules[0].mode`. */
77
- path: string;
78
- kind: 'added' | 'removed' | 'changed';
79
- from?: Json;
80
- to?: Json;
81
- }
82
- declare function mergeLikeServer(base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown>;
83
- /** Every leaf that differs between `before` and `after`, in a stable order. */
84
- declare function diffJson(before: unknown, after: unknown, path?: string): Change[];
85
- /** A unified-diff-ish rendering: one line per change. */
86
- declare function formatChanges(changes: Change[]): string;
87
-
88
- /**
89
- * `cookiemunch rights-page pull|diff|push|publish` — the hosted rights page as code.
90
- *
91
- * Unlike `config diff`, `diff` asks the server: the rights page has a real dry run, so the
92
- * diff is against what the server would store (normalised and sanitised), and an invalid
93
- * file fails with the server's issues before anything is written.
94
- */
95
-
96
- interface Helpers {
97
- requireSite(): string;
98
- readJson(path: string | undefined): Promise<Record<string, unknown>>;
99
- usage(msg: string): Error;
100
- }
101
- declare function rightsPageCommand(sub: string | undefined, p: {
102
- positional: string[];
103
- flags: Record<string, string | true>;
104
- }, io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
105
-
106
- /**
107
- * `cookiemunch csp --merge <vendors|urls> [--framework next|express|nginx] [--site <cbid>]`
108
- *
109
- * One Content-Security-Policy from several products' embed manifests
110
- * (`/.well-known/forgedeck-embed.json`, schema https://cookiemunch.net/schemas/embed-v1.json):
111
- * each manifest lists its origins by directive (`csp`) and the non-origin sources it needs
112
- * (`requires`); the policy is their union, plus `'self'`.
113
- *
114
- * Vendor-neutral: `--merge` takes any manifest URL. The names below are first-class shortcuts
115
- * for products whose manifest host is known — the same host map the API's importer uses
116
- * (packages/server/src/manifest-importer.ts; a test keeps the two equal). A product that has not
117
- * published its manifest yet is reported, and the policy is built from the rest.
118
- *
119
- * Needs no API key: every manifest is public, `--site` included (`GET /v1/embed?cbid=`).
120
- */
121
- /** Where a known product publishes its manifest: the apex first, then its API host. */
122
- declare const KNOWN_MANIFEST_HOSTS: Readonly<Record<string, readonly string[]>>;
123
- declare const CSP_FRAMEWORKS: readonly ["next", "express", "nginx"];
124
- type CspFramework = (typeof CSP_FRAMEWORKS)[number];
125
- type Surface = {
126
- csp?: Record<string, unknown>;
127
- requires?: Record<string, unknown>;
128
- };
129
- type Manifest = {
130
- product?: unknown;
131
- surfaces?: Record<string, Surface>;
132
- };
133
- interface ManifestSource {
134
- /** What the user named: a vendor or a URL. */
135
- label: string;
136
- /** URLs to try, in order. */
137
- urls: string[];
138
- product?: string;
139
- }
140
- /** `atlas,chatly,https://x/.well-known/forgedeck-embed.json` → sources to fetch. */
141
- declare function manifestSources(list: string, opts: {
142
- site?: string;
143
- apiBase: string;
144
- }): {
145
- sources: ManifestSource[];
146
- unknown: string[];
147
- };
148
- /** The union of every surface's origins and requirements, by directive; `'self'` first. */
149
- declare function mergeManifests(manifests: Manifest[]): Map<string, string[]>;
150
- declare function policyString(policy: Map<string, string[]>): string;
151
- /** The policy as the framework writes it. */
152
- declare function renderPolicy(policy: Map<string, string[]>, framework?: CspFramework): string;
153
- interface CspIo {
154
- fetch: typeof fetch;
155
- stdout: (text: string) => void;
156
- stderr: (text: string) => void;
157
- }
158
- declare function cspCommand(opts: {
159
- merge?: string;
160
- framework?: string;
161
- site?: string;
162
- apiBase: string;
163
- }, io: CspIo, usage: (message: string) => Error): Promise<number>;
164
-
165
- export { CSP_FRAMEWORKS, type Change, type CliIo, type CspFramework, DEFAULT_BASE_URL, KNOWN_MANIFEST_HOSTS, USAGE, cspCommand, diffJson, formatChanges, manifestSources, mergeLikeServer, mergeManifests, parseArgs, policyString, renderPolicy, rightsPageCommand, run };
1
+ export { run, parseArgs, USAGE, DEFAULT_BASE_URL, type CliIo } from './cli.js';
2
+ export { diffJson, formatChanges, mergeLikeServer, type Change } from './diff.js';
3
+ export { rightsPageCommand } from './rights-page.js';
4
+ export { cspCommand, mergeManifests, renderPolicy, policyString, manifestSources, KNOWN_MANIFEST_HOSTS, CSP_FRAMEWORKS, type CspFramework } from './csp.js';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  renderPolicy,
15
15
  rightsPageCommand,
16
16
  run
17
- } from "./chunk-HTHRKPXA.js";
17
+ } from "./chunk-6KXGHY4M.js";
18
18
  export {
19
19
  CSP_FRAMEWORKS,
20
20
  DEFAULT_BASE_URL,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `cookiemunch site update`, `cookiemunch health`, `cookiemunch provision` and `cookiemunch partners`.
3
+ *
4
+ * Provisioning secrets are read from the environment (COOKIEMUNCH_ATLAS_SECRET_KEY,
5
+ * COOKIEMUNCH_FORUMULATE_TOKEN), never from the command line where they would land in shell history,
6
+ * and are never printed.
7
+ */
8
+ import type { CookieMunchClient } from '@cookiemunch/sdk';
9
+ import type { CliIo } from './cli.js';
10
+ interface Helpers {
11
+ requireSite(): string;
12
+ site(): string | undefined;
13
+ readJson(path: string | undefined): Promise<Record<string, unknown>>;
14
+ usage(msg: string): Error;
15
+ flag(name: string): string | true | undefined;
16
+ }
17
+ /** `cookiemunch site update --site <cbid> [--domain d] [--name n | --clear-name] [--aliases a,b] [--dry-run]` */
18
+ export declare function siteCommand(sub: string | undefined, io: CliIo, client: CookieMunchClient, h: Helpers, file?: string): Promise<number>;
19
+ /** `cookiemunch health [--site <cbid>]` — exits 1 when a check fails, so CI can gate on it. */
20
+ export declare function healthCommand(io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
21
+ /** `cookiemunch provision <file> [--dry-run]` — the file has no secrets; the environment supplies them. */
22
+ export declare function provisionCommand(file: string | undefined, io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
23
+ /** `cookiemunch partners list|link|unlink --site <cbid> …` */
24
+ export declare function partnersCommand(sub: string | undefined, rest: string[], io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
25
+ /** `cookiemunch keys report [--unused-days n] [--expiring-days n] [--json]` */
26
+ export declare function keysCommand(sub: string | undefined, io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
27
+ export {};
package/dist/ops.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * CLI completeness (CMU-B15, D11, D12, S02):
3
+ *
4
+ * cookiemunch --version | version [--json]
5
+ * cookiemunch cookies diff|push <file> --site <cbid> [--replace] declarations as a file, through the server's dry run
6
+ * cookiemunch executors pull|diff|push <file> [--secret-env NAME] connected systems as a file, never carrying a secret
7
+ * cookiemunch dsar test --types access,deletion [--with-cbid] [--without-cbid] [--cleanup]
8
+ * cookiemunch doctor [--site <cbid>] [--org <id>]
9
+ * cookiemunch keys vend --scopes a,b --ttl 1h [--cbids x,y] [--name n]
10
+ * cookiemunch keys self | rotate-self
11
+ * cookiemunch sandbox [show] | create [--key-name n] | delete [--yes]
12
+ * cookiemunch plan|apply <cookiemunch.json>
13
+ *
14
+ * Exit codes everywhere: 0 ok (or no changes), 1 a difference, a failure or a failed check, 2 a usage mistake.
15
+ */
16
+ import type { CookieMunchClient } from '@cookiemunch/sdk';
17
+ import type { CliIo } from './cli.js';
18
+ export interface OpsHelpers {
19
+ requireSite(): string;
20
+ site(): string | undefined;
21
+ readJson(path: string | undefined): Promise<Record<string, unknown>>;
22
+ usage(msg: string): Error;
23
+ flag(name: string): string | true | undefined;
24
+ positional: string[];
25
+ }
26
+ /** `version [--json]`: the CLI's version, and with --json the API version the server documents. */
27
+ export declare function versionCommand(io: CliIo, cliVersion: string, base: string, asJson: boolean): Promise<number>;
28
+ export declare function cookiesFileCommand(sub: 'diff' | 'push', io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
29
+ export declare function executorsFileCommand(sub: 'pull' | 'diff' | 'push', io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
30
+ /**
31
+ * File test rights requests (guide step 16), read each back, and with --cleanup delete EXACTLY the ids this
32
+ * run created: never a list-and-delete, which once removed live rows (memory never-clean-up-by-listing).
33
+ */
34
+ export declare function dsarTestCommand(io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
35
+ export declare function doctorCommand(io: CliIo, client: CookieMunchClient, h: OpsHelpers, cliVersion: string): Promise<number>;
36
+ /** `1h`, `30m`, `90s`, `3600` → seconds. */
37
+ export declare function parseTtl(v: string): number | null;
38
+ export declare function keysExtraCommand(sub: string, io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
39
+ /** `sandbox [show]`, `sandbox create [--key-name n]` (prints the test key alone), `sandbox delete [--yes]`. */
40
+ export declare function sandboxCommand(sub: string | undefined, io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
41
+ /**
42
+ * One file for everything a site's privacy setup is (CMU-D12). `plan` asks the server's dry run of every part
43
+ * and prints one combined diff; `apply` applies the parts in dependency order (site → config → cookies →
44
+ * presets → rights page → executors → webhooks → partners), reads each back, and logs when.
45
+ * No secret ever goes in the file: an executor's key comes from --secret-env, a new webhook's secret is
46
+ * written to --secrets-out (0600) or the webhook is not created.
47
+ */
48
+ export declare function bundleCommand(sub: 'plan' | 'apply', io: CliIo, client: CookieMunchClient, h: OpsHelpers): Promise<number>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `cookiemunch rights-page pull|diff|push|publish` — the hosted rights page as code.
3
+ *
4
+ * Unlike `config diff`, `diff` asks the server: the rights page has a real dry run, so the
5
+ * diff is against what the server would store (normalised and sanitised), and an invalid
6
+ * file fails with the server's issues before anything is written.
7
+ */
8
+ import { type CookieMunchClient } from '@cookiemunch/sdk';
9
+ import type { CliIo } from './cli.js';
10
+ interface Helpers {
11
+ requireSite(): string;
12
+ readJson(path: string | undefined): Promise<Record<string, unknown>>;
13
+ usage(msg: string): Error;
14
+ }
15
+ export declare function rightsPageCommand(sub: string | undefined, p: {
16
+ positional: string[];
17
+ flags: Record<string, string | true>;
18
+ }, io: CliIo, client: CookieMunchClient, h: Helpers): Promise<number>;
19
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cookiemunch/cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "cookiemunch — config as code, banner previews and connection tests from a terminal or CI, over the Cookie Munch Developer API",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,11 +31,11 @@
31
31
  "access": "public"
32
32
  },
33
33
  "scripts": {
34
- "build": "tsup",
34
+ "build": "tsup && tsc -p tsconfig.json --emitDeclarationOnly --declaration",
35
35
  "test": "vitest run"
36
36
  },
37
37
  "dependencies": {
38
- "@cookiemunch/sdk": "^0.7.0"
38
+ "@cookiemunch/sdk": "^0.8.0"
39
39
  },
40
40
  "homepage": "https://cookiemunch.net/docs",
41
41
  "bugs": {