clefbase 1.5.0 → 1.5.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/cli.js CHANGED
@@ -34878,7 +34878,7 @@ async function promptRequired(message) {
34878
34878
  }
34879
34879
 
34880
34880
  // package.json
34881
- var version = "1.5.0";
34881
+ var version = "1.5.1";
34882
34882
 
34883
34883
  // src/cli/index.ts
34884
34884
  var program2 = new Command();
@@ -1,46 +1,171 @@
1
1
  import { HttpClient } from "./http";
2
2
  import type { FunctionRuntime, FunctionTrigger, FunctionTriggerType, FunctionDef, FunctionExecution, FunctionsConfig, FunctionStats, DeployFunctionOptions, HttpsCallableResult } from "./types";
3
3
  export type { FunctionRuntime, FunctionTrigger, FunctionTriggerType, FunctionDef, FunctionExecution, FunctionsConfig, FunctionStats, DeployFunctionOptions, HttpsCallableResult, };
4
+ /**
5
+ * Thrown by all Functions SDK methods when the server returns an error
6
+ * or the function itself errors / times out.
7
+ *
8
+ * @example
9
+ * import { FunctionsError } from "clefbase";
10
+ *
11
+ * try {
12
+ * const { data } = await fns.call("myFunction", payload);
13
+ * } catch (err) {
14
+ * if (err instanceof FunctionsError) {
15
+ * console.error("HTTP status:", err.httpStatus); // e.g. 500
16
+ * console.error("Message:", err.message);
17
+ * }
18
+ * }
19
+ */
20
+ export declare class FunctionsError extends Error {
21
+ /** HTTP status code returned by the server, if available */
22
+ readonly httpStatus?: number | undefined;
23
+ constructor(message: string,
24
+ /** HTTP status code returned by the server, if available */
25
+ httpStatus?: number | undefined);
26
+ }
4
27
  /**
5
28
  * Create a strongly-typed callable reference to an HTTP-triggered function.
29
+ * Store it once and call it as many times as needed.
6
30
  *
7
31
  * @example
8
32
  * const add = httpsCallable<{ a: number; b: number }, { sum: number }>(fns, "addNumbers");
9
- * const { data } = await add({ a: 3, b: 4 });
10
- * console.log(data.sum); // 7
33
+ * const { data, durationMs } = await add({ a: 3, b: 4 });
34
+ * console.log(data.sum); // 7
35
+ * console.log(durationMs); // e.g. 42
11
36
  */
12
37
  export declare function httpsCallable<TInput = unknown, TOutput = unknown>(fns: ClefbaseFunctions, name: string): (data?: TInput) => Promise<HttpsCallableResult<TOutput>>;
13
38
  /**
14
- * Clefbase Functions service.
39
+ * Call an HTTP-triggered function in one shot — no need to create a callable ref.
40
+ * Equivalent to `httpsCallable(fns, name)(data)`.
41
+ *
42
+ * @example
43
+ * const { data } = await callFunction(fns, "resizeImage", { url: "https://..." });
44
+ */
45
+ export declare function callFunction<TInput = unknown, TOutput = unknown>(fns: ClefbaseFunctions, name: string, data?: TInput): Promise<HttpsCallableResult<TOutput>>;
46
+ /**
47
+ * Deploy (or redeploy) a function from source code.
48
+ * Equivalent to `fns.deploy(options)`.
49
+ *
50
+ * @example
51
+ * await deployFunction(fns, {
52
+ * name: "greetUser",
53
+ * runtime: "node",
54
+ * trigger: { type: "http" },
55
+ * source: `export async function handler(ctx) { return { hi: ctx.data.name }; }`,
56
+ * });
57
+ */
58
+ export declare function deployFunction(fns: ClefbaseFunctions, options: DeployFunctionOptions): Promise<FunctionDef>;
59
+ /**
60
+ * Delete a deployed function by name.
61
+ * Equivalent to `fns.delete(name)`.
62
+ */
63
+ export declare function deleteFunction(fns: ClefbaseFunctions, name: string): Promise<{
64
+ deleted: boolean;
65
+ name: string;
66
+ }>;
67
+ /**
68
+ * List all functions deployed to this project.
69
+ * Equivalent to `fns.list()`.
70
+ */
71
+ export declare function listFunctions(fns: ClefbaseFunctions): Promise<FunctionDef[]>;
72
+ /**
73
+ * Fetch execution history for a function.
74
+ * Equivalent to `fns.executions(name, limit)`.
75
+ */
76
+ export declare function getFunctionExecutions(fns: ClefbaseFunctions, name: string, limit?: number): Promise<FunctionExecution[]>;
77
+ /**
78
+ * Attach a user auth token so that HTTP function calls include the caller's
79
+ * identity in `ctx.auth` inside the function.
80
+ *
81
+ * Obtain the token from `auth.signIn()` or `auth.signUp()`.
82
+ * Pass `null` to remove a previously set token (e.g. after sign-out).
83
+ *
84
+ * @example
85
+ * import { getAuth, getFunctions, setAuthToken, callFunction } from "clefbase";
86
+ *
87
+ * const auth = getAuth(app);
88
+ * const fns = getFunctions(app);
89
+ *
90
+ * const { token } = await auth.signIn("alice@example.com", "password123");
91
+ * setAuthToken(app, token);
92
+ *
93
+ * // ctx.auth.uid / ctx.auth.email are now available inside the function
94
+ * const { data } = await callFunction(fns, "getUserProfile");
95
+ *
96
+ * // On sign-out:
97
+ * await auth.signOut();
98
+ * setAuthToken(app, null);
99
+ */
100
+ export declare function setAuthToken(app: {
101
+ authToken?: string;
102
+ }, token: string | null): void;
103
+ /**
104
+ * Deploy a function from a source file on disk. **Node.js / CLI environments only.**
15
105
  *
16
- * Obtained via `getFunctions(app)`.
106
+ * Reads the file at `filePath` and calls `fns.deploy()` with the source.
107
+ * Runtime is NOT auto-detected from the file extension — pass it explicitly so
108
+ * you can deploy `.ts` files as Node.js without a separate transpile step.
17
109
  *
18
110
  * @example
19
- * import { initClefbase, getFunctions, httpsCallable } from "clefbase";
111
+ * // Deploy a TypeScript file as a Node.js function
112
+ * await deployFromFile(fns, {
113
+ * name: "processOrder",
114
+ * runtime: "node",
115
+ * trigger: { type: "http" },
116
+ * filePath: "./src/functions/processOrder.ts",
117
+ * env: { STRIPE_KEY: process.env.STRIPE_KEY! },
118
+ * });
119
+ *
120
+ * // Deploy a Python file
121
+ * await deployFromFile(fns, {
122
+ * name: "analyzeSentiment",
123
+ * runtime: "python",
124
+ * trigger: { type: "http" },
125
+ * filePath: "./fns/analyze_sentiment.py",
126
+ * timeoutMs: 60_000,
127
+ * });
128
+ */
129
+ export declare function deployFromFile(fns: ClefbaseFunctions, options: Omit<DeployFunctionOptions, "source"> & {
130
+ filePath: string;
131
+ }): Promise<FunctionDef>;
132
+ /**
133
+ * Clefbase Functions service — obtained via `getFunctions(app)`.
134
+ *
135
+ * You can use instance methods directly OR the equivalent top-level
136
+ * convenience functions (`httpsCallable`, `callFunction`, `deployFunction`,
137
+ * `deployFromFile`, `setAuthToken`, etc.) — both styles are supported.
138
+ *
139
+ * @example
140
+ * import { initClefbase, getFunctions, httpsCallable, setAuthToken } from "clefbase";
20
141
  *
21
142
  * const app = initClefbase({ serverUrl, projectId, apiKey, adminSecret: "" });
22
143
  * const fns = getFunctions(app);
23
144
  *
24
- * // Call an HTTP function
25
- * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
26
- * const { data } = await greet({ name: "Alice" });
27
- *
28
- * // Deploy from source
145
+ * // ── Deploy ──────────────────────────────────────────────────────────────
29
146
  * await fns.deploy({
30
147
  * name: "greetUser",
31
148
  * runtime: "node",
32
149
  * trigger: { type: "http" },
33
- * source: `export async function handler(ctx) { return { message: "Hi " + ctx.data.name }; }`,
150
+ * source: `export async function handler(ctx) { return { hi: ctx.data.name }; }`,
34
151
  * });
152
+ *
153
+ * // ── Typed callable ──────────────────────────────────────────────────────
154
+ * const greet = httpsCallable<{ name: string }, { hi: string }>(fns, "greetUser");
155
+ * const { data } = await greet({ name: "Alice" });
156
+ *
157
+ * // ── Auth-aware call ─────────────────────────────────────────────────────
158
+ * const { token } = await getAuth(app).signIn("alice@example.com", "pw");
159
+ * setAuthToken(app, token);
160
+ * await fns.call("secureFunction"); // ctx.auth.uid is now set
35
161
  */
36
162
  export declare class ClefbaseFunctions {
37
163
  private readonly _http;
38
164
  /** @internal */
39
165
  constructor(_http: HttpClient);
40
166
  /**
41
- * Initialise Functions for the project if not already done.
42
- * Safe to call multiple times returns the existing config if found.
43
- * Called automatically by `deploy()` so you rarely need this directly.
167
+ * Initialise Functions for this project if not already done.
168
+ * `deploy()` calls this automatically, so you rarely need it directly.
44
169
  */
45
170
  initProject(opts?: {
46
171
  maxConcurrentExecutions?: number;
@@ -48,28 +173,19 @@ export declare class ClefbaseFunctions {
48
173
  }): Promise<FunctionsConfig>;
49
174
  /**
50
175
  * Deploy (or redeploy) a function from source code.
51
- * Calling this a second time with the same `name` updates the function in-place.
52
176
  *
53
- * @example
54
- * await fns.deploy({
55
- * name: "sendWelcome",
56
- * runtime: "node",
57
- * trigger: { type: "onUserCreate" },
58
- * source: `
59
- * export async function handler(ctx) {
60
- * console.log("New user:", ctx.data.email);
61
- * }
62
- * `,
63
- * });
177
+ * Redeploying with the same `name` updates the function in-place.
178
+ * Scheduled functions are re-armed with the new cron expression automatically.
64
179
  */
65
180
  deploy(options: DeployFunctionOptions): Promise<FunctionDef>;
66
181
  /**
67
182
  * List all functions deployed to this project.
68
- * Returns a lightweight summary (no source code).
183
+ * Source code is not included in the response.
69
184
  */
70
185
  list(): Promise<FunctionDef[]>;
71
186
  /**
72
187
  * Delete a deployed function by name.
188
+ * Scheduled functions are de-registered from the cron timer immediately.
73
189
  */
74
190
  delete(name: string): Promise<{
75
191
  deleted: boolean;
@@ -77,17 +193,16 @@ export declare class ClefbaseFunctions {
77
193
  }>;
78
194
  /**
79
195
  * Call an HTTP-triggered function and return its result.
80
- * Throws a `ClefbaseError` if the function errors or times out.
81
196
  *
82
- * @example
83
- * const { data, durationMs } = await fns.call("processOrder", { orderId: "abc" });
197
+ * Throws a `FunctionsError` on function error, timeout, or not-found.
198
+ * For a reusable typed reference, use `httpsCallable()` instead.
84
199
  */
85
200
  call<TInput = unknown, TOutput = unknown>(name: string, data?: TInput): Promise<HttpsCallableResult<TOutput>>;
86
201
  /**
87
- * Fetch the execution history for a specific function.
202
+ * Fetch execution history for a specific function.
88
203
  *
89
- * @param name Function name
90
- * @param limit Max results to return (default: 20, max: 100)
204
+ * @param name Function name
205
+ * @param limit Max results to return (default: 20, max: 100)
91
206
  */
92
207
  executions(name: string, limit?: number): Promise<FunctionExecution[]>;
93
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,GACpB,CAAC;AAIF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAC/D,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,MAAM,GACX,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAE1D;AAID;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,iBAAiB;IAEhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IADlC,gBAAgB;gBACa,KAAK,EAAE,UAAU;IAI9C;;;;OAIG;IACG,WAAW,CAAC,IAAI,CAAC,EAAE;QAAE,uBAAuB,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAQnH;;;;;;;;;;;;;;;OAeG;IACG,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IAMlE;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAMpC;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAMvE;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IASxC;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAMzE"}
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"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"}
package/dist/functions.js CHANGED
@@ -1,115 +1,306 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ClefbaseFunctions = void 0;
36
+ exports.ClefbaseFunctions = exports.FunctionsError = void 0;
4
37
  exports.httpsCallable = httpsCallable;
5
- // ─── HttpsCallable ────────────────────────────────────────────────────────────
38
+ exports.callFunction = callFunction;
39
+ exports.deployFunction = deployFunction;
40
+ exports.deleteFunction = deleteFunction;
41
+ exports.listFunctions = listFunctions;
42
+ exports.getFunctionExecutions = getFunctionExecutions;
43
+ exports.setAuthToken = setAuthToken;
44
+ exports.deployFromFile = deployFromFile;
45
+ const types_1 = require("./types");
46
+ // ─── FunctionsError ───────────────────────────────────────────────────────────
47
+ /**
48
+ * Thrown by all Functions SDK methods when the server returns an error
49
+ * or the function itself errors / times out.
50
+ *
51
+ * @example
52
+ * import { FunctionsError } from "clefbase";
53
+ *
54
+ * try {
55
+ * const { data } = await fns.call("myFunction", payload);
56
+ * } catch (err) {
57
+ * if (err instanceof FunctionsError) {
58
+ * console.error("HTTP status:", err.httpStatus); // e.g. 500
59
+ * console.error("Message:", err.message);
60
+ * }
61
+ * }
62
+ */
63
+ class FunctionsError extends Error {
64
+ constructor(message,
65
+ /** HTTP status code returned by the server, if available */
66
+ httpStatus) {
67
+ super(message);
68
+ this.httpStatus = httpStatus;
69
+ this.name = "FunctionsError";
70
+ if (Error.captureStackTrace) {
71
+ Error.captureStackTrace(this, FunctionsError);
72
+ }
73
+ }
74
+ }
75
+ exports.FunctionsError = FunctionsError;
76
+ // ─── httpsCallable (top-level factory) ───────────────────────────────────────
6
77
  /**
7
78
  * Create a strongly-typed callable reference to an HTTP-triggered function.
79
+ * Store it once and call it as many times as needed.
8
80
  *
9
81
  * @example
10
82
  * const add = httpsCallable<{ a: number; b: number }, { sum: number }>(fns, "addNumbers");
11
- * const { data } = await add({ a: 3, b: 4 });
12
- * console.log(data.sum); // 7
83
+ * const { data, durationMs } = await add({ a: 3, b: 4 });
84
+ * console.log(data.sum); // 7
85
+ * console.log(durationMs); // e.g. 42
13
86
  */
14
87
  function httpsCallable(fns, name) {
15
88
  return (data) => fns.call(name, data);
16
89
  }
90
+ // ─── callFunction ─────────────────────────────────────────────────────────────
91
+ /**
92
+ * Call an HTTP-triggered function in one shot — no need to create a callable ref.
93
+ * Equivalent to `httpsCallable(fns, name)(data)`.
94
+ *
95
+ * @example
96
+ * const { data } = await callFunction(fns, "resizeImage", { url: "https://..." });
97
+ */
98
+ async function callFunction(fns, name, data) {
99
+ return fns.call(name, data);
100
+ }
101
+ // ─── deployFunction ───────────────────────────────────────────────────────────
102
+ /**
103
+ * Deploy (or redeploy) a function from source code.
104
+ * Equivalent to `fns.deploy(options)`.
105
+ *
106
+ * @example
107
+ * await deployFunction(fns, {
108
+ * name: "greetUser",
109
+ * runtime: "node",
110
+ * trigger: { type: "http" },
111
+ * source: `export async function handler(ctx) { return { hi: ctx.data.name }; }`,
112
+ * });
113
+ */
114
+ async function deployFunction(fns, options) {
115
+ return fns.deploy(options);
116
+ }
117
+ // ─── deleteFunction ───────────────────────────────────────────────────────────
118
+ /**
119
+ * Delete a deployed function by name.
120
+ * Equivalent to `fns.delete(name)`.
121
+ */
122
+ async function deleteFunction(fns, name) {
123
+ return fns.delete(name);
124
+ }
125
+ // ─── listFunctions ────────────────────────────────────────────────────────────
126
+ /**
127
+ * List all functions deployed to this project.
128
+ * Equivalent to `fns.list()`.
129
+ */
130
+ async function listFunctions(fns) {
131
+ return fns.list();
132
+ }
133
+ // ─── getFunctionExecutions ────────────────────────────────────────────────────
134
+ /**
135
+ * Fetch execution history for a function.
136
+ * Equivalent to `fns.executions(name, limit)`.
137
+ */
138
+ async function getFunctionExecutions(fns, name, limit = 20) {
139
+ return fns.executions(name, limit);
140
+ }
141
+ // ─── setAuthToken ─────────────────────────────────────────────────────────────
142
+ /**
143
+ * Attach a user auth token so that HTTP function calls include the caller's
144
+ * identity in `ctx.auth` inside the function.
145
+ *
146
+ * Obtain the token from `auth.signIn()` or `auth.signUp()`.
147
+ * Pass `null` to remove a previously set token (e.g. after sign-out).
148
+ *
149
+ * @example
150
+ * import { getAuth, getFunctions, setAuthToken, callFunction } from "clefbase";
151
+ *
152
+ * const auth = getAuth(app);
153
+ * const fns = getFunctions(app);
154
+ *
155
+ * const { token } = await auth.signIn("alice@example.com", "password123");
156
+ * setAuthToken(app, token);
157
+ *
158
+ * // ctx.auth.uid / ctx.auth.email are now available inside the function
159
+ * const { data } = await callFunction(fns, "getUserProfile");
160
+ *
161
+ * // On sign-out:
162
+ * await auth.signOut();
163
+ * setAuthToken(app, null);
164
+ */
165
+ function setAuthToken(app, token) {
166
+ app.authToken = token ?? undefined;
167
+ }
168
+ // ─── deployFromFile ───────────────────────────────────────────────────────────
169
+ /**
170
+ * Deploy a function from a source file on disk. **Node.js / CLI environments only.**
171
+ *
172
+ * Reads the file at `filePath` and calls `fns.deploy()` with the source.
173
+ * Runtime is NOT auto-detected from the file extension — pass it explicitly so
174
+ * you can deploy `.ts` files as Node.js without a separate transpile step.
175
+ *
176
+ * @example
177
+ * // Deploy a TypeScript file as a Node.js function
178
+ * await deployFromFile(fns, {
179
+ * name: "processOrder",
180
+ * runtime: "node",
181
+ * trigger: { type: "http" },
182
+ * filePath: "./src/functions/processOrder.ts",
183
+ * env: { STRIPE_KEY: process.env.STRIPE_KEY! },
184
+ * });
185
+ *
186
+ * // Deploy a Python file
187
+ * await deployFromFile(fns, {
188
+ * name: "analyzeSentiment",
189
+ * runtime: "python",
190
+ * trigger: { type: "http" },
191
+ * filePath: "./fns/analyze_sentiment.py",
192
+ * timeoutMs: 60_000,
193
+ * });
194
+ */
195
+ async function deployFromFile(fns, options) {
196
+ let readFileSync;
197
+ try {
198
+ ({ readFileSync } = await Promise.resolve().then(() => __importStar(require("fs"))));
199
+ }
200
+ catch {
201
+ throw new FunctionsError("deployFromFile() requires Node.js — it cannot be called in a browser environment.");
202
+ }
203
+ const { filePath, ...rest } = options;
204
+ const source = readFileSync(filePath, "utf8");
205
+ return fns.deploy({ ...rest, source });
206
+ }
17
207
  // ─── ClefbaseFunctions ────────────────────────────────────────────────────────
18
208
  /**
19
- * Clefbase Functions service.
209
+ * Clefbase Functions service — obtained via `getFunctions(app)`.
20
210
  *
21
- * Obtained via `getFunctions(app)`.
211
+ * You can use instance methods directly OR the equivalent top-level
212
+ * convenience functions (`httpsCallable`, `callFunction`, `deployFunction`,
213
+ * `deployFromFile`, `setAuthToken`, etc.) — both styles are supported.
22
214
  *
23
215
  * @example
24
- * import { initClefbase, getFunctions, httpsCallable } from "clefbase";
216
+ * import { initClefbase, getFunctions, httpsCallable, setAuthToken } from "clefbase";
25
217
  *
26
218
  * const app = initClefbase({ serverUrl, projectId, apiKey, adminSecret: "" });
27
219
  * const fns = getFunctions(app);
28
220
  *
29
- * // Call an HTTP function
30
- * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
31
- * const { data } = await greet({ name: "Alice" });
32
- *
33
- * // Deploy from source
221
+ * // ── Deploy ──────────────────────────────────────────────────────────────
34
222
  * await fns.deploy({
35
223
  * name: "greetUser",
36
224
  * runtime: "node",
37
225
  * trigger: { type: "http" },
38
- * source: `export async function handler(ctx) { return { message: "Hi " + ctx.data.name }; }`,
226
+ * source: `export async function handler(ctx) { return { hi: ctx.data.name }; }`,
39
227
  * });
228
+ *
229
+ * // ── Typed callable ──────────────────────────────────────────────────────
230
+ * const greet = httpsCallable<{ name: string }, { hi: string }>(fns, "greetUser");
231
+ * const { data } = await greet({ name: "Alice" });
232
+ *
233
+ * // ── Auth-aware call ─────────────────────────────────────────────────────
234
+ * const { token } = await getAuth(app).signIn("alice@example.com", "pw");
235
+ * setAuthToken(app, token);
236
+ * await fns.call("secureFunction"); // ctx.auth.uid is now set
40
237
  */
41
238
  class ClefbaseFunctions {
42
239
  /** @internal */
43
240
  constructor(_http) {
44
241
  this._http = _http;
45
242
  }
46
- // ─── Config ────────────────────────────────────────────────────────────────
243
+ // ─── initProject ──────────────────────────────────────────────────────────
47
244
  /**
48
- * Initialise Functions for the project if not already done.
49
- * Safe to call multiple times returns the existing config if found.
50
- * Called automatically by `deploy()` so you rarely need this directly.
245
+ * Initialise Functions for this project if not already done.
246
+ * `deploy()` calls this automatically, so you rarely need it directly.
51
247
  */
52
248
  async initProject(opts) {
53
- // The external SDK router auto-initialises on deploy, but expose this
54
- // for explicit setup or config updates.
55
249
  return this._http.post("/", opts ?? {});
56
250
  }
57
- // ─── Deploy ────────────────────────────────────────────────────────────────
251
+ // ─── deploy ───────────────────────────────────────────────────────────────
58
252
  /**
59
253
  * Deploy (or redeploy) a function from source code.
60
- * Calling this a second time with the same `name` updates the function in-place.
61
254
  *
62
- * @example
63
- * await fns.deploy({
64
- * name: "sendWelcome",
65
- * runtime: "node",
66
- * trigger: { type: "onUserCreate" },
67
- * source: `
68
- * export async function handler(ctx) {
69
- * console.log("New user:", ctx.data.email);
70
- * }
71
- * `,
72
- * });
255
+ * Redeploying with the same `name` updates the function in-place.
256
+ * Scheduled functions are re-armed with the new cron expression automatically.
73
257
  */
74
258
  async deploy(options) {
75
259
  return this._http.post("/deploy", options);
76
260
  }
77
- // ─── List ──────────────────────────────────────────────────────────────────
261
+ // ─── list ─────────────────────────────────────────────────────────────────
78
262
  /**
79
263
  * List all functions deployed to this project.
80
- * Returns a lightweight summary (no source code).
264
+ * Source code is not included in the response.
81
265
  */
82
266
  async list() {
83
267
  return this._http.get("/");
84
268
  }
85
- // ─── Delete ────────────────────────────────────────────────────────────────
269
+ // ─── delete ───────────────────────────────────────────────────────────────
86
270
  /**
87
271
  * Delete a deployed function by name.
272
+ * Scheduled functions are de-registered from the cron timer immediately.
88
273
  */
89
274
  async delete(name) {
90
275
  return this._http.delete(`/${encodeURIComponent(name)}`);
91
276
  }
92
- // ─── Call ──────────────────────────────────────────────────────────────────
277
+ // ─── call ─────────────────────────────────────────────────────────────────
93
278
  /**
94
279
  * Call an HTTP-triggered function and return its result.
95
- * Throws a `ClefbaseError` if the function errors or times out.
96
280
  *
97
- * @example
98
- * const { data, durationMs } = await fns.call("processOrder", { orderId: "abc" });
281
+ * Throws a `FunctionsError` on function error, timeout, or not-found.
282
+ * For a reusable typed reference, use `httpsCallable()` instead.
99
283
  */
100
284
  async call(name, data) {
101
- return this._http.post(`/call/${encodeURIComponent(name)}`, { data: data ?? null });
285
+ try {
286
+ return await this._http.post(`/call/${encodeURIComponent(name)}`, { data: data ?? null });
287
+ }
288
+ catch (err) {
289
+ if (err instanceof types_1.ClefbaseError) {
290
+ throw new FunctionsError(err.message, err.status);
291
+ }
292
+ throw err;
293
+ }
102
294
  }
103
- // ─── Executions ────────────────────────────────────────────────────────────
295
+ // ─── executions ───────────────────────────────────────────────────────────
104
296
  /**
105
- * Fetch the execution history for a specific function.
297
+ * Fetch execution history for a specific function.
106
298
  *
107
- * @param name Function name
108
- * @param limit Max results to return (default: 20, max: 100)
299
+ * @param name Function name
300
+ * @param limit Max results to return (default: 20, max: 100)
109
301
  */
110
302
  async executions(name, limit = 20) {
111
- const l = Math.min(limit, 100);
112
- return this._http.get(`/${encodeURIComponent(name)}/executions?limit=${l}`);
303
+ return this._http.get(`/${encodeURIComponent(name)}/executions?limit=${Math.min(limit, 100)}`);
113
304
  }
114
305
  }
115
306
  exports.ClefbaseFunctions = ClefbaseFunctions;
@@ -1 +1 @@
1
- {"version":3,"file":"functions.js","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":";;;AAmCA,sCAKC;AAfD,iFAAiF;AAEjF;;;;;;;GAOG;AACH,SAAgB,aAAa,CAC3B,GAAsB,EACtB,IAAY;IAEZ,OAAO,CAAC,IAAa,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAkB,IAAI,EAAE,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAa,iBAAiB;IAC5B,gBAAgB;IAChB,YAA6B,KAAiB;QAAjB,UAAK,GAAL,KAAK,CAAY;IAAG,CAAC;IAElD,8EAA8E;IAE9E;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,IAAsE;QACtF,sEAAsE;QACtE,wCAAwC;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAkB,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,8EAA8E;IAE9E;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,CAAC,OAA8B;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAE9E;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,8EAA8E;IAE9E;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAqC,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,8EAA8E;IAE9E;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CACR,IAAY,EACZ,IAAa;QAEb,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CACpB,SAAS,kBAAkB,CAAC,IAAI,CAAC,EAAE,EACnC,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CACvB,CAAC;IACJ,CAAC;IAED,8EAA8E;IAE9E;;;;;OAKG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,KAAK,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CACnB,IAAI,kBAAkB,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,CACrD,CAAC;IACJ,CAAC;CACF;AA3FD,8CA2FC"}
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,48 +2,58 @@
2
2
  * clefbase — Firebase-style SDK for Clefbase / Cleforyx
3
3
  *
4
4
  * @example
5
- * import { initClefbase, getDatabase, getAuth, getStorage, getHosting, getFunctions, httpsCallable, FieldValue } from "clefbase";
5
+ * import {
6
+ * initClefbase, getDatabase, getAuth, getStorage, getHosting,
7
+ * getFunctions, httpsCallable, callFunction, deployFunction, deployFromFile,
8
+ * setAuthToken, FunctionsError, FieldValue,
9
+ * } from "clefbase";
6
10
  *
7
- * const app = initClefbase({
8
- * serverUrl: "https://api.cleforyx.com",
9
- * projectId: "my_project_abc",
10
- * apiKey: "cfx_...",
11
- * adminSecret: "", // only needed for hosting
12
- * });
11
+ * const app = initClefbase({ serverUrl, projectId, apiKey, adminSecret: "" });
12
+ * const fns = getFunctions(app);
13
+ * const auth = getAuth(app);
14
+ *
15
+ * // ── Auth-aware function call ───────────────────────────────────────────────
16
+ * const { token } = await auth.signIn("alice@example.com", "password123");
17
+ * setAuthToken(app, token); // ctx.auth.uid / email now available in function
18
+ *
19
+ * // ── Typed callable ────────────────────────────────────────────────────────
20
+ * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
21
+ * const { data } = await greet({ name: "Alice" });
13
22
  *
14
- * // ── Functions ──────────────────────────────────────────────────────────────
15
- * const fns = getFunctions(app);
23
+ * // ── One-shot call ─────────────────────────────────────────────────────────
24
+ * const { data } = await callFunction(fns, "greetUser", { name: "Bob" });
16
25
  *
17
- * // Deploy a function
18
- * await fns.deploy({
26
+ * // ── Deploy from source ────────────────────────────────────────────────────
27
+ * await deployFunction(fns, {
19
28
  * name: "greetUser",
20
29
  * runtime: "node",
21
30
  * trigger: { type: "http" },
22
- * source: `
23
- * export async function handler(ctx) {
24
- * return { message: "Hello, " + ctx.data.name + "!" };
25
- * }
26
- * `,
31
+ * source: `export async function handler(ctx) { return { message: "Hi " + ctx.data.name }; }`,
27
32
  * });
28
33
  *
29
- * // Create a typed callable
30
- * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
31
- * const { data } = await greet({ name: "Alice" });
34
+ * // ── Deploy from file (Node.js) ────────────────────────────────────────────
35
+ * await deployFromFile(fns, {
36
+ * name: "processOrder",
37
+ * runtime: "node",
38
+ * trigger: { type: "http" },
39
+ * filePath: "./src/functions/processOrder.ts",
40
+ * });
32
41
  *
33
- * // Or call directly
34
- * const { data } = await fns.call("greetUser", { name: "Alice" });
42
+ * // ── Error handling ────────────────────────────────────────────────────────
43
+ * try {
44
+ * await callFunction(fns, "mayFail");
45
+ * } catch (err) {
46
+ * if (err instanceof FunctionsError) {
47
+ * console.error(err.httpStatus, err.message);
48
+ * }
49
+ * }
35
50
  *
36
- * // ── Database ────────────────────────────────────────────────────────────────
51
+ * // ── Database ──────────────────────────────────────────────────────────────
37
52
  * const db = getDatabase(app);
38
- *
39
53
  * await db.collection("posts").doc("p1").update({
40
- * views: FieldValue.increment(1),
54
+ * views: FieldValue.increment(1),
41
55
  * publishedAt: FieldValue.serverTimestamp(),
42
56
  * });
43
- *
44
- * const batch = db.batch();
45
- * batch.update(db.collection("counters").doc("hits"), { n: FieldValue.increment(1) });
46
- * await batch.commit();
47
57
  */
48
58
  export { ClefbaseApp, initClefbase, getApp, getDatabase, getAuth, getStorage, getHosting, getFunctions, } from "./app";
49
59
  export { Database, CollectionReference, CollectionGroup, DocumentReference, Query, WriteBatch, Transaction, runTransaction, } from "./db";
@@ -55,7 +65,7 @@ export type { StorageImageStatus } from "./react/StorageImage";
55
65
  export { EmailVerificationCard } from "./react/EmailVerificationCard";
56
66
  export { ClefbaseHosting, SiteReference } from "./hosting";
57
67
  export type { HostingSite, HostingDeploy, HostingFile, DeployResult, DeployOptions, HostingStatus, DeployStatus, } from "./hosting";
58
- export { ClefbaseFunctions, httpsCallable } from "./functions";
68
+ export { ClefbaseFunctions, FunctionsError, httpsCallable, callFunction, deployFunction, deleteFunction, listFunctions, getFunctionExecutions, setAuthToken, deployFromFile, } from "./functions";
59
69
  export type { FunctionRuntime, FunctionTrigger, FunctionTriggerType, FunctionDef, FunctionExecution, FunctionsConfig, FunctionStats, DeployFunctionOptions, HttpsCallableResult, } from "./functions";
60
70
  export { FieldValue, FieldValueSentinel } from "./field_value";
61
71
  export type { FieldValueType } from "./field_value";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAGnB,OAAO,EAEL,iBAAiB,EAEjB,cAAc,EAEd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -3,51 +3,61 @@
3
3
  * clefbase — Firebase-style SDK for Clefbase / Cleforyx
4
4
  *
5
5
  * @example
6
- * import { initClefbase, getDatabase, getAuth, getStorage, getHosting, getFunctions, httpsCallable, FieldValue } from "clefbase";
6
+ * import {
7
+ * initClefbase, getDatabase, getAuth, getStorage, getHosting,
8
+ * getFunctions, httpsCallable, callFunction, deployFunction, deployFromFile,
9
+ * setAuthToken, FunctionsError, FieldValue,
10
+ * } from "clefbase";
7
11
  *
8
- * const app = initClefbase({
9
- * serverUrl: "https://api.cleforyx.com",
10
- * projectId: "my_project_abc",
11
- * apiKey: "cfx_...",
12
- * adminSecret: "", // only needed for hosting
13
- * });
12
+ * const app = initClefbase({ serverUrl, projectId, apiKey, adminSecret: "" });
13
+ * const fns = getFunctions(app);
14
+ * const auth = getAuth(app);
15
+ *
16
+ * // ── Auth-aware function call ───────────────────────────────────────────────
17
+ * const { token } = await auth.signIn("alice@example.com", "password123");
18
+ * setAuthToken(app, token); // ctx.auth.uid / email now available in function
19
+ *
20
+ * // ── Typed callable ────────────────────────────────────────────────────────
21
+ * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
22
+ * const { data } = await greet({ name: "Alice" });
14
23
  *
15
- * // ── Functions ──────────────────────────────────────────────────────────────
16
- * const fns = getFunctions(app);
24
+ * // ── One-shot call ─────────────────────────────────────────────────────────
25
+ * const { data } = await callFunction(fns, "greetUser", { name: "Bob" });
17
26
  *
18
- * // Deploy a function
19
- * await fns.deploy({
27
+ * // ── Deploy from source ────────────────────────────────────────────────────
28
+ * await deployFunction(fns, {
20
29
  * name: "greetUser",
21
30
  * runtime: "node",
22
31
  * trigger: { type: "http" },
23
- * source: `
24
- * export async function handler(ctx) {
25
- * return { message: "Hello, " + ctx.data.name + "!" };
26
- * }
27
- * `,
32
+ * source: `export async function handler(ctx) { return { message: "Hi " + ctx.data.name }; }`,
28
33
  * });
29
34
  *
30
- * // Create a typed callable
31
- * const greet = httpsCallable<{ name: string }, { message: string }>(fns, "greetUser");
32
- * const { data } = await greet({ name: "Alice" });
35
+ * // ── Deploy from file (Node.js) ────────────────────────────────────────────
36
+ * await deployFromFile(fns, {
37
+ * name: "processOrder",
38
+ * runtime: "node",
39
+ * trigger: { type: "http" },
40
+ * filePath: "./src/functions/processOrder.ts",
41
+ * });
33
42
  *
34
- * // Or call directly
35
- * const { data } = await fns.call("greetUser", { name: "Alice" });
43
+ * // ── Error handling ────────────────────────────────────────────────────────
44
+ * try {
45
+ * await callFunction(fns, "mayFail");
46
+ * } catch (err) {
47
+ * if (err instanceof FunctionsError) {
48
+ * console.error(err.httpStatus, err.message);
49
+ * }
50
+ * }
36
51
  *
37
- * // ── Database ────────────────────────────────────────────────────────────────
52
+ * // ── Database ──────────────────────────────────────────────────────────────
38
53
  * const db = getDatabase(app);
39
- *
40
54
  * await db.collection("posts").doc("p1").update({
41
- * views: FieldValue.increment(1),
55
+ * views: FieldValue.increment(1),
42
56
  * publishedAt: FieldValue.serverTimestamp(),
43
57
  * });
44
- *
45
- * const batch = db.batch();
46
- * batch.update(db.collection("counters").doc("hits"), { n: FieldValue.increment(1) });
47
- * await batch.commit();
48
58
  */
49
59
  Object.defineProperty(exports, "__esModule", { value: true });
50
- exports.ClefbaseError = exports.FieldValueSentinel = exports.FieldValue = exports.httpsCallable = exports.ClefbaseFunctions = exports.SiteReference = exports.ClefbaseHosting = exports.EmailVerificationCard = exports.BucketReference = exports.StorageReference = exports.ClefbaseStorage = exports.Auth = exports.runTransaction = exports.Transaction = exports.WriteBatch = exports.Query = exports.DocumentReference = exports.CollectionGroup = exports.CollectionReference = exports.Database = exports.getFunctions = exports.getHosting = exports.getStorage = exports.getAuth = exports.getDatabase = exports.getApp = exports.initClefbase = exports.ClefbaseApp = void 0;
60
+ exports.ClefbaseError = exports.FieldValueSentinel = exports.FieldValue = exports.deployFromFile = exports.setAuthToken = exports.getFunctionExecutions = exports.listFunctions = exports.deleteFunction = exports.deployFunction = exports.callFunction = exports.httpsCallable = exports.FunctionsError = exports.ClefbaseFunctions = exports.SiteReference = exports.ClefbaseHosting = exports.EmailVerificationCard = exports.BucketReference = exports.StorageReference = exports.ClefbaseStorage = exports.Auth = exports.runTransaction = exports.Transaction = exports.WriteBatch = exports.Query = exports.DocumentReference = exports.CollectionGroup = exports.CollectionReference = exports.Database = exports.getFunctions = exports.getHosting = exports.getStorage = exports.getAuth = exports.getDatabase = exports.getApp = exports.initClefbase = exports.ClefbaseApp = void 0;
51
61
  // ─── App ──────────────────────────────────────────────────────────────────────
52
62
  var app_1 = require("./app");
53
63
  Object.defineProperty(exports, "ClefbaseApp", { enumerable: true, get: function () { return app_1.ClefbaseApp; } });
@@ -85,8 +95,19 @@ Object.defineProperty(exports, "ClefbaseHosting", { enumerable: true, get: funct
85
95
  Object.defineProperty(exports, "SiteReference", { enumerable: true, get: function () { return hosting_1.SiteReference; } });
86
96
  // ─── Functions ────────────────────────────────────────────────────────────────
87
97
  var functions_1 = require("./functions");
98
+ // Class
88
99
  Object.defineProperty(exports, "ClefbaseFunctions", { enumerable: true, get: function () { return functions_1.ClefbaseFunctions; } });
100
+ // Error
101
+ Object.defineProperty(exports, "FunctionsError", { enumerable: true, get: function () { return functions_1.FunctionsError; } });
102
+ // Top-level factory / convenience (mirrors the standalone SDK's API shape)
89
103
  Object.defineProperty(exports, "httpsCallable", { enumerable: true, get: function () { return functions_1.httpsCallable; } });
104
+ Object.defineProperty(exports, "callFunction", { enumerable: true, get: function () { return functions_1.callFunction; } });
105
+ Object.defineProperty(exports, "deployFunction", { enumerable: true, get: function () { return functions_1.deployFunction; } });
106
+ Object.defineProperty(exports, "deleteFunction", { enumerable: true, get: function () { return functions_1.deleteFunction; } });
107
+ Object.defineProperty(exports, "listFunctions", { enumerable: true, get: function () { return functions_1.listFunctions; } });
108
+ Object.defineProperty(exports, "getFunctionExecutions", { enumerable: true, get: function () { return functions_1.getFunctionExecutions; } });
109
+ Object.defineProperty(exports, "setAuthToken", { enumerable: true, get: function () { return functions_1.setAuthToken; } });
110
+ Object.defineProperty(exports, "deployFromFile", { enumerable: true, get: function () { return functions_1.deployFromFile; } });
90
111
  // ─── FieldValue ───────────────────────────────────────────────────────────────
91
112
  var field_value_1 = require("./field_value");
92
113
  Object.defineProperty(exports, "FieldValue", { enumerable: true, get: function () { return field_value_1.FieldValue; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;;;AAEH,iFAAiF;AACjF,6BASe;AARb,kGAAA,WAAW,OAAA;AACX,mGAAA,YAAY,OAAA;AACZ,6FAAA,MAAM,OAAA;AACN,kGAAA,WAAW,OAAA;AACX,8FAAA,OAAO,OAAA;AACP,iGAAA,UAAU,OAAA;AACV,iGAAA,UAAU,OAAA;AACV,mGAAA,YAAY,OAAA;AAGd,iFAAiF;AACjF,2BASc;AARZ,8FAAA,QAAQ,OAAA;AACR,yGAAA,mBAAmB,OAAA;AACnB,qGAAA,eAAe,OAAA;AACf,uGAAA,iBAAiB,OAAA;AACjB,2FAAA,KAAK,OAAA;AACL,gGAAA,UAAU,OAAA;AACV,iGAAA,WAAW,OAAA;AACX,oGAAA,cAAc,OAAA;AAGhB,iFAAiF;AACjF,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AAGb,iFAAiF;AACjF,qCAA+E;AAAtE,0GAAA,eAAe,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,0GAAA,eAAe,OAAA;AAM3D,iFAAiF;AACjF,uEAAsE;AAA7D,8HAAA,qBAAqB,OAAA;AAE9B,iFAAiF;AACjF,qCAA2D;AAAlD,0GAAA,eAAe,OAAA;AAAE,wGAAA,aAAa,OAAA;AAWvC,iFAAiF;AACjF,yCAA+D;AAAtD,8GAAA,iBAAiB,OAAA;AAAE,0GAAA,aAAa,OAAA;AAazC,iFAAiF;AACjF,6CAA+D;AAAtD,yGAAA,UAAU,OAAA;AAAE,iHAAA,kBAAkB,OAAA;AAiBvC,iCAAwC;AAA/B,sGAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;;;AAEH,iFAAiF;AACjF,6BASe;AARb,kGAAA,WAAW,OAAA;AACX,mGAAA,YAAY,OAAA;AACZ,6FAAA,MAAM,OAAA;AACN,kGAAA,WAAW,OAAA;AACX,8FAAA,OAAO,OAAA;AACP,iGAAA,UAAU,OAAA;AACV,iGAAA,UAAU,OAAA;AACV,mGAAA,YAAY,OAAA;AAGd,iFAAiF;AACjF,2BASc;AARZ,8FAAA,QAAQ,OAAA;AACR,yGAAA,mBAAmB,OAAA;AACnB,qGAAA,eAAe,OAAA;AACf,uGAAA,iBAAiB,OAAA;AACjB,2FAAA,KAAK,OAAA;AACL,gGAAA,UAAU,OAAA;AACV,iGAAA,WAAW,OAAA;AACX,oGAAA,cAAc,OAAA;AAGhB,iFAAiF;AACjF,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AAGb,iFAAiF;AACjF,qCAA+E;AAAtE,0GAAA,eAAe,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,0GAAA,eAAe,OAAA;AAM3D,iFAAiF;AACjF,uEAAsE;AAA7D,8HAAA,qBAAqB,OAAA;AAE9B,iFAAiF;AACjF,qCAA2D;AAAlD,0GAAA,eAAe,OAAA;AAAE,wGAAA,aAAa,OAAA;AAWvC,iFAAiF;AACjF,yCAcqB;AAbnB,QAAQ;AACR,8GAAA,iBAAiB,OAAA;AACjB,QAAQ;AACR,2GAAA,cAAc,OAAA;AACd,2EAA2E;AAC3E,0GAAA,aAAa,OAAA;AACb,yGAAA,YAAY,OAAA;AACZ,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,0GAAA,aAAa,OAAA;AACb,kHAAA,qBAAqB,OAAA;AACrB,yGAAA,YAAY,OAAA;AACZ,2GAAA,cAAc,OAAA;AAehB,iFAAiF;AACjF,6CAA+D;AAAtD,yGAAA,UAAU,OAAA;AAAE,iHAAA,kBAAkB,OAAA;AAiBvC,iCAAwC;AAA/B,sGAAA,aAAa,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clefbase",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Firebase-style SDK and CLI for Clefbase — database, auth, storage, hosting, and functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",