@ketrics/ketrics-cli 0.3.0 → 0.5.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.
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAgEnC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAyEnC"}
package/dist/src/cli.js CHANGED
@@ -12,6 +12,7 @@ const build_1 = require("./commands/build");
12
12
  const deploy_1 = require("./commands/deploy");
13
13
  const validate_1 = require("./commands/validate");
14
14
  const run_1 = require("./commands/run");
15
+ const update_1 = require("./commands/update");
15
16
  const version_1 = require("./version");
16
17
  /**
17
18
  * Create and configure CLI program
@@ -72,6 +73,14 @@ function createCLI() {
72
73
  verbose: options.verbose,
73
74
  });
74
75
  });
76
+ // Update command
77
+ program
78
+ .command("update")
79
+ .description("Update Ketrics CLI to the latest version")
80
+ .option("--check", "Show the currently installed version without updating")
81
+ .action(async (options) => {
82
+ await (0, update_1.updateCommand)({ check: options.check });
83
+ });
75
84
  return program;
76
85
  }
77
86
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAaH,8BAgEC;AA3ED,yCAAoC;AACpC,8CAAkD;AAClD,4CAAgD;AAChD,8CAAkD;AAClD,kDAAsD;AACtD,wCAA4C;AAC5C,uCAAoC;AAEpC;;GAEG;AACH,SAAgB,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,iBAAO,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAEzD,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,oDAAoD,CAAC;SACrF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,IAAA,sBAAa,EAAC,OAAO,EAAE;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,gBAAgB;IAChB,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAA,oBAAY,GAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,WAAW,EAAE,yDAAyD,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,sBAAa,EAAC;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,mBAAmB;IACnB,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEL,cAAc;IACd,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;SACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,gBAAU,EAAC,QAAQ,EAAE;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAcH,8BAyEC;AArFD,yCAAoC;AACpC,8CAAkD;AAClD,4CAAgD;AAChD,8CAAkD;AAClD,kDAAsD;AACtD,wCAA4C;AAC5C,8CAAkD;AAClD,uCAAoC;AAEpC;;GAEG;AACH,SAAgB,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,iBAAO,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAEzD,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,oDAAoD,CAAC;SACrF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,IAAA,sBAAa,EAAC,OAAO,EAAE;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,gBAAgB;IAChB,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAA,oBAAY,GAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,WAAW,EAAE,yDAAyD,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,sBAAa,EAAC;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,mBAAmB;IACnB,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEL,cAAc;IACd,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;SACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,gBAAU,EAAC,QAAQ,EAAE;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,SAAS,EAAE,uDAAuD,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,sBAAa,EAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Update Command
3
+ *
4
+ * Updates the Ketrics CLI to the latest version from npm.
5
+ */
6
+ export interface UpdateOptions {
7
+ check?: boolean;
8
+ }
9
+ /**
10
+ * Execute update command
11
+ */
12
+ export declare function updateCommand(options?: UpdateOptions): Promise<void>;
13
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoBH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuE9E"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * Update Command
4
+ *
5
+ * Updates the Ketrics CLI to the latest version from npm.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.updateCommand = updateCommand;
9
+ const child_process_1 = require("child_process");
10
+ const logger_1 = require("../utils/logger");
11
+ const spinner_1 = require("../utils/spinner");
12
+ const version_1 = require("../version");
13
+ const PACKAGE_NAME = '@ketrics/ketrics-cli';
14
+ /**
15
+ * Fetch the latest version from the npm registry
16
+ */
17
+ async function getLatestVersion() {
18
+ const output = (0, child_process_1.execSync)(`npm view ${PACKAGE_NAME} version`, {
19
+ encoding: 'utf-8',
20
+ stdio: ['pipe', 'pipe', 'pipe'],
21
+ });
22
+ return output.trim();
23
+ }
24
+ /**
25
+ * Execute update command
26
+ */
27
+ async function updateCommand(options = {}) {
28
+ const currentVersion = version_1.VERSION;
29
+ logger_1.logger.info(`Current version: ${currentVersion}`);
30
+ if (options.check) {
31
+ return;
32
+ }
33
+ logger_1.logger.newline();
34
+ // Check for latest version
35
+ let latestVersion;
36
+ try {
37
+ latestVersion = await (0, spinner_1.withSpinner)('Checking for updates...', () => getLatestVersion(), 'Checked for updates');
38
+ }
39
+ catch {
40
+ logger_1.logger.error('Failed to check for updates. Ensure you have internet access and npm is installed.');
41
+ process.exit(1);
42
+ }
43
+ logger_1.logger.keyValue('Latest version', latestVersion);
44
+ logger_1.logger.newline();
45
+ // Compare versions
46
+ if (currentVersion === latestVersion) {
47
+ logger_1.logger.success('You are already on the latest version!');
48
+ return;
49
+ }
50
+ // Install latest version
51
+ logger_1.logger.info(`Updating ${currentVersion} → ${latestVersion}...`);
52
+ logger_1.logger.newline();
53
+ try {
54
+ await (0, spinner_1.withSpinner)('Installing latest version...', async () => {
55
+ (0, child_process_1.execSync)(`npm install -g ${PACKAGE_NAME}@latest`, {
56
+ encoding: 'utf-8',
57
+ stdio: ['pipe', 'pipe', 'pipe'],
58
+ });
59
+ }, 'Installed latest version');
60
+ }
61
+ catch (error) {
62
+ const message = error instanceof Error ? error.message : String(error);
63
+ if (message.includes('EACCES') || message.includes('permission')) {
64
+ logger_1.logger.error('Permission denied. Try running with sudo:');
65
+ logger_1.logger.newline();
66
+ logger_1.logger.indent(`sudo npm install -g ${PACKAGE_NAME}@latest`, 1);
67
+ }
68
+ else {
69
+ logger_1.logger.error('Failed to update. You can try manually:');
70
+ logger_1.logger.newline();
71
+ logger_1.logger.indent(`npm install -g ${PACKAGE_NAME}@latest`, 1);
72
+ }
73
+ process.exit(1);
74
+ }
75
+ logger_1.logger.newline();
76
+ logger_1.logger.success(`Successfully updated to v${latestVersion}!`);
77
+ }
78
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/update.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA2BH,sCAuEC;AAhGD,iDAAyC;AACzC,4CAAyC;AACzC,8CAA+C;AAC/C,wCAAqC;AAErC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAE5C;;GAEG;AACH,KAAK,UAAU,gBAAgB;IAC7B,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,YAAY,YAAY,UAAU,EAAE;QAC1D,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAMD;;GAEG;AACI,KAAK,UAAU,aAAa,CAAC,UAAyB,EAAE;IAC7D,MAAM,cAAc,GAAG,iBAAO,CAAC;IAE/B,eAAM,CAAC,IAAI,CAAC,oBAAoB,cAAc,EAAE,CAAC,CAAC;IAElD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IAED,eAAM,CAAC,OAAO,EAAE,CAAC;IAEjB,2BAA2B;IAC3B,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,MAAM,IAAA,qBAAW,EAC/B,yBAAyB,EACzB,GAAG,EAAE,CAAC,gBAAgB,EAAE,EACxB,qBAAqB,CACtB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,eAAM,CAAC,KAAK,CACV,oFAAoF,CACrF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,eAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACjD,eAAM,CAAC,OAAO,EAAE,CAAC;IAEjB,mBAAmB;IACnB,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;QACrC,eAAM,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,yBAAyB;IACzB,eAAM,CAAC,IAAI,CAAC,YAAY,cAAc,MAAM,aAAa,KAAK,CAAC,CAAC;IAChE,eAAM,CAAC,OAAO,EAAE,CAAC;IAEjB,IAAI,CAAC;QACH,MAAM,IAAA,qBAAW,EACf,8BAA8B,EAC9B,KAAK,IAAI,EAAE;YACT,IAAA,wBAAQ,EAAC,kBAAkB,YAAY,SAAS,EAAE;gBAChD,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAChC,CAAC,CAAC;QACL,CAAC,EACD,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEzD,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACjE,eAAM,CAAC,KAAK,CACV,2CAA2C,CAC5C,CAAC;YACF,eAAM,CAAC,OAAO,EAAE,CAAC;YACjB,eAAM,CAAC,MAAM,CAAC,uBAAuB,YAAY,SAAS,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,eAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACxD,eAAM,CAAC,OAAO,EAAE,CAAC;YACjB,eAAM,CAAC,MAAM,CAAC,kBAAkB,YAAY,SAAS,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,eAAM,CAAC,OAAO,EAAE,CAAC;IACjB,eAAM,CAAC,OAAO,CAAC,4BAA4B,aAAa,GAAG,CAAC,CAAC;AAC/D,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.3.0";
1
+ export declare const VERSION = "0.5.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Auto-generated - do not edit
5
- exports.VERSION = "0.3.0";
5
+ exports.VERSION = "0.5.0";
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ketrics/ketrics-cli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "CLI tool for deploying applications to Ketrics platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Mock Backend Handlers
3
+ *
4
+ * Define mock responses for your backend functions here.
5
+ * These are used automatically when running `npm run dev` (local development)
6
+ * and are completely excluded from production builds.
7
+ *
8
+ * Each key corresponds to a backend function name exported from backend/src/index.ts.
9
+ * The handler receives the same payload your backend function would receive
10
+ * and should return the same response shape.
11
+ *
12
+ * Usage:
13
+ * 1. Add a handler for each backend function you want to mock
14
+ * 2. Run `npm run dev` - the frontend will use these handlers instead of the runtime API
15
+ * 3. Run `npm run build` / `ketrics deploy` - mock code is stripped out entirely
16
+ */
17
+
18
+ type MockHandler = (payload?: unknown) => unknown | Promise<unknown>;
19
+
20
+ const handlers: Record<string, MockHandler> = {
21
+ echo: (payload) => ({
22
+ payload,
23
+ context: {
24
+ tenant: { id: "mock-tenant-id", code: "mock-tenant", name: "Mock Tenant" },
25
+ application: { id: "mock-app-id", code: "mock-app", name: "Mock App", version: "1.0.0", deploymentId: "mock-deploy" },
26
+ requestor: { type: "user", userId: "mock-user-id", email: "dev@localhost", name: "Local Developer", applicationPermissions: [] },
27
+ runtime: { nodeVersion: "18.x", runtime: "mock", region: "local" },
28
+ environment: {},
29
+ },
30
+ }),
31
+
32
+ info: () => ({
33
+ tenant: { id: "mock-tenant-id", code: "mock-tenant", name: "Mock Tenant" },
34
+ application: { id: "mock-app-id", code: "mock-app", name: "Mock App", version: "1.0.0" },
35
+ runtime: { nodeVersion: "18.x", runtime: "mock", region: "local" },
36
+ }),
37
+
38
+ fetchExternalApi: () => ({
39
+ data: { id: 1, title: "Mock Post", body: "This is a mock response from the local dev server." },
40
+ fetchedAt: new Date().toISOString(),
41
+ }),
42
+
43
+ // --- Volumes ---
44
+
45
+ saveFile: () => ({
46
+ jsonFile: { key: "output/data.json", etag: "mock-etag-1", size: 128 },
47
+ textFile: { key: "output/hello.txt", etag: "mock-etag-2", size: 19 },
48
+ }),
49
+
50
+ readFile: () => ({
51
+ contentType: "application/json",
52
+ contentLength: 128,
53
+ lastModified: new Date().toISOString(),
54
+ parsed: { generatedBy: "mock-app", generatedAt: new Date().toISOString(), tenant: "mock-tenant" },
55
+ }),
56
+
57
+ listFiles: (payload: unknown) => {
58
+ const { prefix } = (payload as { prefix?: string }) || {};
59
+ return {
60
+ files: [
61
+ { key: `${prefix || "output/"}data.json`, size: 128, lastModified: new Date().toISOString(), contentType: "application/json" },
62
+ { key: `${prefix || "output/"}hello.txt`, size: 19, lastModified: new Date().toISOString(), contentType: "text/plain" },
63
+ ],
64
+ count: 2,
65
+ isTruncated: false,
66
+ };
67
+ },
68
+
69
+ generateDownloadUrl: () => ({
70
+ url: "https://example.com/mock-download-url",
71
+ expiresAt: new Date(Date.now() + 3600_000).toISOString(),
72
+ }),
73
+
74
+ copyFile: () => ({
75
+ sourceKey: "output/data.json",
76
+ destinationKey: "backup/data-backup.json",
77
+ etag: "mock-etag-copy",
78
+ }),
79
+
80
+ // --- Database ---
81
+
82
+ queryUsers: (payload: unknown) => {
83
+ const { limit } = (payload as { limit?: number }) || {};
84
+ const users = [
85
+ { id: 1, name: "Alice Johnson", email: "alice@example.com" },
86
+ { id: 2, name: "Bob Smith", email: "bob@example.com" },
87
+ { id: 3, name: "Carol Davis", email: "carol@example.com" },
88
+ { id: 4, name: "Dan Wilson", email: "dan@example.com" },
89
+ { id: 5, name: "Eve Martinez", email: "eve@example.com" },
90
+ ];
91
+ const sliced = users.slice(0, limit || 10);
92
+ return { users: sliced, rowCount: sliced.length };
93
+ },
94
+
95
+ insertRecord: (payload: unknown) => {
96
+ const { name, email } = (payload as { name?: string; email?: string }) || {};
97
+ if (!name || !email) throw new Error("name and email are required");
98
+ return { affectedRows: 1, insertId: Math.floor(Math.random() * 1000) + 100 };
99
+ },
100
+
101
+ transferFunds: (payload: unknown) => {
102
+ const { amount } = (payload as { amount?: number }) || {};
103
+ if (!amount || amount <= 0) throw new Error("Amount must be positive");
104
+ return { transferred: amount };
105
+ },
106
+
107
+ // --- Documents ---
108
+
109
+ createSimplePdf: () => ({
110
+ downloadUrl: "https://example.com/mock-simple.pdf",
111
+ message: "[Mock] PDF would be generated by the backend",
112
+ }),
113
+
114
+ createInvoicePdf: () => ({
115
+ downloadUrl: "https://example.com/mock-invoice.pdf",
116
+ message: "[Mock] Invoice PDF would be generated by the backend",
117
+ }),
118
+
119
+ createSpreadsheet: () => ({
120
+ downloadUrl: "https://example.com/mock-spreadsheet.xlsx",
121
+ message: "[Mock] Spreadsheet would be generated by the backend",
122
+ }),
123
+
124
+ exportDataToExcel: () => ({
125
+ downloadUrl: "https://example.com/mock-export.xlsx",
126
+ message: "[Mock] Excel export would be generated by the backend",
127
+ }),
128
+
129
+ // --- Messaging & Jobs ---
130
+
131
+ sendNotification: (payload: unknown) => {
132
+ const { subject, body } = (payload as { subject?: string; body?: string }) || {};
133
+ return { sent: true, subject, body, message: "[Mock] Notification would be sent by the backend" };
134
+ },
135
+
136
+ scheduleBackgroundJob: () => ({
137
+ jobId: `mock-job-${Date.now()}`,
138
+ status: "scheduled",
139
+ message: "[Mock] Job would be scheduled by the backend",
140
+ }),
141
+
142
+ getSecret: () => ({
143
+ value: "mock-secret-value",
144
+ message: "[Mock] Secret would be retrieved from the backend",
145
+ }),
146
+ };
147
+
148
+ export { handlers };
149
+ export type { MockHandler };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Mock API Client
3
+ *
4
+ * Replaces the real API client during local development (`npm run dev`).
5
+ * Routes function calls to the mock handlers defined in ./handlers.ts
6
+ * instead of making HTTP requests to the Ketrics Runtime API.
7
+ *
8
+ * This file is tree-shaken out of production builds by Vite.
9
+ */
10
+
11
+ import { handlers } from "./handlers";
12
+
13
+ class MockAPIClient {
14
+ async run(fnName: string, payload?: unknown) {
15
+ const handler = handlers[fnName];
16
+
17
+ if (!handler) {
18
+ throw new Error(
19
+ `[Mock] No handler defined for "${fnName}". ` +
20
+ `Add it to src/mocks/handlers.ts to use it in local development.`
21
+ );
22
+ }
23
+
24
+ // Simulate network latency
25
+ await new Promise((resolve) => setTimeout(resolve, 200));
26
+
27
+ try {
28
+ const result = await handler(payload);
29
+ console.log(`[Mock] ${fnName}`, { payload, result });
30
+ return { success: true, result };
31
+ } catch (err) {
32
+ const message = err instanceof Error ? err.message : String(err);
33
+ console.error(`[Mock] ${fnName} error:`, message);
34
+ throw new Error(message);
35
+ }
36
+ }
37
+ }
38
+
39
+ export function createMockClient() {
40
+ console.log(
41
+ "%c[Ketrics] Running with mock backend — edit src/mocks/handlers.ts to customize responses",
42
+ "color: #f59e0b; font-weight: bold;"
43
+ );
44
+ return new MockAPIClient();
45
+ }
@@ -1,19 +1,16 @@
1
1
  import { createAuthManager } from "@ketrics/sdk-frontend";
2
2
 
3
- const auth = createAuthManager();
4
-
5
- // Initialize auto-refresh
6
- auth.initAutoRefresh({
7
- refreshBuffer: 60,
8
- onTokenUpdated: () => {
9
- // Token is refreshed automatically and retrieved via getAccessToken()
10
- },
11
- });
3
+ interface APIClientInterface {
4
+ run(fnName: string, payload?: unknown): Promise<unknown>;
5
+ }
12
6
 
13
- class APIClient {
7
+ // ---------------------------------------------------------------------------
8
+ // Real API Client — used when deployed (production builds)
9
+ // ---------------------------------------------------------------------------
10
+ class APIClient implements APIClientInterface {
14
11
  private auth;
15
12
 
16
- constructor(authManager: typeof auth) {
13
+ constructor(authManager: ReturnType<typeof createAuthManager>) {
17
14
  this.auth = authManager;
18
15
  }
19
16
 
@@ -50,6 +47,27 @@ class APIClient {
50
47
  }
51
48
  }
52
49
 
53
- const apiClient = new APIClient(auth);
50
+ // ---------------------------------------------------------------------------
51
+ // Client initialization — mock in dev, real in production
52
+ // ---------------------------------------------------------------------------
53
+ async function createClient(): Promise<APIClientInterface> {
54
+ if (import.meta.env.DEV) {
55
+ // Dynamic import keeps mock code in a separate chunk that Vite
56
+ // completely excludes from production builds.
57
+ const { createMockClient } = await import("../mocks/mock-client");
58
+ return createMockClient();
59
+ }
60
+
61
+ const auth = createAuthManager();
62
+ auth.initAutoRefresh({
63
+ refreshBuffer: 60,
64
+ onTokenUpdated: () => {
65
+ // Token is refreshed automatically and retrieved via getAccessToken()
66
+ },
67
+ });
68
+ return new APIClient(auth);
69
+ }
70
+
71
+ const apiClient = await createClient();
54
72
 
55
73
  export { apiClient };
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />