@stone-js/tencent-scf-adapter 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright © 2026 Stone Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # Stone.js - Tencent SCF Adapter
2
+
3
+ [![npm](https://img.shields.io/npm/l/@stone-js/tencent-scf-adapter)](https://opensource.org/licenses/MIT)
4
+ [![npm](https://img.shields.io/npm/v/@stone-js/tencent-scf-adapter)](https://www.npmjs.com/package/@stone-js/tencent-scf-adapter)
5
+ [![npm](https://img.shields.io/npm/dm/@stone-js/tencent-scf-adapter)](https://www.npmjs.com/package/@stone-js/tencent-scf-adapter)
6
+ ![Maintenance](https://img.shields.io/maintenance/yes/2026)
7
+ [![Build Status](https://github.com/stone-foundation/stone-js-tencent-scf-adapter/actions/workflows/main.yml/badge.svg)](https://github.com/stone-foundation/stone-js-tencent-scf-adapter/actions/workflows/main.yml)
8
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=stone-foundation_stone-js-tencent-scf-adapter&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=stone-foundation_stone-js-tencent-scf-adapter)
9
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
10
+
11
+ The **Tencent SCF Adapter** lets your Stone.js application run on **event-driven** Tencent Cloud Serverless Cloud Function, beyond HTTP. It normalizes any non-HTTP trigger (COS, CMQ/TDMQ, Timer, CKafka) into a Stone.js `IncomingEvent`, fully aligned with the Continuum Architecture.
12
+
13
+ > For **HTTP-triggered** functions, use [`@stone-js/tencent-scf-http-adapter`](https://www.npmjs.com/package/@stone-js/tencent-scf-http-adapter).
14
+
15
+ ---
16
+
17
+ ## Introduction
18
+
19
+ In Stone.js, **adapters** are the translation layer between a platform and your domain. This adapter targets the non-HTTP SCF triggers: the function is invoked with `(event, context)`, and the adapter turns that into a standardized `IncomingEvent`, runs it through your kernel, and returns a raw response. The event payload is exposed on the event metadata, so one handler can dispatch on the trigger.
20
+
21
+ It does **not** own a server: `run()` returns the `(event, context)` handler SCF invokes.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install @stone-js/tencent-scf-adapter
27
+ # or
28
+ pnpm add @stone-js/tencent-scf-adapter
29
+ # or
30
+ yarn add @stone-js/tencent-scf-adapter
31
+ ```
32
+
33
+ > Requires `@stone-js/core` and `@stone-js/env` as peer dependencies.
34
+
35
+ ## Usage
36
+
37
+ Declarative (decorator):
38
+
39
+ ```ts
40
+ import { StoneApp } from '@stone-js/core'
41
+ import { TencentScf } from '@stone-js/tencent-scf-adapter'
42
+
43
+ @TencentScf()
44
+ @StoneApp({ name: 'workers' })
45
+ export class Application {}
46
+ ```
47
+
48
+ Imperative (blueprint):
49
+
50
+ ```ts
51
+ import { defineStoneApp } from '@stone-js/core'
52
+ import { tencentScfAdapterBlueprint } from '@stone-js/tencent-scf-adapter'
53
+
54
+ export const App = defineStoneApp({ name: 'workers' }, [tencentScfAdapterBlueprint])
55
+ ```
56
+
57
+ `run()` returns the `(event, context)` handler SCF invokes:
58
+
59
+ ```ts
60
+ // index.js — the SCF function entry
61
+ exports.main_handler = await stoneApp.run()
62
+ ```
63
+
64
+ ### Failures and retries
65
+
66
+ SCF treats an event invocation as **failed** only when the handler rejects. On failure the adapter rethrows by default so SCF's retry / dead-letter policy applies, set `stone.adapter.rethrowOnError = false` to opt out and manage failures yourself.
67
+
68
+ ## Documentation
69
+
70
+ See the [official documentation](https://stonejs.dev/docs/adapters/tencent-scf) for the full guide.
71
+
72
+ ## License
73
+
74
+ [MIT](./LICENSE)
@@ -0,0 +1,59 @@
1
+ import { RawResponse } from './declarations';
2
+ import { IRawResponseWrapper, RawResponseOptions } from '@stone-js/core';
3
+ /**
4
+ * Wrapper for generic raw responses.
5
+ *
6
+ * The `RawResponseWrapper` is responsible for encapsulating a raw response
7
+ * and returning it in a structure that aligns with the Stone.js framework's requirements.
8
+ * It implements the `IRawResponseWrapper` interface, ensuring compatibility with the framework.
9
+ */
10
+ export declare class RawResponseWrapper implements IRawResponseWrapper<RawResponse> {
11
+ private readonly options;
12
+ /**
13
+ * Factory method to create an instance of `RawResponseWrapper`.
14
+ *
15
+ * This method initializes the wrapper with a set of partial response options.
16
+ *
17
+ * @param options - Partial options to configure the raw response.
18
+ * @returns A new instance of `RawResponseWrapper`.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const responseWrapper = RawResponseWrapper.create({
23
+ * headers: { 'Content-Type': 'application/json' },
24
+ * body: { message: 'Success' },
25
+ * statusCode: 200,
26
+ * });
27
+ *
28
+ * const response = responseWrapper.respond();
29
+ * console.log(response); // { headers: { 'Content-Type': 'application/json' }, body: { message: 'Success' }, statusCode: 200 }
30
+ * ```
31
+ */
32
+ static create(options: Partial<RawResponseOptions>): RawResponseWrapper;
33
+ /**
34
+ * Constructs an instance of `RawResponseWrapper`.
35
+ *
36
+ * This constructor is private and should not be called directly.
37
+ * Use the `create` method to initialize an instance.
38
+ *
39
+ * @param options - Partial options for configuring the raw response.
40
+ */
41
+ private constructor();
42
+ /**
43
+ * Constructs and returns the raw response.
44
+ *
45
+ * The `respond` method generates and returns the raw response based on
46
+ * the provided options. The response is returned as-is, allowing for
47
+ * maximum flexibility in defining its structure.
48
+ *
49
+ * @returns A `RawResponse` object containing the response options.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const responseWrapper = RawResponseWrapper.create({ body: 'Hello, world!' });
54
+ * const response = responseWrapper.respond();
55
+ * console.log(response); // { body: 'Hello, world!' }
56
+ * ```
57
+ */
58
+ respond(): RawResponse;
59
+ }
@@ -0,0 +1,83 @@
1
+ import { RawResponse, TencentScfEvent, TencentScfContext, TencentScfAdapterContext, TencentScfEventHandlerFunction } from './declarations';
2
+ import { Adapter, IBlueprint, IncomingEvent, OutgoingResponse, IncomingEventOptions } from '@stone-js/core';
3
+ /**
4
+ * Tencent SCF Adapter for Stone.js.
5
+ *
6
+ * The `TencentScfAdapter` provides seamless integration between Stone.js applications
7
+ * and the Tencent SCF environment. It processes incoming events from Tencent SCF,
8
+ * transforms them into `IncomingEvent` instances, and returns a `RawResponse`.
9
+ *
10
+ * This adapter ensures compatibility with Tencent SCF's execution model and
11
+ * abstracts the event handling process for Stone.js developers.
12
+ *
13
+ * @template TencentScfEvent - The type of the raw event received from Tencent SCF.
14
+ * @template RawResponse - The type of the response to send back to Tencent SCF.
15
+ * @template TencentScfContext - The Tencent SCF execution context type.
16
+ * @template IncomingEvent - The type of the processed incoming event.
17
+ * @template IncomingEventOptions - Options used to create an incoming event.
18
+ * @template OutgoingResponse - The type of the outgoing response after processing.
19
+ * @template TencentScfAdapterContext - Context type specific to the adapter.
20
+ *
21
+ * @extends Adapter
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { TencentScfAdapter } from '@stone-js/aws-lambda-adapter';
26
+ *
27
+ * const adapter = TencentScfAdapter.create({...});
28
+ *
29
+ * const handler = await adapter.run();
30
+ *
31
+ * export { handler };
32
+ * ```
33
+ *
34
+ * @see {@link https://stone-js.com/docs Stone.js Documentation}
35
+ * @see {@link https://docs.aws.amazon.com/lambda/ Tencent SCF Documentation}
36
+ */
37
+ export declare class TencentScfAdapter extends Adapter<TencentScfEvent, RawResponse, TencentScfContext, IncomingEvent, IncomingEventOptions, OutgoingResponse, TencentScfAdapterContext> {
38
+ /**
39
+ * Creates an instance of the `TencentScfAdapter`.
40
+ *
41
+ * @param blueprint - The application blueprint.
42
+ * @returns A new instance of `TencentScfAdapter`.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const adapter = TencentScfAdapter.create(blueprint);
47
+ * await adapter.run();
48
+ * ```
49
+ */
50
+ static create(blueprint: IBlueprint): TencentScfAdapter;
51
+ /**
52
+ * Executes the adapter and provides an Tencent SCF-compatible handler function.
53
+ *
54
+ * The `run` method initializes the adapter and returns a handler function
55
+ * that Tencent SCF can invoke. This handler processes events, manages context,
56
+ * and returns the appropriate response.
57
+ *
58
+ * @template ExecutionResultType - The type representing the Tencent SCF event handler function.
59
+ * @returns A promise resolving to the Tencent SCF handler function.
60
+ * @throws {TencentScfAdapterError} If used outside the Tencent SCF environment.
61
+ */
62
+ run<ExecutionResultType = TencentScfEventHandlerFunction>(): Promise<ExecutionResultType>;
63
+ /**
64
+ * Initializes the adapter and validates its execution context.
65
+ *
66
+ * Ensures the adapter is running in an Tencent SCF environment. If not, it
67
+ * throws an error to prevent misuse.
68
+ *
69
+ * @throws {TencentScfAdapterError} If executed outside an Tencent SCF context (e.g., browser).
70
+ */
71
+ protected onStart(): Promise<void>;
72
+ /**
73
+ * Processes an incoming Tencent SCF event.
74
+ *
75
+ * This method transforms the raw Tencent SCF event into a Stone.js `IncomingEvent`,
76
+ * processes it through the pipeline, and generates a `RawResponse` to send back.
77
+ *
78
+ * @param rawEvent - The raw Tencent SCF event to be processed.
79
+ * @param executionContext - The Tencent SCF execution context for the event.
80
+ * @returns A promise resolving to the processed `RawResponse`.
81
+ */
82
+ protected eventListener(rawEvent: TencentScfEvent, executionContext: TencentScfContext): Promise<RawResponse>;
83
+ }
@@ -0,0 +1,28 @@
1
+ import { IBlueprint, AdapterErrorContext, IAdapterErrorHandler, AdapterEventBuilderType } from '@stone-js/core';
2
+ import { TencentScfContext, TencentScfEvent, RawResponse } from './declarations';
3
+ /**
4
+ * TencentScfErrorHandler options.
5
+ */
6
+ export interface TencentScfErrorHandlerOptions {
7
+ blueprint: IBlueprint;
8
+ }
9
+ /**
10
+ * Class representing an TencentScfErrorHandler.
11
+ */
12
+ export declare class TencentScfErrorHandler implements IAdapterErrorHandler<TencentScfEvent, RawResponse, TencentScfContext> {
13
+ private readonly logger;
14
+ /**
15
+ * Create an TencentScfErrorHandler.
16
+ *
17
+ * @param options - TencentScfErrorHandler options.
18
+ */
19
+ constructor({ blueprint }: TencentScfErrorHandlerOptions);
20
+ /**
21
+ * Handle an error.
22
+ *
23
+ * @param error - The error to handle.
24
+ * @param context - The context of the adapter.
25
+ * @returns The raw response builder.
26
+ */
27
+ handle(error: Error, context: AdapterErrorContext<TencentScfEvent, RawResponse, TencentScfContext>): AdapterEventBuilderType<RawResponse>;
28
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A constant representing the Tencent SCF platform identifier.
3
+ *
4
+ * This constant is used as an alias for the Tencent SCF Adapter within the Stone.js framework.
5
+ * It helps in identifying and configuring platform-specific adapters or components for handling
6
+ * incoming requests and responses.
7
+ */
8
+ export declare const TENCENT_SCF_PLATFORM = "tencent_scf";
@@ -0,0 +1,42 @@
1
+ import { RawResponseWrapper } from './RawResponseWrapper';
2
+ import { AdapterContext, IAdapterEventBuilder, IncomingEvent, IncomingEventOptions, OutgoingResponse, RawResponseOptions } from '@stone-js/core';
3
+ /**
4
+ * Represents a generic raw response as a key-value pair.
5
+ */
6
+ export type RawResponse = Record<string, unknown>;
7
+ /**
8
+ * The event payload delivered to a non-HTTP Tencent SCF function.
9
+ *
10
+ * The shape depends on the trigger, the COS object event, the CMQ/TDMQ message, the Timer payload,
11
+ * the CKafka records, etc. Kept generic; the handler inspects the event metadata.
12
+ */
13
+ export type TencentScfEvent = Record<string, unknown>;
14
+ /**
15
+ * The Tencent SCF invocation context (`context` argument).
16
+ *
17
+ * Carries `request_id`, `function_name`, `namespace`, the credentials and the logger.
18
+ */
19
+ export type TencentScfContext = Record<string, unknown>;
20
+ /**
21
+ * The Tencent SCF event handler: `(event, context) => Promise<...>`, the signature the SCF event
22
+ * (non-HTTP) trigger invokes.
23
+ *
24
+ * @template RawResponseType - The type of the response returned by the handler.
25
+ */
26
+ export type TencentScfEventHandlerFunction<RawResponseType = RawResponse> = (rawEvent: TencentScfEvent, context: TencentScfContext) => Promise<RawResponseType>;
27
+ /**
28
+ * Represents the response builder for the Tencent SCF Adapter.
29
+ */
30
+ export type TencentScfAdapterResponseBuilder = IAdapterEventBuilder<RawResponseOptions, RawResponseWrapper>;
31
+ /**
32
+ * Represents the context for the Tencent SCF Adapter.
33
+ *
34
+ * This interface extends `AdapterContext` and includes additional properties
35
+ * specific to generic Tencent SCF events.
36
+ */
37
+ export interface TencentScfAdapterContext extends AdapterContext<TencentScfEvent, RawResponse, TencentScfContext, IncomingEvent, IncomingEventOptions, OutgoingResponse> {
38
+ /**
39
+ * The raw response associated with the current context.
40
+ */
41
+ rawResponse: RawResponse;
42
+ }
@@ -0,0 +1,33 @@
1
+ import { ClassType } from '@stone-js/core';
2
+ import { TencentScfAdapterAdapterConfig } from '../options/TencentScfAdapterBlueprint';
3
+ /**
4
+ * Configuration options for the `TencentScf` decorator.
5
+ * These options extend the default Tencent SCF adapter configuration.
6
+ */
7
+ export interface TencentScfOptions extends Partial<TencentScfAdapterAdapterConfig> {
8
+ }
9
+ /**
10
+ * A Stone.js decorator that integrates the Tencent SCF Adapter with a class.
11
+ *
12
+ * This decorator modifies the class to seamlessly enable Tencent SCF as the
13
+ * execution environment for a Stone.js application. By applying this decorator,
14
+ * the class is automatically configured with the necessary blueprint for Tencent SCF.
15
+ *
16
+ * @template T - The type of the class being decorated. Defaults to `ClassType`.
17
+ * @param options - Optional configuration to customize the Tencent SCF Adapter.
18
+ *
19
+ * @returns A class decorator that applies the Tencent SCF adapter configuration.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { TencentScf } from '@stone-js/tencent-scf-adapter';
24
+ *
25
+ * @TencentScf({
26
+ * alias: 'MyTencentScf',
27
+ * })
28
+ * class App {
29
+ * // Your application logic here
30
+ * }
31
+ * ```
32
+ */
33
+ export declare const TencentScf: <T extends ClassType = ClassType>(options?: TencentScfOptions) => ClassDecorator;
@@ -0,0 +1,7 @@
1
+ import { ErrorOptions, IntegrationError } from '@stone-js/core';
2
+ /**
3
+ * Custom error for Tencent SCF adapter operations.
4
+ */
5
+ export declare class TencentScfAdapterError extends IntegrationError {
6
+ constructor(message: string, options?: ErrorOptions);
7
+ }
@@ -0,0 +1,11 @@
1
+ export * from './RawResponseWrapper';
2
+ export * from './TencentScfAdapter';
3
+ export * from './TencentScfErrorHandler';
4
+ export * from './constants';
5
+ export * from './declarations';
6
+ export * from './decorators/TencentScf';
7
+ export * from './errors/TencentScfAdapterError';
8
+ export * from './middleware/BlueprintMiddleware';
9
+ export * from './middleware/IncomingEventMiddleware';
10
+ export * from './options/TencentScfAdapterBlueprint';
11
+ export * from './resolvers';
package/dist/index.js ADDED
@@ -0,0 +1,399 @@
1
+ import { IntegrationError, Adapter, AdapterEventBuilder, IncomingEvent, defaultLoggerResolver, OutgoingResponse, defaultKernelResolver, isNotEmpty, classDecoratorLegacyWrapper, addBlueprint } from '@stone-js/core';
2
+ import { getString } from '@stone-js/env';
3
+ import { cloneValue, deepMerge } from '@stone-js/config';
4
+
5
+ /**
6
+ * Wrapper for generic raw responses.
7
+ *
8
+ * The `RawResponseWrapper` is responsible for encapsulating a raw response
9
+ * and returning it in a structure that aligns with the Stone.js framework's requirements.
10
+ * It implements the `IRawResponseWrapper` interface, ensuring compatibility with the framework.
11
+ */
12
+ class RawResponseWrapper {
13
+ options;
14
+ /**
15
+ * Factory method to create an instance of `RawResponseWrapper`.
16
+ *
17
+ * This method initializes the wrapper with a set of partial response options.
18
+ *
19
+ * @param options - Partial options to configure the raw response.
20
+ * @returns A new instance of `RawResponseWrapper`.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const responseWrapper = RawResponseWrapper.create({
25
+ * headers: { 'Content-Type': 'application/json' },
26
+ * body: { message: 'Success' },
27
+ * statusCode: 200,
28
+ * });
29
+ *
30
+ * const response = responseWrapper.respond();
31
+ * console.log(response); // { headers: { 'Content-Type': 'application/json' }, body: { message: 'Success' }, statusCode: 200 }
32
+ * ```
33
+ */
34
+ static create(options) {
35
+ return new this(options);
36
+ }
37
+ /**
38
+ * Constructs an instance of `RawResponseWrapper`.
39
+ *
40
+ * This constructor is private and should not be called directly.
41
+ * Use the `create` method to initialize an instance.
42
+ *
43
+ * @param options - Partial options for configuring the raw response.
44
+ */
45
+ constructor(options) {
46
+ this.options = options;
47
+ }
48
+ /**
49
+ * Constructs and returns the raw response.
50
+ *
51
+ * The `respond` method generates and returns the raw response based on
52
+ * the provided options. The response is returned as-is, allowing for
53
+ * maximum flexibility in defining its structure.
54
+ *
55
+ * @returns A `RawResponse` object containing the response options.
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const responseWrapper = RawResponseWrapper.create({ body: 'Hello, world!' });
60
+ * const response = responseWrapper.respond();
61
+ * console.log(response); // { body: 'Hello, world!' }
62
+ * ```
63
+ */
64
+ respond() {
65
+ return this.options;
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Custom error for Tencent SCF adapter operations.
71
+ */
72
+ class TencentScfAdapterError extends IntegrationError {
73
+ constructor(message, options) {
74
+ super(message, options);
75
+ this.name = 'TencentScfAdapterError';
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Tencent SCF Adapter for Stone.js.
81
+ *
82
+ * The `TencentScfAdapter` provides seamless integration between Stone.js applications
83
+ * and the Tencent SCF environment. It processes incoming events from Tencent SCF,
84
+ * transforms them into `IncomingEvent` instances, and returns a `RawResponse`.
85
+ *
86
+ * This adapter ensures compatibility with Tencent SCF's execution model and
87
+ * abstracts the event handling process for Stone.js developers.
88
+ *
89
+ * @template TencentScfEvent - The type of the raw event received from Tencent SCF.
90
+ * @template RawResponse - The type of the response to send back to Tencent SCF.
91
+ * @template TencentScfContext - The Tencent SCF execution context type.
92
+ * @template IncomingEvent - The type of the processed incoming event.
93
+ * @template IncomingEventOptions - Options used to create an incoming event.
94
+ * @template OutgoingResponse - The type of the outgoing response after processing.
95
+ * @template TencentScfAdapterContext - Context type specific to the adapter.
96
+ *
97
+ * @extends Adapter
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * import { TencentScfAdapter } from '@stone-js/aws-lambda-adapter';
102
+ *
103
+ * const adapter = TencentScfAdapter.create({...});
104
+ *
105
+ * const handler = await adapter.run();
106
+ *
107
+ * export { handler };
108
+ * ```
109
+ *
110
+ * @see {@link https://stone-js.com/docs Stone.js Documentation}
111
+ * @see {@link https://docs.aws.amazon.com/lambda/ Tencent SCF Documentation}
112
+ */
113
+ class TencentScfAdapter extends Adapter {
114
+ /**
115
+ * Creates an instance of the `TencentScfAdapter`.
116
+ *
117
+ * @param blueprint - The application blueprint.
118
+ * @returns A new instance of `TencentScfAdapter`.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const adapter = TencentScfAdapter.create(blueprint);
123
+ * await adapter.run();
124
+ * ```
125
+ */
126
+ static create(blueprint) {
127
+ return new this(blueprint);
128
+ }
129
+ /**
130
+ * Executes the adapter and provides an Tencent SCF-compatible handler function.
131
+ *
132
+ * The `run` method initializes the adapter and returns a handler function
133
+ * that Tencent SCF can invoke. This handler processes events, manages context,
134
+ * and returns the appropriate response.
135
+ *
136
+ * @template ExecutionResultType - The type representing the Tencent SCF event handler function.
137
+ * @returns A promise resolving to the Tencent SCF handler function.
138
+ * @throws {TencentScfAdapterError} If used outside the Tencent SCF environment.
139
+ */
140
+ async run() {
141
+ await this.onStart();
142
+ const handler = async (rawEvent, executionContext) => {
143
+ return await this.eventListener(rawEvent, executionContext);
144
+ };
145
+ return handler;
146
+ }
147
+ /**
148
+ * Initializes the adapter and validates its execution context.
149
+ *
150
+ * Ensures the adapter is running in an Tencent SCF environment. If not, it
151
+ * throws an error to prevent misuse.
152
+ *
153
+ * @throws {TencentScfAdapterError} If executed outside an Tencent SCF context (e.g., browser).
154
+ */
155
+ async onStart() {
156
+ if (typeof window === 'object') {
157
+ throw new TencentScfAdapterError('This `TencentScfAdapter` must be used only in Tencent SCF context.');
158
+ }
159
+ await this.executeHooks('onStart');
160
+ }
161
+ /**
162
+ * Processes an incoming Tencent SCF event.
163
+ *
164
+ * This method transforms the raw Tencent SCF event into a Stone.js `IncomingEvent`,
165
+ * processes it through the pipeline, and generates a `RawResponse` to send back.
166
+ *
167
+ * @param rawEvent - The raw Tencent SCF event to be processed.
168
+ * @param executionContext - The Tencent SCF execution context for the event.
169
+ * @returns A promise resolving to the processed `RawResponse`.
170
+ */
171
+ async eventListener(rawEvent, executionContext) {
172
+ const incomingEventBuilder = AdapterEventBuilder.create({
173
+ resolver: (options) => IncomingEvent.create(options)
174
+ });
175
+ const rawResponseBuilder = AdapterEventBuilder.create({
176
+ resolver: (options) => RawResponseWrapper.create(options)
177
+ });
178
+ const rawResponse = {};
179
+ const context = {
180
+ rawEvent,
181
+ rawResponse,
182
+ executionContext,
183
+ rawResponseBuilder,
184
+ incomingEventBuilder
185
+ };
186
+ let eventHandler;
187
+ try {
188
+ eventHandler = this.resolveEventHandler();
189
+ await this.executeEventHandlerHooks('onInit', eventHandler);
190
+ return await this.sendEventThroughDestination(context, eventHandler);
191
+ }
192
+ catch (error) {
193
+ const rawResponseBuilder = await this.handleError(error, context);
194
+ // Pass `eventHandler` so the kernel's `onTerminate` (log flush, connection close) runs on the
195
+ // error path too — the core only fires it when the handler is provided.
196
+ const response = await this.buildRawResponse({ ...context, rawResponseBuilder }, eventHandler);
197
+ // Tencent SCF only treats an event invocation (COS, CMQ/TDMQ, Timer, CKafka) as failed when
198
+ // the handler REJECTS. Swallowing the error and returning a value acknowledges the event and
199
+ // defeats SCF's retry / dead-letter policy — silent data loss. So by default we rethrow. An
200
+ // app that manages failures itself can opt out with `stone.adapter.rethrowOnError = false`.
201
+ if (this.blueprint.get('stone.adapter.rethrowOnError', true)) {
202
+ throw error;
203
+ }
204
+ return response;
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * A constant representing the Tencent SCF platform identifier.
211
+ *
212
+ * This constant is used as an alias for the Tencent SCF Adapter within the Stone.js framework.
213
+ * It helps in identifying and configuring platform-specific adapters or components for handling
214
+ * incoming requests and responses.
215
+ */
216
+ const TENCENT_SCF_PLATFORM = 'tencent_scf';
217
+
218
+ /**
219
+ * Class representing an TencentScfErrorHandler.
220
+ */
221
+ class TencentScfErrorHandler {
222
+ logger;
223
+ /**
224
+ * Create an TencentScfErrorHandler.
225
+ *
226
+ * @param options - TencentScfErrorHandler options.
227
+ */
228
+ constructor({ blueprint }) {
229
+ this.logger = blueprint.get('stone.logger.resolver', defaultLoggerResolver)(blueprint);
230
+ }
231
+ /**
232
+ * Handle an error.
233
+ *
234
+ * @param error - The error to handle.
235
+ * @param context - The context of the adapter.
236
+ * @returns The raw response builder.
237
+ */
238
+ handle(error, context) {
239
+ this.logger.error(error.message, { error });
240
+ return context
241
+ .rawResponseBuilder
242
+ .add('statusCode', 500);
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Adapter resolver for generic Tencent SCF adapter.
248
+ *
249
+ * Creates and configures an `TencentScfAdapter` for handling generic events in Tencent SCF.
250
+ *
251
+ * @param blueprint - The `IBlueprint` providing configuration and dependencies.
252
+ * @returns An `TencentScfAdapter` instance.
253
+ */
254
+ const tencentScfAdapterResolver = (blueprint) => {
255
+ return TencentScfAdapter.create(blueprint);
256
+ };
257
+
258
+ /**
259
+ * Middleware to dynamically set response resolver for adapter.
260
+ *
261
+ * @param context - The configuration context containing modules and blueprint.
262
+ * @param next - The next pipeline function to continue processing.
263
+ * @returns The updated blueprint or a promise resolving to it.
264
+ *
265
+ * @example
266
+ * ```typescript
267
+ * SetTencentScfResponseResolverMiddleware(context, next)
268
+ * ```
269
+ */
270
+ const SetTencentScfResponseResolverMiddleware = async (context, next) => {
271
+ if (context.blueprint.get('stone.adapter.platform') === TENCENT_SCF_PLATFORM) {
272
+ context.blueprint.set('stone.kernel.responseResolver', (options) => OutgoingResponse.create(options));
273
+ }
274
+ return await next(context);
275
+ };
276
+ /**
277
+ * Configuration for adapter processing middleware.
278
+ *
279
+ * This array defines a list of middleware pipes, each with a `pipe` function and a `priority`.
280
+ * These pipes are executed in the order of their priority values, with lower values running first.
281
+ */
282
+ const metaAdapterBlueprintMiddleware = [
283
+ { module: SetTencentScfResponseResolverMiddleware, priority: 6 }
284
+ ];
285
+
286
+ /**
287
+ * Middleware for handling incoming events and transforming them into Stone.js events.
288
+ *
289
+ * This class processes incoming events, extracting relevant data and forwards them to the next middleware in the pipeline.
290
+ */
291
+ class IncomingEventMiddleware {
292
+ /**
293
+ * Handles the incoming event, processes it, and invokes the next middleware in the pipeline.
294
+ *
295
+ * @param context - The adapter context containing the raw event, execution context, and other data.
296
+ * @param next - The next middleware to be invoked in the pipeline.
297
+ * @returns A promise that resolves to the processed Response Builder.
298
+ * @throws {TencentScfAdapterError} If required components are missing in the context.
299
+ */
300
+ async handle(context, next) {
301
+ if ((context.rawEvent === undefined) || ((context.incomingEventBuilder?.add) === undefined)) {
302
+ throw new TencentScfAdapterError('The context is missing required components.');
303
+ }
304
+ context
305
+ .incomingEventBuilder
306
+ .add('metadata', context.rawEvent)
307
+ .add('source', this.getSource(context));
308
+ return await next(context);
309
+ }
310
+ /**
311
+ * Create the IncomingEventSource from the context.
312
+ *
313
+ * @param context - The adapter context containing the raw event, execution context, and other data.
314
+ * @returns The Incoming Event Source.
315
+ */
316
+ getSource(context) {
317
+ return {
318
+ rawEvent: context.rawEvent,
319
+ platform: TENCENT_SCF_PLATFORM,
320
+ rawContext: context.executionContext
321
+ };
322
+ }
323
+ }
324
+ /**
325
+ * Meta Middleware for processing incoming events.
326
+ */
327
+ const MetaIncomingEventMiddleware = { module: IncomingEventMiddleware, isClass: true };
328
+
329
+ /**
330
+ * Default blueprint configuration for the Tencent SCF Adapter.
331
+ *
332
+ * This blueprint defines the initial configuration for the Tencent SCF adapter
333
+ * within the Stone.js framework. It includes:
334
+ * - An alias for the Tencent SCF platform (`TENCENT_SCF_PLATFORM`).
335
+ * - A default resolver function (currently a placeholder).
336
+ * - Middleware, hooks, and state flags (`current`, `default`, `preferred`).
337
+ */
338
+ const tencentScfAdapterBlueprint = {
339
+ stone: {
340
+ blueprint: {
341
+ middleware: metaAdapterBlueprintMiddleware
342
+ },
343
+ adapters: [
344
+ {
345
+ current: false,
346
+ variant: 'server',
347
+ platform: TENCENT_SCF_PLATFORM,
348
+ middleware: [
349
+ MetaIncomingEventMiddleware
350
+ ],
351
+ resolver: tencentScfAdapterResolver,
352
+ eventHandlerResolver: defaultKernelResolver,
353
+ errorHandlers: {
354
+ default: { module: TencentScfErrorHandler, isClass: true }
355
+ },
356
+ // The Tencent SCF runtime sets SCF_FUNCTIONNAME in the function environment.
357
+ default: isNotEmpty(getString('SCF_FUNCTIONNAME', ''))
358
+ }
359
+ ]
360
+ }
361
+ };
362
+
363
+ /**
364
+ * A Stone.js decorator that integrates the Tencent SCF Adapter with a class.
365
+ *
366
+ * This decorator modifies the class to seamlessly enable Tencent SCF as the
367
+ * execution environment for a Stone.js application. By applying this decorator,
368
+ * the class is automatically configured with the necessary blueprint for Tencent SCF.
369
+ *
370
+ * @template T - The type of the class being decorated. Defaults to `ClassType`.
371
+ * @param options - Optional configuration to customize the Tencent SCF Adapter.
372
+ *
373
+ * @returns A class decorator that applies the Tencent SCF adapter configuration.
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * import { TencentScf } from '@stone-js/tencent-scf-adapter';
378
+ *
379
+ * @TencentScf({
380
+ * alias: 'MyTencentScf',
381
+ * })
382
+ * class App {
383
+ * // Your application logic here
384
+ * }
385
+ * ```
386
+ */
387
+ const TencentScf = (options = {}) => {
388
+ return classDecoratorLegacyWrapper((target, context) => {
389
+ // Clone the module-level default before merging so decorating a class never mutates the shared
390
+ // singleton (which would leak options across classes and tests).
391
+ const blueprint = cloneValue(tencentScfAdapterBlueprint);
392
+ if (blueprint.stone?.adapters?.[0] !== undefined) {
393
+ blueprint.stone.adapters[0] = deepMerge(blueprint.stone.adapters[0], options);
394
+ }
395
+ addBlueprint(target, context, blueprint);
396
+ });
397
+ };
398
+
399
+ export { IncomingEventMiddleware, MetaIncomingEventMiddleware, RawResponseWrapper, SetTencentScfResponseResolverMiddleware, TENCENT_SCF_PLATFORM, TencentScf, TencentScfAdapter, TencentScfAdapterError, TencentScfErrorHandler, metaAdapterBlueprintMiddleware, tencentScfAdapterBlueprint, tencentScfAdapterResolver };
@@ -0,0 +1,21 @@
1
+ import { ClassType, BlueprintContext, IBlueprint, MetaMiddleware, NextMiddleware } from '@stone-js/core';
2
+ /**
3
+ * Middleware to dynamically set response resolver for adapter.
4
+ *
5
+ * @param context - The configuration context containing modules and blueprint.
6
+ * @param next - The next pipeline function to continue processing.
7
+ * @returns The updated blueprint or a promise resolving to it.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * SetTencentScfResponseResolverMiddleware(context, next)
12
+ * ```
13
+ */
14
+ export declare const SetTencentScfResponseResolverMiddleware: (context: BlueprintContext<IBlueprint, ClassType>, next: NextMiddleware<BlueprintContext<IBlueprint, ClassType>, IBlueprint>) => Promise<IBlueprint>;
15
+ /**
16
+ * Configuration for adapter processing middleware.
17
+ *
18
+ * This array defines a list of middleware pipes, each with a `pipe` function and a `priority`.
19
+ * These pipes are executed in the order of their priority values, with lower values running first.
20
+ */
21
+ export declare const metaAdapterBlueprintMiddleware: Array<MetaMiddleware<BlueprintContext<IBlueprint, ClassType>, IBlueprint>>;
@@ -0,0 +1,29 @@
1
+ import { NextMiddleware, type MetaMiddleware } from '@stone-js/core';
2
+ import { TencentScfAdapterContext, TencentScfAdapterResponseBuilder } from '../declarations';
3
+ /**
4
+ * Middleware for handling incoming events and transforming them into Stone.js events.
5
+ *
6
+ * This class processes incoming events, extracting relevant data and forwards them to the next middleware in the pipeline.
7
+ */
8
+ export declare class IncomingEventMiddleware {
9
+ /**
10
+ * Handles the incoming event, processes it, and invokes the next middleware in the pipeline.
11
+ *
12
+ * @param context - The adapter context containing the raw event, execution context, and other data.
13
+ * @param next - The next middleware to be invoked in the pipeline.
14
+ * @returns A promise that resolves to the processed Response Builder.
15
+ * @throws {TencentScfAdapterError} If required components are missing in the context.
16
+ */
17
+ handle(context: TencentScfAdapterContext, next: NextMiddleware<TencentScfAdapterContext, TencentScfAdapterResponseBuilder>): Promise<TencentScfAdapterResponseBuilder>;
18
+ /**
19
+ * Create the IncomingEventSource from the context.
20
+ *
21
+ * @param context - The adapter context containing the raw event, execution context, and other data.
22
+ * @returns The Incoming Event Source.
23
+ */
24
+ private getSource;
25
+ }
26
+ /**
27
+ * Meta Middleware for processing incoming events.
28
+ */
29
+ export declare const MetaIncomingEventMiddleware: MetaMiddleware<any, any>;
@@ -0,0 +1,30 @@
1
+ import { TencentScfContext, TencentScfEvent, RawResponse } from '../declarations';
2
+ import { AdapterConfig, IncomingEvent, IncomingEventOptions, OutgoingResponse, StoneBlueprint } from '@stone-js/core';
3
+ /**
4
+ * Configuration interface for the Tencent SCF Adapter.
5
+ *
6
+ * Extends the `AdapterConfig` interface from the Stone.js framework and provides
7
+ * customizable options specific to the Tencent SCF platform. This includes
8
+ * alias, resolver, middleware, hooks, and various adapter state flags.
9
+ */
10
+ export interface TencentScfAdapterAdapterConfig extends AdapterConfig<TencentScfEvent, RawResponse, TencentScfContext, IncomingEvent, IncomingEventOptions, OutgoingResponse> {
11
+ }
12
+ /**
13
+ * Blueprint interface for the Tencent SCF Adapter.
14
+ *
15
+ * This interface extends `StoneBlueprint` and defines the structure of the
16
+ * Tencent SCF adapter blueprint used in the Stone.js framework. It includes
17
+ * a `stone` object with an array of `TencentScfAdapterConfig` items.
18
+ */
19
+ export interface TencentScfAdapterBlueprint extends StoneBlueprint {
20
+ }
21
+ /**
22
+ * Default blueprint configuration for the Tencent SCF Adapter.
23
+ *
24
+ * This blueprint defines the initial configuration for the Tencent SCF adapter
25
+ * within the Stone.js framework. It includes:
26
+ * - An alias for the Tencent SCF platform (`TENCENT_SCF_PLATFORM`).
27
+ * - A default resolver function (currently a placeholder).
28
+ * - Middleware, hooks, and state flags (`current`, `default`, `preferred`).
29
+ */
30
+ export declare const tencentScfAdapterBlueprint: TencentScfAdapterBlueprint;
@@ -0,0 +1,10 @@
1
+ import { AdapterResolver } from '@stone-js/core';
2
+ /**
3
+ * Adapter resolver for generic Tencent SCF adapter.
4
+ *
5
+ * Creates and configures an `TencentScfAdapter` for handling generic events in Tencent SCF.
6
+ *
7
+ * @param blueprint - The `IBlueprint` providing configuration and dependencies.
8
+ * @returns An `TencentScfAdapter` instance.
9
+ */
10
+ export declare const tencentScfAdapterResolver: AdapterResolver;
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@stone-js/tencent-scf-adapter",
3
+ "version": "0.8.0",
4
+ "description": "General-purpose Tencent Cloud SCF adapter for Stone.js, run any app on event-driven Serverless Cloud Function triggers, beyond HTTP. Supports COS, CMQ/TDMQ, Timer and CKafka.",
5
+ "author": "Mr. Stone <evensstone@gmail.com>",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/stone-foundation/stone-js-framework.git",
10
+ "directory": "stone-js-tencent-scf-adapter"
11
+ },
12
+ "homepage": "https://stonejs.dev",
13
+ "bugs": {
14
+ "url": "https://github.com/stone-foundation/stone-js-framework/issues"
15
+ },
16
+ "keywords": [
17
+ "tencent",
18
+ "tencent-cloud",
19
+ "scf",
20
+ "serverless-cloud-function",
21
+ "faas",
22
+ "serverless",
23
+ "cos",
24
+ "timer",
25
+ "china",
26
+ "adapter",
27
+ "Stone.js"
28
+ ],
29
+ "files": [
30
+ "/dist"
31
+ ],
32
+ "type": "module",
33
+ "sideEffects": false,
34
+ "types": "./dist/index.d.ts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "default": "./dist/index.js"
39
+ }
40
+ },
41
+ "engines": {
42
+ "node": ">=18.17.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@stone-js/core": "0.8.0",
46
+ "@stone-js/env": "0.8.0"
47
+ },
48
+ "dependencies": {
49
+ "@stone-js/config": "0.8.0"
50
+ },
51
+ "devDependencies": {
52
+ "@commitlint/cli": "^19.8.1",
53
+ "@commitlint/config-conventional": "^19.8.1",
54
+ "@rollup/plugin-commonjs": "^28.0.6",
55
+ "@rollup/plugin-multi-entry": "^6.0.1",
56
+ "@rollup/plugin-node-resolve": "^16.0.1",
57
+ "@rollup/plugin-typescript": "^12.1.4",
58
+ "@types/node": "^24.0.7",
59
+ "@vitest/coverage-v8": "^3.2.4",
60
+ "husky": "^9.1.7",
61
+ "rimraf": "^6.0.1",
62
+ "rollup": "^4.44.1",
63
+ "rollup-plugin-node-externals": "^8.0.1",
64
+ "ts-standard": "^12.0.2",
65
+ "tslib": "^2.8.1",
66
+ "typedoc": "^0.28.6",
67
+ "typedoc-plugin-markdown": "^4.7.0",
68
+ "typescript": "^5.6.3",
69
+ "vitest": "^3.2.4"
70
+ },
71
+ "ts-standard": {
72
+ "globals": [
73
+ "it",
74
+ "test",
75
+ "expect",
76
+ "describe",
77
+ "beforeEach"
78
+ ]
79
+ },
80
+ "scripts": {
81
+ "lint": "ts-standard src",
82
+ "lint:fix": "ts-standard --fix src tests",
83
+ "predoc": "rimraf docs",
84
+ "doc": "typedoc",
85
+ "clean": "rimraf dist",
86
+ "build": "rollup -c",
87
+ "test": "vitest run",
88
+ "test:cvg": "npm run test -- --coverage",
89
+ "test:text": "npm run test:cvg -- --coverage.reporter=text",
90
+ "test:html": "npm run test:cvg -- --coverage.reporter=html",
91
+ "test:clover": "npm run test:cvg -- --coverage.reporter=clover"
92
+ }
93
+ }