@karmaniverous/smoz 0.2.9 → 0.2.11
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 +28 -28
- package/README.md +82 -81
- package/dist/cjs/index.js +20 -10
- package/dist/cli/index.cjs +262 -278
- package/dist/index.d.ts +44 -36
- package/dist/mjs/index.js +20 -10
- package/package.json +36 -37
- package/templates/default/.vscode/extensions.json +8 -8
- package/templates/default/README.md +98 -96
- package/templates/default/app/config/app.config.ts +3 -2
- package/templates/default/app/generated/openapi.json +8 -8
- package/templates/default/eslint.config.ts +0 -1
- package/templates/default/gitignore +42 -42
- package/templates/default/package.json +6 -7
- package/templates/default/tsconfig.base.json +21 -21
- package/templates/default/tsconfig.downstream.json +13 -13
- package/templates/default/tsconfig.eslint.json +2 -2
- package/templates/default/tsconfig.json +25 -25
- package/templates/default/tsdoc.json +46 -46
- package/templates/default/typedoc.json +14 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ZodOpenApiOperationObject, ZodOpenApiPathItemObject, ZodOpenApiPathsObject } from 'zod-openapi';
|
|
2
2
|
import * as aws_lambda from 'aws-lambda';
|
|
3
|
-
import { APIGatewayProxyEvent,
|
|
3
|
+
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, ALBEvent, SQSEvent, SNSEvent, S3Event, DynamoDBStreamEvent, KinesisStreamEvent, EventBridgeEvent, CloudWatchLogsEvent, SESEvent, CloudFrontRequestEvent, FirehoseTransformationEvent, CognitoUserPoolTriggerEvent, Context } from 'aws-lambda';
|
|
4
4
|
import { AWS } from '@serverless/typescript';
|
|
5
|
-
import { ZodObject, ZodRawShape
|
|
5
|
+
import { z, ZodObject, ZodRawShape } from 'zod';
|
|
6
6
|
import { MiddlewareObj } from '@middy/core';
|
|
7
7
|
import httpContentNegotiation from '@middy/http-content-negotiation';
|
|
8
8
|
import httpCors from '@middy/http-cors';
|
|
@@ -35,6 +35,39 @@ type MakeRequired<T extends object, U extends keyof T> = {
|
|
|
35
35
|
*/
|
|
36
36
|
type BaseOperation = MakeRequired<Omit<ZodOpenApiOperationObject, 'operationId'>, 'summary'>;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* baseEventTypeMapSchema
|
|
40
|
+
* - Schema-first companion to BaseEventTypeMap.
|
|
41
|
+
* - Now includes a Step Functions event with an optional Payload wrapper.
|
|
42
|
+
* - Ensures z.infer<typeof baseEventTypeMapSchema> === BaseEventTypeMap.
|
|
43
|
+
*
|
|
44
|
+
* @remarks * Consumers typically extend this schema when creating an App to add
|
|
45
|
+
* project‑local event tokens (e.g., 'step').
|
|
46
|
+
* Only tokens listed in the app’s `httpEventTypeTokens` are treated as HTTP at runtime.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
declare const baseEventTypeMapSchema: z.ZodObject<{
|
|
50
|
+
rest: z.ZodCustom<APIGatewayProxyEvent, APIGatewayProxyEvent>;
|
|
51
|
+
http: z.ZodCustom<APIGatewayProxyEventV2, APIGatewayProxyEventV2>;
|
|
52
|
+
alb: z.ZodCustom<ALBEvent, ALBEvent>;
|
|
53
|
+
sqs: z.ZodCustom<SQSEvent, SQSEvent>;
|
|
54
|
+
sns: z.ZodCustom<SNSEvent, SNSEvent>;
|
|
55
|
+
s3: z.ZodCustom<S3Event, S3Event>;
|
|
56
|
+
dynamodb: z.ZodCustom<DynamoDBStreamEvent, DynamoDBStreamEvent>;
|
|
57
|
+
kinesis: z.ZodCustom<KinesisStreamEvent, KinesisStreamEvent>;
|
|
58
|
+
eventbridge: z.ZodCustom<EventBridgeEvent<string, unknown>, EventBridgeEvent<string, unknown>>;
|
|
59
|
+
'cloudwatch-logs': z.ZodCustom<CloudWatchLogsEvent, CloudWatchLogsEvent>;
|
|
60
|
+
ses: z.ZodCustom<SESEvent, SESEvent>;
|
|
61
|
+
cloudfront: z.ZodCustom<CloudFrontRequestEvent, CloudFrontRequestEvent>;
|
|
62
|
+
firehose: z.ZodCustom<FirehoseTransformationEvent, FirehoseTransformationEvent>;
|
|
63
|
+
'cognito-userpool': z.ZodCustom<CognitoUserPoolTriggerEvent, CognitoUserPoolTriggerEvent>;
|
|
64
|
+
step: z.ZodObject<{
|
|
65
|
+
Payload: z.ZodOptional<z.ZodUnknown>;
|
|
66
|
+
}, z.core.$catchall<z.ZodUnknown>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
/** Canonical base event map type (schema‑first). Extend the schema in your App. */
|
|
69
|
+
type BaseEventTypeMap = z.infer<typeof baseEventTypeMapSchema>;
|
|
70
|
+
|
|
38
71
|
type Dict<T> = Record<string, T>;
|
|
39
72
|
type StagesFactoryInput<GlobalParams extends Record<string, unknown>, StageParams extends Record<string, unknown>> = {
|
|
40
73
|
globalParamsSchema: ZodObject<ZodRawShape>;
|
|
@@ -327,36 +360,6 @@ declare const buildSafeDefaults: (args: BuildSafeDefaultsArgs) => {
|
|
|
327
360
|
onError: M[];
|
|
328
361
|
};
|
|
329
362
|
|
|
330
|
-
/**
|
|
331
|
-
* baseEventTypeMapSchema
|
|
332
|
-
* - Schema-first companion to BaseEventTypeMap.
|
|
333
|
-
* - Ensures z.infer<typeof baseEventTypeMapSchema> === BaseEventTypeMap.
|
|
334
|
-
*
|
|
335
|
-
* @remarks
|
|
336
|
-
* Consumers typically extend this schema when creating an App to add
|
|
337
|
-
* project‑local event tokens (e.g., 'step').
|
|
338
|
-
* Only tokens listed in the app’s `httpEventTypeTokens` are treated as HTTP at runtime.
|
|
339
|
-
*/
|
|
340
|
-
|
|
341
|
-
declare const baseEventTypeMapSchema: z.ZodObject<{
|
|
342
|
-
rest: z.ZodCustom<APIGatewayProxyEvent, APIGatewayProxyEvent>;
|
|
343
|
-
http: z.ZodCustom<APIGatewayProxyEventV2, APIGatewayProxyEventV2>;
|
|
344
|
-
alb: z.ZodCustom<ALBEvent, ALBEvent>;
|
|
345
|
-
sqs: z.ZodCustom<SQSEvent, SQSEvent>;
|
|
346
|
-
sns: z.ZodCustom<SNSEvent, SNSEvent>;
|
|
347
|
-
s3: z.ZodCustom<S3Event, S3Event>;
|
|
348
|
-
dynamodb: z.ZodCustom<DynamoDBStreamEvent, DynamoDBStreamEvent>;
|
|
349
|
-
kinesis: z.ZodCustom<KinesisStreamEvent, KinesisStreamEvent>;
|
|
350
|
-
eventbridge: z.ZodCustom<EventBridgeEvent<string, unknown>, EventBridgeEvent<string, unknown>>;
|
|
351
|
-
'cloudwatch-logs': z.ZodCustom<CloudWatchLogsEvent, CloudWatchLogsEvent>;
|
|
352
|
-
ses: z.ZodCustom<SESEvent, SESEvent>;
|
|
353
|
-
cloudfront: z.ZodCustom<CloudFrontRequestEvent, CloudFrontRequestEvent>;
|
|
354
|
-
firehose: z.ZodCustom<FirehoseTransformationEvent, FirehoseTransformationEvent>;
|
|
355
|
-
'cognito-userpool': z.ZodCustom<CognitoUserPoolTriggerEvent, CognitoUserPoolTriggerEvent>;
|
|
356
|
-
}, z.core.$strip>;
|
|
357
|
-
/** Canonical base event map type (schema‑first). Extend the schema in your App. */
|
|
358
|
-
type BaseEventTypeMap = z.infer<typeof baseEventTypeMapSchema>;
|
|
359
|
-
|
|
360
363
|
/** HTTP methods supported from zod-openapi's PathItem shape (excluding helper 'id'). */
|
|
361
364
|
type MethodKey = keyof Omit<ZodOpenApiPathItemObject, 'id'>;
|
|
362
365
|
/**
|
|
@@ -462,13 +465,14 @@ interface AppInit<GlobalParamsSchema extends ZodObj, StageParamsSchema extends Z
|
|
|
462
465
|
* @returns a new App instance
|
|
463
466
|
*/
|
|
464
467
|
static create<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj>(init: AppInit<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>): App<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>;
|
|
468
|
+
static create<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj>(init: Omit<AppInit<GlobalParamsSchema, StageParamsSchema, typeof baseEventTypeMapSchema>, 'eventTypeMapSchema'> & {
|
|
469
|
+
eventTypeMapSchema?: undefined;
|
|
470
|
+
}): App<GlobalParamsSchema, StageParamsSchema, typeof baseEventTypeMapSchema>;
|
|
465
471
|
/**
|
|
466
472
|
* Register a function (HTTP or non‑HTTP).
|
|
467
473
|
*
|
|
468
474
|
* @typeParam EventType - A key from your eventTypeMapSchema (e.g., 'rest' | 'http' | 'sqs' | 'step')
|
|
469
|
-
* @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape)
|
|
470
|
-
* @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape)
|
|
471
|
-
* @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
|
|
475
|
+
* @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape) * @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape) * @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
|
|
472
476
|
* @returns a per‑function API: { handler(business), openapi(baseOperation), serverless(extras) }
|
|
473
477
|
*/
|
|
474
478
|
defineFunction<EventType extends Extract<keyof z.infer<EventTypeMapSchema>, string>, EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined>(options: {
|
|
@@ -499,6 +503,10 @@ interface AppInit<GlobalParamsSchema extends ZodObj, StageParamsSchema extends Z
|
|
|
499
503
|
cloudfront: aws_lambda.CloudFrontRequestEvent;
|
|
500
504
|
firehose: aws_lambda.FirehoseTransformationEvent;
|
|
501
505
|
'cognito-userpool': aws_lambda.CognitoUserPoolTriggerEvent;
|
|
506
|
+
step: {
|
|
507
|
+
[x: string]: unknown;
|
|
508
|
+
Payload?: unknown;
|
|
509
|
+
};
|
|
502
510
|
})[EventType]>) => (event: unknown, context: aws_lambda.Context) => Promise<ResponseSchema extends z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>> ? z.core.output<ResponseSchema> : unknown>;
|
|
503
511
|
openapi: (baseOperation: BaseOperation) => void;
|
|
504
512
|
serverless: (extras: unknown) => void;
|
|
@@ -562,7 +570,7 @@ interface EnvAttached<GlobalParamsSchema extends ZodObject<ZodRawShape>, StagePa
|
|
|
562
570
|
* type R = DeepOverride<A, B>;
|
|
563
571
|
*/
|
|
564
572
|
type DeepOverride<T, U> = [T] extends [never] ? U : [U] extends [never] ? T : T extends any[] ? U : U extends any[] ? U : T extends object ? U extends object ? {
|
|
565
|
-
[K in keyof
|
|
573
|
+
[K in keyof T | keyof U]: K extends keyof U ? DeepOverride<K extends keyof T ? T[K] : never, K extends keyof U ? U[K] : never> : K extends keyof T ? T[K] : never;
|
|
566
574
|
} : T : U;
|
|
567
575
|
|
|
568
576
|
/** Event type after applying deep schema overrides. */
|
package/dist/mjs/index.js
CHANGED
|
@@ -28,12 +28,23 @@ const baseEventTypeMapSchema = z.object({
|
|
|
28
28
|
firehose: z.custom(),
|
|
29
29
|
// eslint-disable-next-line @typescript-eslint/no-deprecated -- Upstream AWS types mark this as deprecated; we retain the token for compatibility with existing apps.
|
|
30
30
|
'cognito-userpool': z.custom(),
|
|
31
|
+
/**
|
|
32
|
+
* Step Functions → Lambda (Service Integration: Lambda Invoke)
|
|
33
|
+
*
|
|
34
|
+
* When Step Functions invokes Lambda via the AWS SDK integration
|
|
35
|
+
* (e.g., "arn:aws:states:::lambda:invoke"), the event received by the
|
|
36
|
+
* Lambda handler is an object that wraps the original input under a
|
|
37
|
+
* "Payload" key. The Payload is already parsed JSON.
|
|
38
|
+
*
|
|
39
|
+
* Notes:
|
|
40
|
+
* - We accept additional keys (e.g., StatusCode/ExecutedVersion in some
|
|
41
|
+
* patterns) via passthrough.
|
|
42
|
+
* - For the common “request/response” integration where Step Functions
|
|
43
|
+
* passes state directly, apps can still treat the event via their
|
|
44
|
+
* own app-local event map if needed.
|
|
45
|
+
*/
|
|
46
|
+
step: z.object({ Payload: z.unknown().optional() }).catchall(z.unknown()),
|
|
31
47
|
});
|
|
32
|
-
// Notes:
|
|
33
|
-
// - This list intentionally includes widely used, generic AWS events.
|
|
34
|
-
// - Apps can extend the schema with custom or specialized tokens:
|
|
35
|
-
// const EventMap = baseEventTypeMapSchema.extend({ step: z.custom<MyStepEvent>() })
|
|
36
|
-
// - Only tokens listed in your App's httpEventTypeTokens are treated as HTTP by the runtime.
|
|
37
48
|
|
|
38
49
|
/**
|
|
39
50
|
* Stage artifacts factory.
|
|
@@ -1041,10 +1052,10 @@ const buildAllServerlessFunctions = (registry, serverless, buildFnEnv) => {
|
|
|
1041
1052
|
/**
|
|
1042
1053
|
* App (schema‑first)
|
|
1043
1054
|
*
|
|
1055
|
+
* Overloads on create() preserve strong inference when eventTypeMapSchema is omitted.
|
|
1044
1056
|
* Central orchestrator for a SMOZ application. You provide:
|
|
1045
1057
|
* - Global/stage parameter schemas and env exposure keys
|
|
1046
|
-
* - Serverless defaults (handler filename/export and context map)
|
|
1047
|
-
* - Event‑type map schema (extendable: e.g., add 'step')
|
|
1058
|
+
* - Serverless defaults (handler filename/export and context map) * - Event‑type map schema (extendable: e.g., add 'step')
|
|
1048
1059
|
*
|
|
1049
1060
|
* The instance:
|
|
1050
1061
|
* - Validates configuration
|
|
@@ -1128,6 +1139,7 @@ const buildAllServerlessFunctions = (registry, serverless, buildFnEnv) => {
|
|
|
1128
1139
|
* @param init - initialization object (schemas, serverless defaults, params/envKeys)
|
|
1129
1140
|
* @returns a new App instance
|
|
1130
1141
|
*/
|
|
1142
|
+
// Implementation (must come after overload signatures)
|
|
1131
1143
|
static create(init) {
|
|
1132
1144
|
return new App(init);
|
|
1133
1145
|
}
|
|
@@ -1135,9 +1147,7 @@ const buildAllServerlessFunctions = (registry, serverless, buildFnEnv) => {
|
|
|
1135
1147
|
* Register a function (HTTP or non‑HTTP).
|
|
1136
1148
|
*
|
|
1137
1149
|
* @typeParam EventType - A key from your eventTypeMapSchema (e.g., 'rest' | 'http' | 'sqs' | 'step')
|
|
1138
|
-
* @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape)
|
|
1139
|
-
* @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape)
|
|
1140
|
-
* @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
|
|
1150
|
+
* @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape) * @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape) * @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
|
|
1141
1151
|
* @returns a per‑function API: { handler(business), openapi(baseOperation), serverless(extras) }
|
|
1142
1152
|
*/
|
|
1143
1153
|
defineFunction(options) {
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"url": "https://github.com/karmaniverous/smoz/issues"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@karmaniverous/get-dotenv": "^5.2.6",
|
|
16
17
|
"@middy/core": "^6.4.5",
|
|
17
18
|
"@middy/http-content-negotiation": "^6.4.5",
|
|
18
19
|
"@middy/http-cors": "^6.4.5",
|
|
@@ -23,57 +24,56 @@
|
|
|
23
24
|
"@middy/http-response-serializer": "^6.4.5",
|
|
24
25
|
"aws-lambda": "^1.0.7",
|
|
25
26
|
"chokidar": "^4.0.3",
|
|
26
|
-
"
|
|
27
|
-
"http-errors": "^2.0.0",
|
|
27
|
+
"http-errors": "^2.0.1",
|
|
28
28
|
"package-directory": "^8.1.0",
|
|
29
29
|
"radash": "^12.1.1",
|
|
30
|
-
"zod": "^4.1.
|
|
30
|
+
"zod": "^4.1.13"
|
|
31
31
|
},
|
|
32
32
|
"description": "John Galt Services back end.",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@dotenvx/dotenvx": "^1.
|
|
35
|
-
"@eslint/js": "^9.
|
|
36
|
-
"@rollup/plugin-alias": "^
|
|
37
|
-
"@rollup/plugin-typescript": "^12.
|
|
38
|
-
"@serverless/typescript": "^4.
|
|
39
|
-
"@types/aws-lambda": "^8.10.
|
|
34
|
+
"@dotenvx/dotenvx": "^1.51.1",
|
|
35
|
+
"@eslint/js": "^9.39.1",
|
|
36
|
+
"@rollup/plugin-alias": "^6.0.0",
|
|
37
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
38
|
+
"@serverless/typescript": "^4.23.0",
|
|
39
|
+
"@types/aws-lambda": "^8.10.159",
|
|
40
40
|
"@types/fs-extra": "^11.0.4",
|
|
41
41
|
"@types/http-errors": "^2.0.5",
|
|
42
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^24",
|
|
43
43
|
"@types/serverless": "^3.12.27",
|
|
44
|
-
"@vitest/coverage-v8": "^
|
|
44
|
+
"@vitest/coverage-v8": "^4.0.13",
|
|
45
45
|
"auto-changelog": "^2.5.0",
|
|
46
|
+
"eslint": "^9.39.1",
|
|
46
47
|
"eslint-config-prettier": "^10.1.8",
|
|
47
48
|
"eslint-plugin-prettier": "^5.5.4",
|
|
48
49
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"lefthook": "^1.13.0",
|
|
50
|
+
"fs-extra": "^11.3.2",
|
|
51
|
+
"knip": "^5.70.2",
|
|
52
|
+
"lefthook": "^2.0.4",
|
|
53
53
|
"prettier": "^3.6.2",
|
|
54
|
-
"release-it": "^19.0.
|
|
55
|
-
"rimraf": "^6.
|
|
54
|
+
"release-it": "^19.0.6",
|
|
55
|
+
"rimraf": "^6.1.2",
|
|
56
|
+
"rollup": "^4.53.3",
|
|
56
57
|
"rollup-plugin-dts": "^6.2.3",
|
|
57
|
-
"
|
|
58
|
+
"serverless": "^4.25.0",
|
|
58
59
|
"serverless-apigateway-log-retention": "^1.1.0",
|
|
59
60
|
"serverless-deployment-bucket": "^1.6.0",
|
|
60
61
|
"serverless-domain-manager": "^8.0.0",
|
|
61
62
|
"serverless-offline": "^14.4.0",
|
|
62
63
|
"serverless-plugin-common-excludes": "^4.0.0",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"typedoc-plugin-mdn-links": "^5.0.
|
|
64
|
+
"tsx": "^4.20.6",
|
|
65
|
+
"typedoc": "^0.28.14",
|
|
66
|
+
"typedoc-plugin-mdn-links": "^5.0.10",
|
|
66
67
|
"typedoc-plugin-replace-text": "^4.2.0",
|
|
67
|
-
"typedoc-plugin-zod": "^1.4.
|
|
68
|
-
"
|
|
69
|
-
"typescript-eslint": "^8.
|
|
70
|
-
"typescript": "^5.9.2",
|
|
68
|
+
"typedoc-plugin-zod": "^1.4.3",
|
|
69
|
+
"typescript": "^5.9.3",
|
|
70
|
+
"typescript-eslint": "^8.48.0",
|
|
71
71
|
"vite-tsconfig-paths": "^5.1.4",
|
|
72
|
-
"vitest": "^
|
|
73
|
-
"zod-openapi": "^5.4.
|
|
72
|
+
"vitest": "^4.0.13",
|
|
73
|
+
"zod-openapi": "^5.4.3"
|
|
74
74
|
},
|
|
75
75
|
"engines": {
|
|
76
|
-
"node": ">=22.19.0
|
|
76
|
+
"node": ">=22.19.0"
|
|
77
77
|
},
|
|
78
78
|
"exports": {
|
|
79
79
|
".": {
|
|
@@ -142,15 +142,15 @@
|
|
|
142
142
|
"npm run knip",
|
|
143
143
|
"npm run build"
|
|
144
144
|
],
|
|
145
|
-
"before:npm:release": [
|
|
146
|
-
"npx auto-changelog -p",
|
|
147
|
-
"npm run docs",
|
|
148
|
-
"git add -A"
|
|
149
|
-
],
|
|
150
145
|
"after:release": [
|
|
151
146
|
"git switch -c release/${version}",
|
|
152
147
|
"git push -u origin release/${version}",
|
|
153
148
|
"git switch ${branchName}"
|
|
149
|
+
],
|
|
150
|
+
"after:bump": [
|
|
151
|
+
"npx auto-changelog -p",
|
|
152
|
+
"npm run docs",
|
|
153
|
+
"git add CHANGELOG.md"
|
|
154
154
|
]
|
|
155
155
|
},
|
|
156
156
|
"npm": {
|
|
@@ -172,20 +172,19 @@
|
|
|
172
172
|
"knip": "knip",
|
|
173
173
|
"lint": "eslint .",
|
|
174
174
|
"lint:fix": "eslint --fix .",
|
|
175
|
-
"openapi": "tsx src/cli/index.ts register && tsx
|
|
176
|
-
"package": "
|
|
175
|
+
"openapi": "tsx src/cli/index.ts register && tsx src/cli/index.ts openapi",
|
|
176
|
+
"package": "serverless package",
|
|
177
177
|
"release": "dotenvx run -f .env.local -- release-it",
|
|
178
178
|
"release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.prerelease --preRelease",
|
|
179
179
|
"remove": "serverless remove",
|
|
180
180
|
"smoz": "tsx src/cli/index.ts",
|
|
181
|
-
"stan:docs": "typedoc --emit none",
|
|
182
181
|
"test": "vitest run",
|
|
183
182
|
"typecheck": "tsx src/cli/index.ts register && tsc -p tsconfig.json --noEmit",
|
|
184
183
|
"templates:typecheck": "tsx scripts/templates-typecheck.ts",
|
|
185
184
|
"templates:lint": "eslint --fix -c templates/default/eslint.config.ts \"templates/default/**/*.{ts,tsx,js,jsx}\" \"templates/default/eslint.config.ts\""
|
|
186
185
|
},
|
|
187
186
|
"type": "module",
|
|
188
|
-
"version": "0.2.
|
|
187
|
+
"version": "0.2.11",
|
|
189
188
|
"volta": {
|
|
190
189
|
"node": "22.19.0"
|
|
191
190
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"recommendations": [
|
|
3
|
-
"dbaeumer.vscode-eslint",
|
|
4
|
-
"esbenp.prettier-vscode",
|
|
5
|
-
"redhat.vscode-yaml",
|
|
6
|
-
"vitest.explorer"
|
|
7
|
-
]
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"recommendations": [
|
|
3
|
+
"dbaeumer.vscode-eslint",
|
|
4
|
+
"esbenp.prettier-vscode",
|
|
5
|
+
"redhat.vscode-yaml",
|
|
6
|
+
"vitest.explorer"
|
|
7
|
+
]
|
|
8
|
+
}
|
|
@@ -1,96 +1,98 @@
|
|
|
1
|
-
# SMOZ App Template
|
|
2
|
-
|
|
3
|
-
This template provides a minimal, convention‑friendly baseline for new SMOZ apps:
|
|
4
|
-
|
|
5
|
-
- TypeScript configuration (strict, moduleResolution bundler)
|
|
6
|
-
- ESLint (flat config) + typescript‑eslint + Prettier
|
|
7
|
-
- Vitest baseline config
|
|
8
|
-
- TypeDoc baseline config
|
|
9
|
-
|
|
10
|
-
## Conventions
|
|
11
|
-
|
|
12
|
-
- Author code lives under:
|
|
13
|
-
- `app/config/app.config.ts` — app schemas/config (params, env, http tokens)
|
|
14
|
-
- `app/functions/<eventType>/...` (e.g., `app/functions/rest/hello/get`)
|
|
15
|
-
- Generated artifacts live under:
|
|
16
|
-
- `app/generated/`
|
|
17
|
-
- `register.functions.ts` — side‑effect imports of all `lambda.ts`
|
|
18
|
-
- `register.openapi.ts` — side‑effect imports of all `openapi.ts`
|
|
19
|
-
- `register.serverless.ts` — side‑effect imports of per‑function `serverless.ts` (if any)
|
|
20
|
-
- `openapi.json` — OpenAPI document
|
|
21
|
-
|
|
22
|
-
## Getting started
|
|
23
|
-
|
|
24
|
-
1. Install dependencies
|
|
25
|
-
- Run: `npm install`
|
|
26
|
-
2. Type checking
|
|
27
|
-
- Run: `npm run typecheck`
|
|
28
|
-
3. Linting
|
|
29
|
-
- Run: `npm run lint` (or `npm run lint:fix` to auto‑fix)
|
|
30
|
-
4. Tests (baseline suite OK)
|
|
31
|
-
- Run: `npm run test`
|
|
32
|
-
5. Docs (TypeDoc baseline loads)
|
|
33
|
-
- Run: `npm run docs`
|
|
34
|
-
6. Generate OpenAPI (if your app config and endpoints are present)
|
|
35
|
-
- Run: `npm run openapi`
|
|
36
|
-
|
|
37
|
-
## SMOZ CLI — register
|
|
38
|
-
|
|
39
|
-
The CLI scans `app/functions/**` for `lambda.ts`, `openapi.ts`, and optional `serverless.ts` and generates side‑effect registration files under `app/generated/`.
|
|
40
|
-
|
|
41
|
-
- Build CLI (if packaged locally): `npm run cli:build`
|
|
42
|
-
- Register: `npx smoz register`
|
|
43
|
-
- Idempotent: rewrites files only when content changes
|
|
44
|
-
- Formats output with Prettier when available
|
|
45
|
-
|
|
46
|
-
Tip: Commit `app/generated/register.*.ts` so typecheck is stable without running the CLI. Teams often keep `app/generated/openapi.json` untracked in VCS (optional).
|
|
47
|
-
|
|
48
|
-
## Notes
|
|
49
|
-
|
|
50
|
-
- HTTP tokens (`rest`, `http`) are configured in your `app.config.ts`. You may widen these tokens per app.
|
|
51
|
-
- Keep function modules small and focused:
|
|
52
|
-
- `lambda.ts`: define and register function (`app.defineFunction`)
|
|
53
|
-
- `handler.ts`: business handler exported via `fn.handler`
|
|
54
|
-
- `openapi.ts`: attach OpenAPI operation via `fn.openapi`
|
|
55
|
-
- `serverless.ts`: (non‑HTTP only) attach extra events via `fn.serverless`
|
|
56
|
-
|
|
57
|
-
## Next steps
|
|
58
|
-
|
|
59
|
-
- Add your first endpoint (e.g., `app/functions/rest/hello/get`)
|
|
60
|
-
- Run the CLI register step
|
|
61
|
-
- Generate OpenAPI
|
|
62
|
-
- Package or deploy with your preferred toolchain
|
|
63
|
-
|
|
64
|
-
## Params used by serverless.ts
|
|
65
|
-
|
|
66
|
-
This template references a few params from your app config:
|
|
67
|
-
|
|
68
|
-
- Global params (app/config/app.config.ts → global.params)
|
|
69
|
-
- `ESB_MINIFY` (boolean) — controls `build.esbuild.minify`
|
|
70
|
-
- `ESB_SOURCEMAP` (boolean) — controls `build.esbuild.sourcemap`
|
|
71
|
-
- `PROFILE`, `REGION`, `SERVICE_NAME`
|
|
72
|
-
- Stage params (app/config/app.config.ts → stage.params.<stage>)
|
|
73
|
-
- `DOMAIN_NAME` — used by the custom domain plugin config
|
|
74
|
-
- `DOMAIN_CERTIFICATE_ARN` — ACM certificate ARN for the domain
|
|
75
|
-
- `STAGE`
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
1
|
+
# SMOZ App Template
|
|
2
|
+
|
|
3
|
+
This template provides a minimal, convention‑friendly baseline for new SMOZ apps:
|
|
4
|
+
|
|
5
|
+
- TypeScript configuration (strict, moduleResolution bundler)
|
|
6
|
+
- ESLint (flat config) + typescript‑eslint + Prettier
|
|
7
|
+
- Vitest baseline config
|
|
8
|
+
- TypeDoc baseline config
|
|
9
|
+
|
|
10
|
+
## Conventions
|
|
11
|
+
|
|
12
|
+
- Author code lives under:
|
|
13
|
+
- `app/config/app.config.ts` — app schemas/config (params, env, http tokens)
|
|
14
|
+
- `app/functions/<eventType>/...` (e.g., `app/functions/rest/hello/get`)
|
|
15
|
+
- Generated artifacts live under:
|
|
16
|
+
- `app/generated/`
|
|
17
|
+
- `register.functions.ts` — side‑effect imports of all `lambda.ts`
|
|
18
|
+
- `register.openapi.ts` — side‑effect imports of all `openapi.ts`
|
|
19
|
+
- `register.serverless.ts` — side‑effect imports of per‑function `serverless.ts` (if any)
|
|
20
|
+
- `openapi.json` — OpenAPI document
|
|
21
|
+
|
|
22
|
+
## Getting started
|
|
23
|
+
|
|
24
|
+
1. Install dependencies
|
|
25
|
+
- Run: `npm install`
|
|
26
|
+
2. Type checking
|
|
27
|
+
- Run: `npm run typecheck`
|
|
28
|
+
3. Linting
|
|
29
|
+
- Run: `npm run lint` (or `npm run lint:fix` to auto‑fix)
|
|
30
|
+
4. Tests (baseline suite OK)
|
|
31
|
+
- Run: `npm run test`
|
|
32
|
+
5. Docs (TypeDoc baseline loads)
|
|
33
|
+
- Run: `npm run docs`
|
|
34
|
+
6. Generate OpenAPI (if your app config and endpoints are present)
|
|
35
|
+
- Run: `npm run openapi`
|
|
36
|
+
|
|
37
|
+
## SMOZ CLI — register
|
|
38
|
+
|
|
39
|
+
The CLI scans `app/functions/**` for `lambda.ts`, `openapi.ts`, and optional `serverless.ts` and generates side‑effect registration files under `app/generated/`.
|
|
40
|
+
|
|
41
|
+
- Build CLI (if packaged locally): `npm run cli:build`
|
|
42
|
+
- Register: `npx smoz register`
|
|
43
|
+
- Idempotent: rewrites files only when content changes
|
|
44
|
+
- Formats output with Prettier when available
|
|
45
|
+
|
|
46
|
+
Tip: Commit `app/generated/register.*.ts` so typecheck is stable without running the CLI. Teams often keep `app/generated/openapi.json` untracked in VCS (optional).
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- HTTP tokens (`rest`, `http`) are configured in your `app.config.ts`. You may widen these tokens per app.
|
|
51
|
+
- Keep function modules small and focused:
|
|
52
|
+
- `lambda.ts`: define and register function (`app.defineFunction`)
|
|
53
|
+
- `handler.ts`: business handler exported via `fn.handler`
|
|
54
|
+
- `openapi.ts`: attach OpenAPI operation via `fn.openapi`
|
|
55
|
+
- `serverless.ts`: (non‑HTTP only) attach extra events via `fn.serverless`
|
|
56
|
+
|
|
57
|
+
## Next steps
|
|
58
|
+
|
|
59
|
+
- Add your first endpoint (e.g., `app/functions/rest/hello/get`)
|
|
60
|
+
- Run the CLI register step
|
|
61
|
+
- Generate OpenAPI
|
|
62
|
+
- Package or deploy with your preferred toolchain
|
|
63
|
+
|
|
64
|
+
## Params used by serverless.ts
|
|
65
|
+
|
|
66
|
+
This template references a few params from your app config:
|
|
67
|
+
|
|
68
|
+
- Global params (app/config/app.config.ts → global.params)
|
|
69
|
+
- `ESB_MINIFY` (boolean) — controls `build.esbuild.minify`
|
|
70
|
+
- `ESB_SOURCEMAP` (boolean) — controls `build.esbuild.sourcemap`
|
|
71
|
+
- `PROFILE`, `REGION`, `SERVICE_NAME`
|
|
72
|
+
- Stage params (app/config/app.config.ts → stage.params.<stage>)
|
|
73
|
+
- `DOMAIN_NAME` — used by the custom domain plugin config
|
|
74
|
+
- `DOMAIN_CERTIFICATE_ARN` — ACM certificate ARN for the domain
|
|
75
|
+
- `STAGE`
|
|
76
|
+
- `STAGE_NAME` — seeded as `${SERVICE_NAME}-${STAGE}` (not consumed yet)
|
|
77
|
+
|
|
78
|
+
Where these are used:
|
|
79
|
+
|
|
80
|
+
- The esbuild block in `serverless.ts` reads `ESB_MINIFY` and `ESB_SOURCEMAP`
|
|
81
|
+
to toggle minification and sourcemaps.
|
|
82
|
+
- The `customDomain` section in `serverless.ts` reads `DOMAIN_NAME` and
|
|
83
|
+
`DOMAIN_CERTIFICATE_ARN`. Update these with your values or remove the
|
|
84
|
+
custom domain plugin if not needed.
|
|
85
|
+
|
|
86
|
+
## Path hygiene (cross‑platform)
|
|
87
|
+
|
|
88
|
+
Windows uses backslashes in paths, which can leak into string comparisons and generated artifacts. Normalize separators consistently using the helper exported by the toolkit:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { toPosixPath } from '@karmaniverous/smoz';
|
|
92
|
+
|
|
93
|
+
// Derive the app root as the parent directory of app/config/
|
|
94
|
+
import { fileURLToPath } from 'node:url';
|
|
95
|
+
export const APP_ROOT_ABS = toPosixPath(
|
|
96
|
+
fileURLToPath(new URL('..', import.meta.url)),
|
|
97
|
+
);
|
|
98
|
+
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
|
|
4
|
-
import { App,
|
|
4
|
+
import { App, toPosixPath } from '@karmaniverous/smoz';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
// Derive the app root as the parent directory of app/config/
|
|
@@ -22,8 +22,8 @@ export const app = App.create({
|
|
|
22
22
|
DOMAIN_CERTIFICATE_ARN: z.string(),
|
|
23
23
|
DOMAIN_NAME: z.string(),
|
|
24
24
|
STAGE: z.string(),
|
|
25
|
+
STAGE_NAME: z.string(),
|
|
25
26
|
}),
|
|
26
|
-
eventTypeMapSchema: baseEventTypeMapSchema,
|
|
27
27
|
serverless: {
|
|
28
28
|
httpContextEventMap: {
|
|
29
29
|
my: {}, // place a Cognito authorizer here if needed
|
|
@@ -50,6 +50,7 @@ export const app = App.create({
|
|
|
50
50
|
'arn:aws:acm:us-east-1:000000000000:certificate/dev-placeholder',
|
|
51
51
|
DOMAIN_NAME: 'api.dev.example.test',
|
|
52
52
|
STAGE: 'dev',
|
|
53
|
+
STAGE_NAME: 'my-smoz-app-dev',
|
|
53
54
|
},
|
|
54
55
|
},
|
|
55
56
|
envKeys: ['STAGE'],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"openapi": "3.1.0",
|
|
3
|
-
"info": { "title": "smoz-app", "version": "0.0.0" },
|
|
4
|
-
"servers": [
|
|
5
|
-
{ "description": "Dev", "url": "http://localhost" }
|
|
6
|
-
],
|
|
7
|
-
"paths": {}
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": { "title": "smoz-app", "version": "0.0.0" },
|
|
4
|
+
"servers": [
|
|
5
|
+
{ "description": "Dev", "url": "http://localhost" }
|
|
6
|
+
],
|
|
7
|
+
"paths": {}
|
|
8
|
+
}
|