@primitivedotdev/sdk 0.19.0 → 0.20.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/api/generated/index.js +1 -1
- package/dist/api/generated/sdk.gen.js +205 -0
- package/dist/api/index.d.ts +2 -2
- package/dist/{api-C5VR_Opg.js → api-DNF21MDo.js} +246 -1
- package/dist/{index-oRkCqj6u.d.ts → index-C6ObsYjq.d.ts} +732 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/oclif/api-command.js +13 -0
- package/dist/oclif/commands/functions-deploy.js +108 -0
- package/dist/oclif/commands/functions-redeploy.js +97 -0
- package/dist/oclif/index.js +10 -0
- package/dist/openapi/openapi.generated.js +872 -1
- package/dist/openapi/operations.generated.js +690 -0
- package/oclif.manifest.json +703 -1
- package/package.json +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { A as UnknownEvent, C as ParsedDataFailed, D as RawContentDownloadOnly, E as RawContent, M as WebhookAttachment, N as WebhookEvent, O as RawContentInline, S as ParsedDataComplete, T as ParsedStatus, _ as ForwardResultInline, a as DmarcPolicy, b as KnownWebhookEvent, c as EmailAnalysis, d as EventType, f as ForwardAnalysis, g as ForwardResultAttachmentSkipped, h as ForwardResultAttachmentAnalyzed, i as DkimSignature, j as ValidateEmailAuthResult, k as SpfResult, l as EmailAuth, m as ForwardResult, n as AuthVerdict, o as DmarcResult, p as ForwardOriginalSender, r as DkimResult, s as EmailAddress, t as AuthConfidence, u as EmailReceivedEvent, v as ForwardVerdict, w as ParsedError, x as ParsedData, y as ForwardVerification } from "./types-9vXGZjPd.js";
|
|
2
2
|
import { a as buildReplySubject, c as parseHeaderAddress, i as buildForwardSubject, n as ReceivedEmailAddress, o as formatAddress, r as ReceivedEmailThread, s as normalizeReceivedEmail, t as ReceivedEmail } from "./received-email-DNjpq_Wt.js";
|
|
3
|
-
import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendInput, f as SendResult, g as createPrimitiveClient, l as ReplyInput, m as client, n as ForwardInput, p as SendThreadInput, s as PrimitiveClient } from "./index-
|
|
3
|
+
import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendInput, f as SendResult, g as createPrimitiveClient, l as ReplyInput, m as client, n as ForwardInput, p as SendThreadInput, s as PrimitiveClient } from "./index-C6ObsYjq.js";
|
|
4
4
|
import { A as VerifyOptions, B as PAYLOAD_ERRORS, C as signStandardWebhooksPayload, D as PRIMITIVE_CONFIRMED_HEADER, E as LEGACY_SIGNATURE_HEADER, F as VerifyDownloadTokenResult, G as VERIFICATION_ERRORS, H as RAW_EMAIL_ERRORS, I as generateDownloadToken, J as WebhookPayloadErrorCode, K as WebhookErrorCode, L as verifyDownloadToken, M as verifyWebhookSignature, N as GenerateDownloadTokenOptions, O as PRIMITIVE_SIGNATURE_HEADER, P as VerifyDownloadTokenOptions, Q as WebhookVerificationErrorCode, R as safeValidateEmailReceivedEvent, S as StandardWebhooksVerifyOptions, T as LEGACY_CONFIRMED_HEADER, U as RawEmailDecodeError, V as PrimitiveWebhookError, W as RawEmailDecodeErrorCode, X as WebhookValidationErrorCode, Y as WebhookValidationError, Z as WebhookVerificationError, _ as emailReceivedEventJsonSchema, a as confirmedHeaders, b as STANDARD_WEBHOOK_TIMESTAMP_HEADER, c as handleWebhook, d as isRawIncluded, f as parseWebhookEvent, g as validateEmailAuth, h as WEBHOOK_VERSION, i as WebhookHeaders, j as signWebhookPayload, k as SignResult, l as isDownloadExpired, m as verifyRawEmailDownload, n as HandleWebhookOptions, o as decodeRawEmail, p as receive, q as WebhookPayloadError, r as ReceiveRequestOptions, s as getDownloadTimeRemaining, t as DecodeRawEmailOptions, u as isEmailReceivedEvent, v as STANDARD_WEBHOOK_ID_HEADER, w as verifyStandardWebhooksSignature, x as StandardWebhooksSignResult, y as STANDARD_WEBHOOK_SIGNATURE_HEADER, z as validateEmailReceivedEvent } from "./index-CDlwyxdp.js";
|
|
5
5
|
|
|
6
6
|
//#region src/index.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as parseHeaderAddress, i as normalizeReceivedEmail, n as buildReplySubject, r as formatAddress, t as buildForwardSubject } from "./received-email-D6tKtWwW.js";
|
|
2
|
-
import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-
|
|
2
|
+
import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-DNF21MDo.js";
|
|
3
3
|
import { A as PRIMITIVE_CONFIRMED_HEADER, B as RAW_EMAIL_ERRORS, C as STANDARD_WEBHOOK_ID_HEADER, D as verifyStandardWebhooksSignature, E as signStandardWebhooksPayload, F as verifyDownloadToken, G as WebhookVerificationError, H as VERIFICATION_ERRORS, I as safeValidateEmailReceivedEvent, L as validateEmailReceivedEvent, M as signWebhookPayload, N as verifyWebhookSignature, O as LEGACY_CONFIRMED_HEADER, P as generateDownloadToken, R as PAYLOAD_ERRORS, S as emailReceivedEventJsonSchema, T as STANDARD_WEBHOOK_TIMESTAMP_HEADER, U as WebhookPayloadError, V as RawEmailDecodeError, W as WebhookValidationError, _ as DmarcResult, a as isDownloadExpired, b as ParsedStatus, c as parseWebhookEvent, d as WEBHOOK_VERSION, f as validateEmailAuth, g as DmarcPolicy, h as DkimResult, i as handleWebhook, j as PRIMITIVE_SIGNATURE_HEADER, k as LEGACY_SIGNATURE_HEADER, l as receive, m as AuthVerdict, n as decodeRawEmail, o as isEmailReceivedEvent, p as AuthConfidence, r as getDownloadTimeRemaining, s as isRawIncluded, t as confirmedHeaders, u as verifyRawEmailDownload, v as EventType, w as STANDARD_WEBHOOK_SIGNATURE_HEADER, x as SpfResult, y as ForwardVerdict, z as PrimitiveWebhookError } from "./webhook-rUjGV6Zu.js";
|
|
4
4
|
//#region src/index.ts
|
|
5
5
|
const primitive = {
|
|
@@ -224,6 +224,19 @@ export function readJsonBody(flags) {
|
|
|
224
224
|
}
|
|
225
225
|
return undefined;
|
|
226
226
|
}
|
|
227
|
+
// Read a UTF-8 text file off disk, mapping any failure to a CLIError
|
|
228
|
+
// tagged with the originating flag so the user sees which path failed
|
|
229
|
+
// to open. Used by hand-rolled commands that take a file-input flag
|
|
230
|
+
// (e.g. functions:deploy --file).
|
|
231
|
+
export function readTextFileFlag(path, flagLabel) {
|
|
232
|
+
try {
|
|
233
|
+
return readFileSync(path, "utf8");
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
237
|
+
throw cliError(`Could not read ${flagLabel} ${path}: ${detail}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
227
240
|
export function extractErrorPayload(raw) {
|
|
228
241
|
if (raw &&
|
|
229
242
|
typeof raw === "object" &&
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import { createFunction } from "../../api/generated/sdk.gen.js";
|
|
3
|
+
import { PrimitiveApiClient } from "../../api/index.js";
|
|
4
|
+
import { extractErrorPayload, readTextFileFlag, removeStaleSavedCredentialOnUnauthorized, runWithTiming, TIME_FLAG_DESCRIPTION, writeErrorWithHints, } from "../api-command.js";
|
|
5
|
+
import { resolveCliAuth } from "../auth.js";
|
|
6
|
+
// `primitive functions:deploy` is the agent-grade shortcut for
|
|
7
|
+
// `functions:create-function`. The underlying operation takes `code`
|
|
8
|
+
// as a string in the JSON body, which is awkward at the CLI for
|
|
9
|
+
// multi-line bundles: agents would otherwise have to shell-escape an
|
|
10
|
+
// entire ESM file or write a temp body.json. This command reads the
|
|
11
|
+
// bundle straight off disk via --file, so the natural workflow is:
|
|
12
|
+
//
|
|
13
|
+
// esbuild handler.ts --bundle --format=esm --outfile=bundle.js
|
|
14
|
+
// primitive functions:deploy --name myfn --file bundle.js
|
|
15
|
+
//
|
|
16
|
+
// Source maps follow the same shape via --source-map-file. They are
|
|
17
|
+
// stored only on the runtime side (not in our database) so dropping
|
|
18
|
+
// them later in the pipeline is fine; the CLI just hands them through.
|
|
19
|
+
//
|
|
20
|
+
// For full control (raw body, --raw-body JSON, etc.) the underlying
|
|
21
|
+
// `functions:create-function` operation stays available.
|
|
22
|
+
class FunctionsDeployCommand extends Command {
|
|
23
|
+
static description = `Deploy a new function from a bundled handler file. Agent-grade shortcut for functions:create-function.
|
|
24
|
+
|
|
25
|
+
Reads the bundle off disk (--file) instead of forcing the caller to
|
|
26
|
+
serialize the source into a JSON body. Use the underlying operation
|
|
27
|
+
\`functions:create-function\` if you need the full flag surface
|
|
28
|
+
(raw-body JSON, etc.).`;
|
|
29
|
+
static summary = "Deploy a new function from a bundled handler file";
|
|
30
|
+
static examples = [
|
|
31
|
+
"<%= config.bin %> functions:deploy --name forwarder --file ./bundle.js",
|
|
32
|
+
"<%= config.bin %> functions:deploy --name forwarder --file ./bundle.js --source-map-file ./bundle.js.map",
|
|
33
|
+
];
|
|
34
|
+
static flags = {
|
|
35
|
+
"api-key": Flags.string({
|
|
36
|
+
description: "Primitive API key (defaults to PRIMITIVE_API_KEY or saved `primitive login` credentials)",
|
|
37
|
+
env: "PRIMITIVE_API_KEY",
|
|
38
|
+
}),
|
|
39
|
+
"base-url": Flags.string({
|
|
40
|
+
description: "API base URL (defaults to PRIMITIVE_API_URL or production)",
|
|
41
|
+
env: "PRIMITIVE_API_URL",
|
|
42
|
+
}),
|
|
43
|
+
name: Flags.string({
|
|
44
|
+
description: "Slug-style name. Lowercase letters, digits, hyphens, underscores. 1-64 chars. Must be unique within the org.",
|
|
45
|
+
required: true,
|
|
46
|
+
}),
|
|
47
|
+
file: Flags.string({
|
|
48
|
+
description: "Path to the bundled ESM handler file (single self-contained module). Loaded as the `code` body field.",
|
|
49
|
+
required: true,
|
|
50
|
+
}),
|
|
51
|
+
"source-map-file": Flags.string({
|
|
52
|
+
description: "Optional path to a source map for the bundle. Stored only on the runtime side and used to symbolicate stack traces.",
|
|
53
|
+
}),
|
|
54
|
+
time: Flags.boolean({
|
|
55
|
+
description: TIME_FLAG_DESCRIPTION,
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
async run() {
|
|
59
|
+
const { flags } = await this.parse(FunctionsDeployCommand);
|
|
60
|
+
await runWithTiming(flags.time, async () => {
|
|
61
|
+
// Reads are inside the timed block so --time captures disk I/O
|
|
62
|
+
// alongside the API call. A pathological filesystem (NFS, slow
|
|
63
|
+
// FUSE mount) showing up here is exactly the kind of latency
|
|
64
|
+
// surprise --time is meant to surface.
|
|
65
|
+
const code = readTextFileFlag(flags.file, "--file");
|
|
66
|
+
const sourceMap = flags["source-map-file"]
|
|
67
|
+
? readTextFileFlag(flags["source-map-file"], "--source-map-file")
|
|
68
|
+
: undefined;
|
|
69
|
+
const baseUrlOverridden = flags["base-url"] !== undefined;
|
|
70
|
+
const auth = resolveCliAuth({
|
|
71
|
+
apiKey: flags["api-key"],
|
|
72
|
+
baseUrl: flags["base-url"],
|
|
73
|
+
configDir: this.config.configDir,
|
|
74
|
+
});
|
|
75
|
+
const apiClient = new PrimitiveApiClient({
|
|
76
|
+
apiKey: auth.apiKey,
|
|
77
|
+
baseUrl: auth.baseUrl,
|
|
78
|
+
});
|
|
79
|
+
const authFailureContext = {
|
|
80
|
+
auth,
|
|
81
|
+
baseUrlOverridden,
|
|
82
|
+
configDir: this.config.configDir,
|
|
83
|
+
};
|
|
84
|
+
const result = await createFunction({
|
|
85
|
+
body: {
|
|
86
|
+
name: flags.name,
|
|
87
|
+
code,
|
|
88
|
+
...(sourceMap !== undefined ? { sourceMap } : {}),
|
|
89
|
+
},
|
|
90
|
+
client: apiClient.client,
|
|
91
|
+
responseStyle: "fields",
|
|
92
|
+
});
|
|
93
|
+
if (result.error) {
|
|
94
|
+
const errorPayload = extractErrorPayload(result.error);
|
|
95
|
+
writeErrorWithHints(errorPayload);
|
|
96
|
+
removeStaleSavedCredentialOnUnauthorized({
|
|
97
|
+
...authFailureContext,
|
|
98
|
+
payload: errorPayload,
|
|
99
|
+
});
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const envelope = result.data;
|
|
104
|
+
this.log(JSON.stringify(envelope?.data ?? null, null, 2));
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export default FunctionsDeployCommand;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import { updateFunction } from "../../api/generated/sdk.gen.js";
|
|
3
|
+
import { PrimitiveApiClient } from "../../api/index.js";
|
|
4
|
+
import { extractErrorPayload, readTextFileFlag, removeStaleSavedCredentialOnUnauthorized, runWithTiming, TIME_FLAG_DESCRIPTION, writeErrorWithHints, } from "../api-command.js";
|
|
5
|
+
import { resolveCliAuth } from "../auth.js";
|
|
6
|
+
// `primitive functions:redeploy` is the agent-grade shortcut for
|
|
7
|
+
// `functions:update-function`. Same file-reading ergonomic as
|
|
8
|
+
// functions:deploy but for an existing function. Use this to push a
|
|
9
|
+
// new bundle, OR to refresh secret bindings: passing the
|
|
10
|
+
// previously-deployed bundle (or any equivalent file) re-runs the
|
|
11
|
+
// deploy and refreshes env from the secrets table, which is how
|
|
12
|
+
// secret writes go live.
|
|
13
|
+
class FunctionsRedeployCommand extends Command {
|
|
14
|
+
static description = `Update or redeploy a function from a bundled handler file. Agent-grade shortcut for functions:update-function.
|
|
15
|
+
|
|
16
|
+
Use to push a new bundle OR to refresh secret bindings into the
|
|
17
|
+
running handler. The same file is fine for both: the deploy reads
|
|
18
|
+
the bindings table fresh on every call, so passing the existing
|
|
19
|
+
bundle picks up any secret writes since the last deploy.`;
|
|
20
|
+
static summary = "Redeploy a function from a bundled handler file";
|
|
21
|
+
static examples = [
|
|
22
|
+
"<%= config.bin %> functions:redeploy --id <fn-id> --file ./bundle.js",
|
|
23
|
+
"<%= config.bin %> functions:redeploy --id <fn-id> --file ./bundle.js --source-map-file ./bundle.js.map",
|
|
24
|
+
];
|
|
25
|
+
static flags = {
|
|
26
|
+
"api-key": Flags.string({
|
|
27
|
+
description: "Primitive API key (defaults to PRIMITIVE_API_KEY or saved `primitive login` credentials)",
|
|
28
|
+
env: "PRIMITIVE_API_KEY",
|
|
29
|
+
}),
|
|
30
|
+
"base-url": Flags.string({
|
|
31
|
+
description: "API base URL (defaults to PRIMITIVE_API_URL or production)",
|
|
32
|
+
env: "PRIMITIVE_API_URL",
|
|
33
|
+
}),
|
|
34
|
+
id: Flags.string({
|
|
35
|
+
description: "Function id (UUID). The function must already exist.",
|
|
36
|
+
required: true,
|
|
37
|
+
}),
|
|
38
|
+
file: Flags.string({
|
|
39
|
+
description: "Path to the bundled ESM handler file. Loaded as the `code` body field.",
|
|
40
|
+
required: true,
|
|
41
|
+
}),
|
|
42
|
+
"source-map-file": Flags.string({
|
|
43
|
+
description: "Optional path to a source map for the bundle. Used to symbolicate stack traces in the function's logs.",
|
|
44
|
+
}),
|
|
45
|
+
time: Flags.boolean({
|
|
46
|
+
description: TIME_FLAG_DESCRIPTION,
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
async run() {
|
|
50
|
+
const { flags } = await this.parse(FunctionsRedeployCommand);
|
|
51
|
+
await runWithTiming(flags.time, async () => {
|
|
52
|
+
// Reads inside the timed block: --time captures disk I/O too,
|
|
53
|
+
// which is the latency the flag is meant to surface.
|
|
54
|
+
const code = readTextFileFlag(flags.file, "--file");
|
|
55
|
+
const sourceMap = flags["source-map-file"]
|
|
56
|
+
? readTextFileFlag(flags["source-map-file"], "--source-map-file")
|
|
57
|
+
: undefined;
|
|
58
|
+
const baseUrlOverridden = flags["base-url"] !== undefined;
|
|
59
|
+
const auth = resolveCliAuth({
|
|
60
|
+
apiKey: flags["api-key"],
|
|
61
|
+
baseUrl: flags["base-url"],
|
|
62
|
+
configDir: this.config.configDir,
|
|
63
|
+
});
|
|
64
|
+
const apiClient = new PrimitiveApiClient({
|
|
65
|
+
apiKey: auth.apiKey,
|
|
66
|
+
baseUrl: auth.baseUrl,
|
|
67
|
+
});
|
|
68
|
+
const authFailureContext = {
|
|
69
|
+
auth,
|
|
70
|
+
baseUrlOverridden,
|
|
71
|
+
configDir: this.config.configDir,
|
|
72
|
+
};
|
|
73
|
+
const result = await updateFunction({
|
|
74
|
+
path: { id: flags.id },
|
|
75
|
+
body: {
|
|
76
|
+
code,
|
|
77
|
+
...(sourceMap !== undefined ? { sourceMap } : {}),
|
|
78
|
+
},
|
|
79
|
+
client: apiClient.client,
|
|
80
|
+
responseStyle: "fields",
|
|
81
|
+
});
|
|
82
|
+
if (result.error) {
|
|
83
|
+
const errorPayload = extractErrorPayload(result.error);
|
|
84
|
+
writeErrorWithHints(errorPayload);
|
|
85
|
+
removeStaleSavedCredentialOnUnauthorized({
|
|
86
|
+
...authFailureContext,
|
|
87
|
+
payload: errorPayload,
|
|
88
|
+
});
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const envelope = result.data;
|
|
93
|
+
this.log(JSON.stringify(envelope?.data ?? null, null, 2));
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export default FunctionsRedeployCommand;
|
package/dist/oclif/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import { Args, Command, Errors } from "@oclif/core";
|
|
|
2
2
|
import { operationManifest, } from "../openapi/index.js";
|
|
3
3
|
import { createOperationCommand } from "./api-command.js";
|
|
4
4
|
import EmailsLatestCommand from "./commands/emails-latest.js";
|
|
5
|
+
import FunctionsDeployCommand from "./commands/functions-deploy.js";
|
|
6
|
+
import FunctionsRedeployCommand from "./commands/functions-redeploy.js";
|
|
5
7
|
import LoginCommand from "./commands/login.js";
|
|
6
8
|
import LogoutCommand from "./commands/logout.js";
|
|
7
9
|
import SendCommand from "./commands/send.js";
|
|
@@ -131,5 +133,13 @@ export const COMMANDS = {
|
|
|
131
133
|
// inbound emails as a compact text table. emails:list-emails stays
|
|
132
134
|
// available for the full JSON envelope + cursor pagination.
|
|
133
135
|
"emails:latest": EmailsLatestCommand,
|
|
136
|
+
// `functions:deploy` and `functions:redeploy` are file-input
|
|
137
|
+
// shortcuts for create-function / update-function. The underlying
|
|
138
|
+
// ops take `code` as a body string, which is awkward at the CLI
|
|
139
|
+
// for multi-line bundles; these read the bundle off disk and pass
|
|
140
|
+
// it through. The auto-generated functions:* operations stay
|
|
141
|
+
// available for callers that want the full surface.
|
|
142
|
+
"functions:deploy": FunctionsDeployCommand,
|
|
143
|
+
"functions:redeploy": FunctionsRedeployCommand,
|
|
134
144
|
...generatedCommands,
|
|
135
145
|
};
|