@channel.io/app-sdk-server 0.1.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.
Files changed (137) hide show
  1. package/dist/__tests__/decorators.test.d.ts +2 -0
  2. package/dist/__tests__/decorators.test.d.ts.map +1 -0
  3. package/dist/__tests__/decorators.test.js +259 -0
  4. package/dist/__tests__/decorators.test.js.map +1 -0
  5. package/dist/__tests__/testing-utils.test.d.ts +2 -0
  6. package/dist/__tests__/testing-utils.test.d.ts.map +1 -0
  7. package/dist/__tests__/testing-utils.test.js +118 -0
  8. package/dist/__tests__/testing-utils.test.js.map +1 -0
  9. package/dist/appstore/client.d.ts +70 -0
  10. package/dist/appstore/client.d.ts.map +1 -0
  11. package/dist/appstore/client.js +141 -0
  12. package/dist/appstore/client.js.map +1 -0
  13. package/dist/appstore/index.d.ts +3 -0
  14. package/dist/appstore/index.d.ts.map +1 -0
  15. package/dist/appstore/index.js +3 -0
  16. package/dist/appstore/index.js.map +1 -0
  17. package/dist/appstore/types.d.ts +87 -0
  18. package/dist/appstore/types.d.ts.map +1 -0
  19. package/dist/appstore/types.js +5 -0
  20. package/dist/appstore/types.js.map +1 -0
  21. package/dist/decorators/extension.decorator.d.ts +33 -0
  22. package/dist/decorators/extension.decorator.d.ts.map +1 -0
  23. package/dist/decorators/extension.decorator.js +36 -0
  24. package/dist/decorators/extension.decorator.js.map +1 -0
  25. package/dist/decorators/function.decorator.d.ts +34 -0
  26. package/dist/decorators/function.decorator.d.ts.map +1 -0
  27. package/dist/decorators/function.decorator.js +45 -0
  28. package/dist/decorators/function.decorator.js.map +1 -0
  29. package/dist/decorators/index.d.ts +5 -0
  30. package/dist/decorators/index.d.ts.map +1 -0
  31. package/dist/decorators/index.js +9 -0
  32. package/dist/decorators/index.js.map +1 -0
  33. package/dist/decorators/param.decorator.d.ts +49 -0
  34. package/dist/decorators/param.decorator.d.ts.map +1 -0
  35. package/dist/decorators/param.decorator.js +62 -0
  36. package/dist/decorators/param.decorator.js.map +1 -0
  37. package/dist/decorators/schema.decorator.d.ts +48 -0
  38. package/dist/decorators/schema.decorator.d.ts.map +1 -0
  39. package/dist/decorators/schema.decorator.js +59 -0
  40. package/dist/decorators/schema.decorator.js.map +1 -0
  41. package/dist/discovery/extension-discovery.service.d.ts +45 -0
  42. package/dist/discovery/extension-discovery.service.d.ts.map +1 -0
  43. package/dist/discovery/extension-discovery.service.js +192 -0
  44. package/dist/discovery/extension-discovery.service.js.map +1 -0
  45. package/dist/discovery/index.d.ts +3 -0
  46. package/dist/discovery/index.d.ts.map +1 -0
  47. package/dist/discovery/index.js +2 -0
  48. package/dist/discovery/index.js.map +1 -0
  49. package/dist/discovery/metadata.interface.d.ts +42 -0
  50. package/dist/discovery/metadata.interface.d.ts.map +1 -0
  51. package/dist/discovery/metadata.interface.js +2 -0
  52. package/dist/discovery/metadata.interface.js.map +1 -0
  53. package/dist/guards/index.d.ts +3 -0
  54. package/dist/guards/index.d.ts.map +1 -0
  55. package/dist/guards/index.js +3 -0
  56. package/dist/guards/index.js.map +1 -0
  57. package/dist/guards/signature.guard.d.ts +65 -0
  58. package/dist/guards/signature.guard.d.ts.map +1 -0
  59. package/dist/guards/signature.guard.js +156 -0
  60. package/dist/guards/signature.guard.js.map +1 -0
  61. package/dist/guards/signature.middleware.d.ts +76 -0
  62. package/dist/guards/signature.middleware.d.ts.map +1 -0
  63. package/dist/guards/signature.middleware.js +110 -0
  64. package/dist/guards/signature.middleware.js.map +1 -0
  65. package/dist/index.d.ts +11 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +21 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/native/client.d.ts +105 -0
  70. package/dist/native/client.d.ts.map +1 -0
  71. package/dist/native/client.js +210 -0
  72. package/dist/native/client.js.map +1 -0
  73. package/dist/native/index.d.ts +3 -0
  74. package/dist/native/index.d.ts.map +1 -0
  75. package/dist/native/index.js +3 -0
  76. package/dist/native/index.js.map +1 -0
  77. package/dist/native/types.d.ts +198 -0
  78. package/dist/native/types.d.ts.map +1 -0
  79. package/dist/native/types.js +8 -0
  80. package/dist/native/types.js.map +1 -0
  81. package/dist/nestjs/channel-app.controller.d.ts +22 -0
  82. package/dist/nestjs/channel-app.controller.d.ts.map +1 -0
  83. package/dist/nestjs/channel-app.controller.js +87 -0
  84. package/dist/nestjs/channel-app.controller.js.map +1 -0
  85. package/dist/nestjs/channel-app.module.d.ts +47 -0
  86. package/dist/nestjs/channel-app.module.d.ts.map +1 -0
  87. package/dist/nestjs/channel-app.module.js +93 -0
  88. package/dist/nestjs/channel-app.module.js.map +1 -0
  89. package/dist/nestjs/channel-app.service.d.ts +44 -0
  90. package/dist/nestjs/channel-app.service.d.ts.map +1 -0
  91. package/dist/nestjs/channel-app.service.js +190 -0
  92. package/dist/nestjs/channel-app.service.js.map +1 -0
  93. package/dist/nestjs/index.d.ts +5 -0
  94. package/dist/nestjs/index.d.ts.map +1 -0
  95. package/dist/nestjs/index.js +5 -0
  96. package/dist/nestjs/index.js.map +1 -0
  97. package/dist/nestjs/types.d.ts +70 -0
  98. package/dist/nestjs/types.d.ts.map +1 -0
  99. package/dist/nestjs/types.js +5 -0
  100. package/dist/nestjs/types.js.map +1 -0
  101. package/dist/simple/channel-app.d.ts +80 -0
  102. package/dist/simple/channel-app.d.ts.map +1 -0
  103. package/dist/simple/channel-app.js +253 -0
  104. package/dist/simple/channel-app.js.map +1 -0
  105. package/dist/simple/index.d.ts +2 -0
  106. package/dist/simple/index.d.ts.map +1 -0
  107. package/dist/simple/index.js +2 -0
  108. package/dist/simple/index.js.map +1 -0
  109. package/dist/testing/index.d.ts +9 -0
  110. package/dist/testing/index.d.ts.map +1 -0
  111. package/dist/testing/index.js +9 -0
  112. package/dist/testing/index.js.map +1 -0
  113. package/dist/testing/mock-context.d.ts +32 -0
  114. package/dist/testing/mock-context.d.ts.map +1 -0
  115. package/dist/testing/mock-context.js +33 -0
  116. package/dist/testing/mock-context.js.map +1 -0
  117. package/dist/testing/test-extension.d.ts +60 -0
  118. package/dist/testing/test-extension.d.ts.map +1 -0
  119. package/dist/testing/test-extension.js +113 -0
  120. package/dist/testing/test-extension.js.map +1 -0
  121. package/dist/token/cache.d.ts +31 -0
  122. package/dist/token/cache.d.ts.map +1 -0
  123. package/dist/token/cache.js +69 -0
  124. package/dist/token/cache.js.map +1 -0
  125. package/dist/token/index.d.ts +4 -0
  126. package/dist/token/index.d.ts.map +1 -0
  127. package/dist/token/index.js +4 -0
  128. package/dist/token/index.js.map +1 -0
  129. package/dist/token/manager.d.ts +111 -0
  130. package/dist/token/manager.d.ts.map +1 -0
  131. package/dist/token/manager.js +246 -0
  132. package/dist/token/manager.js.map +1 -0
  133. package/dist/token/types.d.ts +85 -0
  134. package/dist/token/types.d.ts.map +1 -0
  135. package/dist/token/types.js +5 -0
  136. package/dist/token/types.js.map +1 -0
  137. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Testing utilities for Channel.io App SDK
3
+ *
4
+ * This module provides utilities for testing extensions and functions
5
+ * without running the full NestJS application.
6
+ */
7
+ export { createMockContext, type MockContextOptions } from "./mock-context.js";
8
+ export { createTestExtension, type TestExtensionResult } from "./test-extension.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Testing utilities for Channel.io App SDK
3
+ *
4
+ * This module provides utilities for testing extensions and functions
5
+ * without running the full NestJS application.
6
+ */
7
+ export { createMockContext } from "./mock-context.js";
8
+ export { createTestExtension } from "./test-extension.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAA2B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAA4B,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { FunctionContext } from "../native/types.js";
2
+ /**
3
+ * Options for creating a mock context
4
+ */
5
+ export interface MockContextOptions {
6
+ /** Channel ID (default: "test-channel-id") */
7
+ channelId?: string;
8
+ /** Caller type (default: "manager") */
9
+ callerType?: "user" | "manager" | "system";
10
+ /** Caller ID (default: "test-caller-id") */
11
+ callerId?: string;
12
+ /** Auth token (optional) */
13
+ authToken?: string;
14
+ /** API credentials (optional) */
15
+ apiCredentials?: Record<string, string>;
16
+ }
17
+ /**
18
+ * Create a mock function context for testing
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const ctx = createMockContext({
23
+ * channelId: "my-channel",
24
+ * callerType: "user",
25
+ * callerId: "user-123",
26
+ * });
27
+ *
28
+ * const result = await extension.myFunction(ctx, params);
29
+ * ```
30
+ */
31
+ export declare function createMockContext(options?: MockContextOptions): FunctionContext;
32
+ //# sourceMappingURL=mock-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-context.d.ts","sourceRoot":"","sources":["../../src/testing/mock-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3C,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,eAAe,CAoBnF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Create a mock function context for testing
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const ctx = createMockContext({
7
+ * channelId: "my-channel",
8
+ * callerType: "user",
9
+ * callerId: "user-123",
10
+ * });
11
+ *
12
+ * const result = await extension.myFunction(ctx, params);
13
+ * ```
14
+ */
15
+ export function createMockContext(options = {}) {
16
+ const ctx = {
17
+ channel: {
18
+ id: options.channelId ?? "test-channel-id",
19
+ },
20
+ caller: {
21
+ type: options.callerType ?? "manager",
22
+ id: options.callerId ?? "test-caller-id",
23
+ },
24
+ };
25
+ if (options.authToken !== undefined) {
26
+ ctx.authToken = options.authToken;
27
+ }
28
+ if (options.apiCredentials !== undefined) {
29
+ ctx.apiCredentials = options.apiCredentials;
30
+ }
31
+ return ctx;
32
+ }
33
+ //# sourceMappingURL=mock-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-context.js","sourceRoot":"","sources":["../../src/testing/mock-context.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE;IAChE,MAAM,GAAG,GAAoB;QAC3B,OAAO,EAAE;YACP,EAAE,EAAE,OAAO,CAAC,SAAS,IAAI,iBAAiB;SAC3C;QACD,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;YACrC,EAAE,EAAE,OAAO,CAAC,QAAQ,IAAI,gBAAgB;SACzC;KACF,CAAC;IAEF,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACzC,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,60 @@
1
+ import "reflect-metadata";
2
+ import type { Type } from "@nestjs/common";
3
+ import { type MockContextOptions } from "./mock-context.js";
4
+ /**
5
+ * Result of creating a test extension
6
+ */
7
+ export interface TestExtensionResult<T> {
8
+ /** The extension instance */
9
+ instance: T;
10
+ /** Extension name from metadata */
11
+ extensionName: string;
12
+ /** List of function names */
13
+ functionNames: string[];
14
+ /**
15
+ * Call a function on the extension with automatic context creation
16
+ *
17
+ * @param functionName - The function name (without extension prefix)
18
+ * @param params - The input parameters
19
+ * @param contextOptions - Optional mock context options
20
+ */
21
+ callFunction: <TParams = unknown, TResult = unknown>(functionName: string, params?: TParams, contextOptions?: MockContextOptions) => Promise<TResult>;
22
+ }
23
+ /**
24
+ * Create a test extension instance with helper methods
25
+ *
26
+ * This utility allows testing extension classes without running NestJS.
27
+ * It provides automatic context creation and function discovery.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import { createTestExtension, createMockContext } from '@channel.io/app-sdk-server/testing';
32
+ *
33
+ * describe('CalendarExtension', () => {
34
+ * it('should list event types', async () => {
35
+ * const { callFunction } = createTestExtension(CalendarExtension);
36
+ *
37
+ * const result = await callFunction('listEventTypes', {});
38
+ *
39
+ * expect(result.eventTypes).toHaveLength(3);
40
+ * });
41
+ *
42
+ * it('should get availability with custom context', async () => {
43
+ * const { callFunction } = createTestExtension(CalendarExtension);
44
+ *
45
+ * const result = await callFunction(
46
+ * 'getAvailability',
47
+ * { eventTypeId: '1', startDate: '2024-01-01', endDate: '2024-01-02' },
48
+ * { channelId: 'custom-channel' }
49
+ * );
50
+ *
51
+ * expect(result.slots).toBeDefined();
52
+ * });
53
+ * });
54
+ * ```
55
+ *
56
+ * @param ExtensionClass - The extension class decorated with @Extension
57
+ * @param dependencies - Optional dependencies to inject into the constructor
58
+ */
59
+ export declare function createTestExtension<T>(ExtensionClass: Type<T>, ...dependencies: unknown[]): TestExtensionResult<T>;
60
+ //# sourceMappingURL=test-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-extension.d.ts","sourceRoot":"","sources":["../../src/testing/test-extension.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAY3C,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,6BAA6B;IAC7B,QAAQ,EAAE,CAAC,CAAC;IACZ,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACjD,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,OAAO,EAChB,cAAc,CAAC,EAAE,kBAAkB,KAChC,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EACvB,GAAG,YAAY,EAAE,OAAO,EAAE,GACzB,mBAAmB,CAAC,CAAC,CAAC,CA8GxB"}
@@ -0,0 +1,113 @@
1
+ import "reflect-metadata";
2
+ import { EXTENSION_METADATA, FUNCTION_METADATA, FUNCTIONS_METADATA, PARAM_METADATA, FunctionParamType, INPUT_SCHEMA_METADATA, OUTPUT_SCHEMA_METADATA, } from "../decorators/index.js";
3
+ import { createMockContext } from "./mock-context.js";
4
+ /**
5
+ * Create a test extension instance with helper methods
6
+ *
7
+ * This utility allows testing extension classes without running NestJS.
8
+ * It provides automatic context creation and function discovery.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createTestExtension, createMockContext } from '@channel.io/app-sdk-server/testing';
13
+ *
14
+ * describe('CalendarExtension', () => {
15
+ * it('should list event types', async () => {
16
+ * const { callFunction } = createTestExtension(CalendarExtension);
17
+ *
18
+ * const result = await callFunction('listEventTypes', {});
19
+ *
20
+ * expect(result.eventTypes).toHaveLength(3);
21
+ * });
22
+ *
23
+ * it('should get availability with custom context', async () => {
24
+ * const { callFunction } = createTestExtension(CalendarExtension);
25
+ *
26
+ * const result = await callFunction(
27
+ * 'getAvailability',
28
+ * { eventTypeId: '1', startDate: '2024-01-01', endDate: '2024-01-02' },
29
+ * { channelId: 'custom-channel' }
30
+ * );
31
+ *
32
+ * expect(result.slots).toBeDefined();
33
+ * });
34
+ * });
35
+ * ```
36
+ *
37
+ * @param ExtensionClass - The extension class decorated with @Extension
38
+ * @param dependencies - Optional dependencies to inject into the constructor
39
+ */
40
+ export function createTestExtension(ExtensionClass, ...dependencies) {
41
+ // Get extension metadata
42
+ const extensionMeta = Reflect.getMetadata(EXTENSION_METADATA, ExtensionClass);
43
+ if (!extensionMeta) {
44
+ throw new Error(`Class ${ExtensionClass.name} is not decorated with @Extension`);
45
+ }
46
+ // Create instance with dependencies
47
+ const instance = new ExtensionClass(...dependencies);
48
+ // Discover functions
49
+ const functionKeys = Reflect.getMetadata(FUNCTIONS_METADATA, ExtensionClass) ?? [];
50
+ const functionNames = functionKeys.map((key) => {
51
+ const funcMeta = Reflect.getMetadata(FUNCTION_METADATA, ExtensionClass, key);
52
+ return funcMeta?.name ?? String(key);
53
+ });
54
+ // Create function caller
55
+ const callFunction = async (functionName, params, contextOptions) => {
56
+ // Find the method by function name
57
+ const methodKey = functionKeys.find((key) => {
58
+ const funcMeta = Reflect.getMetadata(FUNCTION_METADATA, ExtensionClass, key);
59
+ return funcMeta?.name === functionName || String(key) === functionName;
60
+ });
61
+ if (!methodKey) {
62
+ throw new Error(`Function "${functionName}" not found on ${ExtensionClass.name}. ` +
63
+ `Available functions: ${functionNames.join(", ")}`);
64
+ }
65
+ // Get parameter metadata
66
+ const paramMeta = Reflect.getMetadata(PARAM_METADATA, ExtensionClass, methodKey) ?? [];
67
+ // Get input schema for validation
68
+ const inputSchema = Reflect.getMetadata(INPUT_SCHEMA_METADATA, ExtensionClass, methodKey);
69
+ // Validate input if schema exists
70
+ let validatedParams = params;
71
+ if (inputSchema && params !== undefined) {
72
+ validatedParams = inputSchema.parse(params);
73
+ }
74
+ // Create context
75
+ const ctx = createMockContext(contextOptions);
76
+ // Build arguments based on parameter decorators
77
+ const args = [];
78
+ const sortedParams = [...paramMeta].sort((a, b) => a.index - b.index);
79
+ for (const param of sortedParams) {
80
+ switch (param.type) {
81
+ case FunctionParamType.CTX:
82
+ args[param.index] = ctx;
83
+ break;
84
+ case FunctionParamType.INPUT:
85
+ args[param.index] = validatedParams;
86
+ break;
87
+ case FunctionParamType.BODY:
88
+ args[param.index] = { context: ctx, params: validatedParams };
89
+ break;
90
+ }
91
+ }
92
+ // If no parameter decorators, use default order: (ctx, params)
93
+ if (sortedParams.length === 0) {
94
+ args.push(ctx, validatedParams);
95
+ }
96
+ // Call the method
97
+ const method = instance[methodKey];
98
+ const result = await method.apply(instance, args);
99
+ // Validate output if schema exists
100
+ const outputSchema = Reflect.getMetadata(OUTPUT_SCHEMA_METADATA, ExtensionClass, methodKey);
101
+ if (outputSchema) {
102
+ return outputSchema.parse(result);
103
+ }
104
+ return result;
105
+ };
106
+ return {
107
+ instance,
108
+ extensionName: extensionMeta.name,
109
+ functionNames,
110
+ callFunction,
111
+ };
112
+ }
113
+ //# sourceMappingURL=test-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-extension.js","sourceRoot":"","sources":["../../src/testing/test-extension.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAA2B,MAAM,mBAAmB,CAAC;AA0B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,mBAAmB,CACjC,cAAuB,EACvB,GAAG,YAAuB;IAE1B,yBAAyB;IACzB,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;IAC9E,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,SAAS,cAAc,CAAC,IAAI,mCAAmC,CAAC,CAAC;IACnF,CAAC;IAED,oCAAoC;IACpC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,YAAY,CAAC,CAAC;IAErD,qBAAqB;IACrB,MAAM,YAAY,GAChB,OAAO,CAAC,WAAW,CAAC,kBAAkB,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC;IAEhE,MAAM,aAAa,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,iBAAiB,EAAE,cAAc,EAAE,GAAG,CAE9D,CAAC;QACd,OAAO,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,yBAAyB;IACzB,MAAM,YAAY,GAAG,KAAK,EACxB,YAAoB,EACpB,MAAgB,EAChB,cAAmC,EACjB,EAAE;QACpB,mCAAmC;QACnC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,iBAAiB,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;YAC7E,OAAO,QAAQ,EAAE,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,YAAY,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,aAAa,YAAY,kBAAkB,cAAc,CAAC,IAAI,IAAI;gBAChE,wBAAwB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrD,CAAC;QACJ,CAAC;QAED,yBAAyB;QACzB,MAAM,SAAS,GACb,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,cAAc,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;QAEvE,kCAAkC;QAClC,MAAM,WAAW,GAA4B,OAAO,CAAC,WAAW,CAC9D,qBAAqB,EACrB,cAAc,EACd,SAAS,CACV,CAAC;QAEF,kCAAkC;QAClC,IAAI,eAAe,GAAG,MAAM,CAAC;QAC7B,IAAI,WAAW,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACxC,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;QACzD,CAAC;QAED,iBAAiB;QACjB,MAAM,GAAG,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAE9C,gDAAgD;QAChD,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAEtE,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YACjC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,iBAAiB,CAAC,GAAG;oBACxB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;oBACxB,MAAM;gBACR,KAAK,iBAAiB,CAAC,KAAK;oBAC1B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC;oBACpC,MAAM;gBACR,KAAK,iBAAiB,CAAC,IAAI;oBACzB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;oBAC9D,MAAM;YACV,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAClC,CAAC;QAED,kBAAkB;QAClB,MAAM,MAAM,GAAI,QAA6C,CAAC,SAAS,CAElD,CAAC;QAEtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAElD,mCAAmC;QACnC,MAAM,YAAY,GAA4B,OAAO,CAAC,WAAW,CAC/D,sBAAsB,EACtB,cAAc,EACd,SAAS,CACV,CAAC;QAEF,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;QAC/C,CAAC;QAED,OAAO,MAAiB,CAAC;IAC3B,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,aAAa,EAAE,aAAa,CAAC,IAAI;QACjC,aAAa;QACb,YAAY;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { TokenCacheStorage, CachedToken } from "./types.js";
2
+ /**
3
+ * In-memory token cache storage
4
+ * Suitable for single-instance deployments
5
+ * For multi-instance deployments, use Redis or database storage
6
+ */
7
+ export declare class InMemoryTokenCache implements TokenCacheStorage {
8
+ private cache;
9
+ private cleanupInterval;
10
+ constructor(cleanupIntervalMs?: number);
11
+ get(key: string): Promise<CachedToken | null>;
12
+ set(key: string, token: CachedToken, ttlMs?: number): Promise<void>;
13
+ delete(key: string): Promise<void>;
14
+ clear(): Promise<void>;
15
+ /**
16
+ * Cleanup expired entries
17
+ */
18
+ private cleanup;
19
+ /**
20
+ * Stop the cleanup interval (call when shutting down)
21
+ */
22
+ destroy(): void;
23
+ /**
24
+ * Get cache statistics
25
+ */
26
+ getStats(): {
27
+ size: number;
28
+ keys: string[];
29
+ };
30
+ }
31
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/token/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,OAAO,CAAC,KAAK,CAAgE;IAC7E,OAAO,CAAC,eAAe,CAA+C;gBAE1D,iBAAiB,SAAQ;IAOrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAa7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;CAM7C"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * In-memory token cache storage
3
+ * Suitable for single-instance deployments
4
+ * For multi-instance deployments, use Redis or database storage
5
+ */
6
+ export class InMemoryTokenCache {
7
+ cache = new Map();
8
+ cleanupInterval = null;
9
+ constructor(cleanupIntervalMs = 60000) {
10
+ // Periodic cleanup of expired entries
11
+ this.cleanupInterval = setInterval(() => {
12
+ this.cleanup();
13
+ }, cleanupIntervalMs);
14
+ }
15
+ get(key) {
16
+ const entry = this.cache.get(key);
17
+ if (!entry)
18
+ return Promise.resolve(null);
19
+ // Check if expired
20
+ if (Date.now() > entry.expiresAt) {
21
+ this.cache.delete(key);
22
+ return Promise.resolve(null);
23
+ }
24
+ return Promise.resolve(entry.token);
25
+ }
26
+ set(key, token, ttlMs) {
27
+ const expiresAt = ttlMs ? Date.now() + ttlMs : token.token.expiresAt;
28
+ this.cache.set(key, { token, expiresAt });
29
+ return Promise.resolve();
30
+ }
31
+ delete(key) {
32
+ this.cache.delete(key);
33
+ return Promise.resolve();
34
+ }
35
+ clear() {
36
+ this.cache.clear();
37
+ return Promise.resolve();
38
+ }
39
+ /**
40
+ * Cleanup expired entries
41
+ */
42
+ cleanup() {
43
+ const now = Date.now();
44
+ for (const [key, entry] of this.cache.entries()) {
45
+ if (now > entry.expiresAt) {
46
+ this.cache.delete(key);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Stop the cleanup interval (call when shutting down)
52
+ */
53
+ destroy() {
54
+ if (this.cleanupInterval) {
55
+ clearInterval(this.cleanupInterval);
56
+ this.cleanupInterval = null;
57
+ }
58
+ }
59
+ /**
60
+ * Get cache statistics
61
+ */
62
+ getStats() {
63
+ return {
64
+ size: this.cache.size,
65
+ keys: Array.from(this.cache.keys()),
66
+ };
67
+ }
68
+ }
69
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/token/cache.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACrB,KAAK,GAAG,IAAI,GAAG,EAAqD,CAAC;IACrE,eAAe,GAA0C,IAAI,CAAC;IAEtE,YAAY,iBAAiB,GAAG,KAAK;QACnC,sCAAsC;QACtC,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;YACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACxB,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEzC,mBAAmB;QACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAkB,EAAE,KAAc;QACjD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SACpC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./cache.js";
3
+ export * from "./manager.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/token/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./cache.js";
3
+ export * from "./manager.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/token/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,111 @@
1
+ import type { TokenManagerConfig, TokenResponse, ManagerTokenRequest, UserTokenRequest, ChannelTokenRequest } from "./types.js";
2
+ /**
3
+ * Token manager for Channel.io App SDK
4
+ *
5
+ * Handles token issuance, caching, and automatic refresh for:
6
+ * - Manager tokens (for desk/agent operations)
7
+ * - User tokens (for user-facing operations)
8
+ * - Channel tokens (for channel-level operations)
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { TokenManager } from '@channel.io/app-sdk-server';
13
+ *
14
+ * const tokenManager = new TokenManager({
15
+ * appId: process.env.APP_ID,
16
+ * appSecret: process.env.APP_SECRET,
17
+ * });
18
+ *
19
+ * // Get a manager token (with automatic caching and refresh)
20
+ * const token = await tokenManager.getManagerToken({
21
+ * channelId: 'channel-123',
22
+ * managerId: 'manager-456',
23
+ * });
24
+ *
25
+ * // Use the token for API calls
26
+ * await fetch('https://api.channel.io/...', {
27
+ * headers: {
28
+ * 'Authorization': `Bearer ${token.accessToken}`,
29
+ * },
30
+ * });
31
+ * ```
32
+ */
33
+ export declare class TokenManager {
34
+ private readonly config;
35
+ private readonly cache;
36
+ private readonly debug;
37
+ constructor(config: TokenManagerConfig);
38
+ /**
39
+ * Get a manager token with automatic caching and refresh
40
+ */
41
+ getManagerToken(request: ManagerTokenRequest): Promise<TokenResponse>;
42
+ /**
43
+ * Get a user token with automatic caching and refresh
44
+ */
45
+ getUserToken(request: UserTokenRequest): Promise<TokenResponse>;
46
+ /**
47
+ * Get a channel token with automatic caching and refresh
48
+ */
49
+ getChannelToken(request: ChannelTokenRequest): Promise<TokenResponse>;
50
+ /**
51
+ * Manually refresh a token (bypass cache)
52
+ */
53
+ refreshToken(refreshToken: string): Promise<TokenResponse>;
54
+ /**
55
+ * Invalidate a cached token
56
+ */
57
+ invalidateToken(type: "manager" | "user" | "channel", channelId: string, entityId?: string): Promise<void>;
58
+ /**
59
+ * Clear all cached tokens
60
+ */
61
+ clearCache(): Promise<void>;
62
+ /**
63
+ * Get or refresh a token with automatic caching
64
+ */
65
+ private getOrRefreshToken;
66
+ /**
67
+ * Issue a manager token
68
+ */
69
+ private issueManagerToken;
70
+ /**
71
+ * Issue a user token
72
+ */
73
+ private issueUserToken;
74
+ /**
75
+ * Issue a channel token
76
+ */
77
+ private issueChannelToken;
78
+ /**
79
+ * Cache a token
80
+ */
81
+ private cacheToken;
82
+ /**
83
+ * Build a cache key
84
+ */
85
+ private buildCacheKey;
86
+ /**
87
+ * Make an API request to Channel.io
88
+ */
89
+ private apiRequest;
90
+ /**
91
+ * Normalize token response (handle different API response formats)
92
+ */
93
+ private normalizeTokenResponse;
94
+ /**
95
+ * Debug logging
96
+ */
97
+ private log;
98
+ /**
99
+ * Cleanup resources (call when shutting down)
100
+ */
101
+ destroy(): void;
102
+ }
103
+ /**
104
+ * Token manager error
105
+ */
106
+ export declare class TokenManagerError extends Error {
107
+ readonly statusCode?: number | undefined;
108
+ readonly responseBody?: string | undefined;
109
+ constructor(message: string, statusCode?: number | undefined, responseBody?: string | undefined);
110
+ }
111
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/token/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EAEb,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAiCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGF;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0D;IAChF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;gBAEpB,MAAM,EAAE,kBAAkB;IAUtC;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;IAK3E;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IAKrE;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;IAK3E;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAQhE;;OAEG;IACG,eAAe,CACnB,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,EACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;YACW,iBAAiB;IAqC/B;;OAEG;YACW,iBAAiB;IAQ/B;;OAEG;YACW,cAAc;IAQ5B;;OAEG;YACW,iBAAiB;IAQ/B;;OAEG;YACW,UAAU;IAWxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;YACW,UAAU;IA0BxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;OAEG;IACH,OAAO,CAAC,GAAG;IAUX;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,UAAU,CAAC,EAAE,MAAM;aACnB,YAAY,CAAC,EAAE,MAAM;gBAFrC,OAAO,EAAE,MAAM,EACC,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,YAAY,CAAC,EAAE,MAAM,YAAA;CAKxC"}