@karmaniverous/smoz 0.1.7 → 0.2.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 (51) hide show
  1. package/dist/cli/index.cjs +191 -59
  2. package/package.json +2 -2
  3. package/templates/default/.vscode/extensions.json +8 -0
  4. package/templates/default/.vscode/settings.json +23 -0
  5. package/templates/{minimal → default}/app/config/app.config.ts +50 -50
  6. package/templates/{minimal → default}/app/config/openapi.ts +45 -45
  7. package/templates/{full → default}/app/functions/rest/hello/get/handler.ts +18 -18
  8. package/templates/{full → default}/app/functions/rest/hello/get/lambda.ts +28 -28
  9. package/templates/{minimal → default}/app/functions/rest/hello/get/openapi.ts +23 -23
  10. package/templates/{minimal → default}/app/functions/rest/openapi/get/handler.ts +22 -22
  11. package/templates/{minimal → default}/app/functions/rest/openapi/get/lambda.ts +29 -29
  12. package/templates/{full → default}/app/functions/rest/openapi/get/openapi.ts +20 -20
  13. package/templates/{project → default}/eslint.config.ts +6 -15
  14. package/templates/default/package.json +44 -0
  15. package/templates/default/serverless.ts +113 -0
  16. package/templates/default/test/smoke.test.ts +7 -0
  17. package/templates/default/tsconfig.eslint.json +13 -0
  18. package/templates/default/tsdoc.json +46 -0
  19. package/templates/{minimal → default}/types/registers.d.ts +11 -11
  20. package/templates/.check/eslint.minimal.config.ts +0 -41
  21. package/templates/.check/eslint.templates.config.ts +0 -60
  22. package/templates/.check/tsconfig.eslintconfig.json +0 -6
  23. package/templates/.check/tsconfig.minimal.json +0 -14
  24. package/templates/.manifests/package.full.json +0 -21
  25. package/templates/.manifests/package.minimal.json +0 -19
  26. package/templates/.manifests/package.project.json +0 -23
  27. package/templates/full/app/config/app.config.ts +0 -50
  28. package/templates/full/app/config/openapi.ts +0 -44
  29. package/templates/full/app/functions/rest/hello/get/openapi.ts +0 -19
  30. package/templates/full/app/functions/rest/openapi/get/handler.ts +0 -20
  31. package/templates/full/app/functions/rest/openapi/get/lambda.ts +0 -29
  32. package/templates/full/app/functions/sqs/tick/handler.ts +0 -7
  33. package/templates/full/app/functions/sqs/tick/lambda.ts +0 -24
  34. package/templates/full/app/functions/sqs/tick/serverless.ts +0 -8
  35. package/templates/full/serverless.ts +0 -33
  36. package/templates/full/tsconfig.json +0 -25
  37. package/templates/full/types/registers.d.ts +0 -11
  38. package/templates/minimal/app/functions/rest/hello/get/handler.ts +0 -18
  39. package/templates/minimal/app/functions/rest/hello/get/lambda.ts +0 -28
  40. package/templates/minimal/app/functions/rest/openapi/get/openapi.ts +0 -20
  41. package/templates/minimal/app/generated/openapi.json +0 -8
  42. package/templates/minimal/serverless.ts +0 -34
  43. package/templates/minimal/tsconfig.json +0 -25
  44. /package/templates/{project → default}/.prettierrc.json +0 -0
  45. /package/templates/{project → default}/README.md +0 -0
  46. /package/templates/{full → default}/app/generated/openapi.json +0 -0
  47. /package/templates/{project → default}/gitignore +0 -0
  48. /package/templates/{project → default}/tsconfig.base.json +0 -0
  49. /package/templates/{project → default}/tsconfig.json +0 -0
  50. /package/templates/{project → default}/typedoc.json +0 -0
  51. /package/templates/{project → default}/vitest.config.ts +0 -0
@@ -1,28 +1,28 @@
1
- import { join } from 'node:path';
2
-
3
- import { toPosixPath } from '@karmaniverous/smoz';
4
- import { z } from 'zod';
5
-
6
- import { app, APP_ROOT_ABS } from '@/app/config/app.config';
7
-
8
- export const eventSchema = z.object({}).optional();
9
- export const responseSchema = z.object({ ok: z.boolean() });
10
- type FnApi = {
11
- handler: <T>(
12
- impl: () => Promise<T> | T,
13
- ) => (...args: unknown[]) => Promise<T>;
14
- openapi: (op: unknown) => void;
15
- };
16
-
17
- export const fn = app.defineFunction({
18
- functionName: 'hello_get',
19
- eventType: 'rest',
20
- httpContexts: ['public'],
21
- method: 'get',
22
- basePath: 'hello',
23
- contentType: 'application/json',
24
- eventSchema,
25
- responseSchema,
26
- callerModuleUrl: import.meta.url,
27
- endpointsRootAbs: toPosixPath(join(APP_ROOT_ABS, 'functions', 'rest')),
28
- }) as unknown as FnApi;
1
+ import { join } from 'node:path';
2
+
3
+ import { toPosixPath } from '@karmaniverous/smoz';
4
+ import { z } from 'zod';
5
+
6
+ import { app, APP_ROOT_ABS } from '@/app/config/app.config';
7
+
8
+ export const eventSchema = z.object({}).optional();
9
+ export const responseSchema = z.object({ ok: z.boolean() });
10
+ type FnApi = {
11
+ handler: <T>(
12
+ impl: () => Promise<T> | T,
13
+ ) => (...args: unknown[]) => Promise<T>;
14
+ openapi: (op: unknown) => void;
15
+ };
16
+
17
+ export const fn = app.defineFunction({
18
+ functionName: 'hello_get',
19
+ eventType: 'rest',
20
+ httpContexts: ['public'],
21
+ method: 'get',
22
+ basePath: 'hello',
23
+ contentType: 'application/json',
24
+ eventSchema,
25
+ responseSchema,
26
+ callerModuleUrl: import.meta.url,
27
+ endpointsRootAbs: toPosixPath(join(APP_ROOT_ABS, 'functions', 'rest')),
28
+ }) as unknown as FnApi;
@@ -1,23 +1,23 @@
1
- import { fn, responseSchema } from './lambda';
2
-
3
- type FnOpenApiApi = {
4
- openapi: (op: unknown) => void;
5
- };
6
-
7
- const reg = fn as unknown as FnOpenApiApi;
8
-
9
- reg.openapi({
10
- summary: 'Hello',
11
- description: 'Return a simple OK payload.',
12
- responses: {
13
- 200: {
14
- description: 'Ok',
15
- content: {
16
- 'application/json': { schema: responseSchema },
17
- },
18
- },
19
- },
20
- tags: ['public'],
21
- });
22
-
23
- export {};
1
+ import { fn, responseSchema } from './lambda';
2
+
3
+ type FnOpenApiApi = {
4
+ openapi: (op: unknown) => void;
5
+ };
6
+
7
+ const reg = fn as unknown as FnOpenApiApi;
8
+
9
+ reg.openapi({
10
+ summary: 'Hello',
11
+ description: 'Return a simple OK payload.',
12
+ responses: {
13
+ 200: {
14
+ description: 'Ok',
15
+ content: {
16
+ 'application/json': { schema: responseSchema },
17
+ },
18
+ },
19
+ },
20
+ tags: ['public'],
21
+ });
22
+
23
+ export {};
@@ -1,22 +1,22 @@
1
- import type { z } from 'zod';
2
-
3
- // Import the document from its real generated location.
4
- // The template ships a placeholder at app/generated/openapi.json.
5
- import openapiDoc from '@/app/generated/openapi.json';
6
-
7
- import type { responseSchema } from './lambda';
8
- import { fn } from './lambda';
9
-
10
- type Response = z.infer<typeof responseSchema>;
11
- type FnHandlerApi<T> = {
12
- handler: (impl: () => Promise<T> | T) => (...args: unknown[]) => Promise<T>;
13
- };
14
-
15
- const reg = fn as unknown as FnHandlerApi<Response>;
16
-
17
- export const handler = reg.handler(async () => {
18
- // Tip: run `npm run openapi` to regenerate this file.
19
- // Trivial await keeps parity with prior style.
20
- await Promise.resolve();
21
- return openapiDoc as Response;
22
- });
1
+ import type { z } from 'zod';
2
+
3
+ // Import the document from its real generated location.
4
+ // The template ships a placeholder at app/generated/openapi.json.
5
+ import openapiDoc from '@/app/generated/openapi.json';
6
+
7
+ import type { responseSchema } from './lambda';
8
+ import { fn } from './lambda';
9
+
10
+ type Response = z.infer<typeof responseSchema>;
11
+ type FnHandlerApi<T> = {
12
+ handler: (impl: () => Promise<T> | T) => (...args: unknown[]) => Promise<T>;
13
+ };
14
+
15
+ const reg = fn as unknown as FnHandlerApi<Response>;
16
+
17
+ export const handler = reg.handler(async () => {
18
+ // Tip: run `npm run openapi` to regenerate this file.
19
+ // Trivial await keeps parity with prior style.
20
+ await Promise.resolve();
21
+ return openapiDoc as Response;
22
+ });
@@ -1,29 +1,29 @@
1
- import { join } from 'node:path';
2
-
3
- import { toPosixPath } from '@karmaniverous/smoz';
4
- import { z } from 'zod';
5
-
6
- import { app, APP_ROOT_ABS } from '@/app/config/app.config';
7
-
8
- export const eventSchema = z.any().optional();
9
- export const responseSchema = z.unknown();
10
-
11
- type FnApi = {
12
- handler: <T>(
13
- impl: () => Promise<T> | T,
14
- ) => (...args: unknown[]) => Promise<T>;
15
- openapi: (op: unknown) => void;
16
- };
17
-
18
- export const fn = app.defineFunction({
19
- functionName: 'openapi_get',
20
- eventType: 'rest',
21
- httpContexts: ['public'],
22
- method: 'get',
23
- basePath: 'openapi',
24
- contentType: 'application/json',
25
- eventSchema,
26
- responseSchema,
27
- callerModuleUrl: import.meta.url,
28
- endpointsRootAbs: toPosixPath(join(APP_ROOT_ABS, 'functions', 'rest')),
29
- }) as unknown as FnApi;
1
+ import { join } from 'node:path';
2
+
3
+ import { toPosixPath } from '@karmaniverous/smoz';
4
+ import { z } from 'zod';
5
+
6
+ import { app, APP_ROOT_ABS } from '@/app/config/app.config';
7
+
8
+ export const eventSchema = z.any().optional();
9
+ export const responseSchema = z.unknown();
10
+
11
+ type FnApi = {
12
+ handler: <T>(
13
+ impl: () => Promise<T> | T,
14
+ ) => (...args: unknown[]) => Promise<T>;
15
+ openapi: (op: unknown) => void;
16
+ };
17
+
18
+ export const fn = app.defineFunction({
19
+ functionName: 'openapi_get',
20
+ eventType: 'rest',
21
+ httpContexts: ['public'],
22
+ method: 'get',
23
+ basePath: 'openapi',
24
+ contentType: 'application/json',
25
+ eventSchema,
26
+ responseSchema,
27
+ callerModuleUrl: import.meta.url,
28
+ endpointsRootAbs: toPosixPath(join(APP_ROOT_ABS, 'functions', 'rest')),
29
+ }) as unknown as FnApi;
@@ -1,20 +1,20 @@
1
- import { fn, responseSchema } from './lambda';
2
-
3
- type FnOpenApiApi = {
4
- openapi: (op: unknown) => void;
5
- };
6
-
7
- const reg = fn as unknown as FnOpenApiApi;
8
-
9
- reg.openapi({
10
- summary: 'Get OpenAPI document',
11
- description:
12
- 'Return the OpenAPI 3.1 document. Generate it via "npm run openapi".',
13
- responses: {
14
- 200: {
15
- description: 'OpenAPI document',
16
- content: { 'application/json': { schema: responseSchema } },
17
- },
18
- },
19
- tags: ['openapi'],
20
- });
1
+ import { fn, responseSchema } from './lambda';
2
+
3
+ type FnOpenApiApi = {
4
+ openapi: (op: unknown) => void;
5
+ };
6
+
7
+ const reg = fn as unknown as FnOpenApiApi;
8
+
9
+ reg.openapi({
10
+ summary: 'Get OpenAPI document',
11
+ description:
12
+ 'Return the OpenAPI 3.1 document. Generate it via "npm run openapi".',
13
+ responses: {
14
+ 200: {
15
+ description: 'OpenAPI document',
16
+ content: { 'application/json': { schema: responseSchema } },
17
+ },
18
+ },
19
+ tags: ['openapi'],
20
+ });
@@ -9,16 +9,6 @@ import { fileURLToPath } from 'url';
9
9
  const tsconfigRootDir = dirname(fileURLToPath(import.meta.url));
10
10
 
11
11
  export default [
12
- {
13
- ignores: [
14
- '.serverless/**',
15
- '.tsbuild/**',
16
- 'coverage/**',
17
- 'dist/**',
18
- 'docs/**',
19
- 'node_modules/**',
20
- ],
21
- },
22
12
  eslint.configs.recommended,
23
13
  ...tseslint.configs.strictTypeChecked,
24
14
  prettierConfig,
@@ -26,7 +16,7 @@ export default [
26
16
  languageOptions: {
27
17
  parser: tseslint.parser,
28
18
  parserOptions: {
29
- project: ['./tsconfig.json'],
19
+ project: ['./tsconfig.eslint.json'],
30
20
  tsconfigRootDir,
31
21
  },
32
22
  },
@@ -36,12 +26,13 @@ export default [
36
26
  },
37
27
  rules: {
38
28
  'prettier/prettier': 'error',
39
- '@typescript-eslint/consistent-type-imports': 'error',
40
- '@typescript-eslint/no-unused-expressions': 'off',
41
- '@typescript-eslint/no-unused-vars': 'error',
42
- 'no-unused-vars': 'off',
43
29
  'simple-import-sort/imports': 'error',
44
30
  'simple-import-sort/exports': 'error',
31
+ '@typescript-eslint/no-empty-object-type': 'off',
32
+ '@typescript-eslint/no-unused-vars': 'error',
33
+ '@typescript-eslint/no-unsafe-assignment': 'error',
34
+ '@typescript-eslint/no-unsafe-member-access': 'error',
35
+ '@typescript-eslint/no-unsafe-return': 'error',
45
36
  },
46
37
  },
47
38
  ];
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "smoz-template-default",
3
+ "private": true,
4
+ "type": "module",
5
+ "version": "0.0.0",
6
+ "dependencies": {
7
+ "@middy/core": "^6.4.5",
8
+ "zod": "^4.1.6"
9
+ },
10
+ "devDependencies": {
11
+ "@serverless/typescript": "^4.18.2",
12
+ "@types/node": "^22",
13
+ "eslint": "^9.35.0",
14
+ "eslint-config-prettier": "^10.1.8",
15
+ "eslint-plugin-prettier": "^5.5.4",
16
+ "eslint-plugin-simple-import-sort": "^12.1.1",
17
+ "jiti": "^2.5.1",
18
+ "prettier": "^3.6.2",
19
+ "serverless": "^4.18.2",
20
+ "serverless-apigateway-log-retention": "^1.1.0",
21
+ "serverless-deployment-bucket": "^1.6.0",
22
+ "serverless-domain-manager": "^8.0.0",
23
+ "serverless-offline": "^14.4.0",
24
+ "serverless-plugin-common-excludes": "^4.0.0",
25
+ "tsx": "^4.20.5",
26
+ "typedoc": "^0.28.12",
27
+ "typescript": "^5.9.2",
28
+ "typescript-eslint": "^8.43.0",
29
+ "vitest": "^3.2.4",
30
+ "zod-openapi": "^5.4.1"
31
+ },
32
+ "scripts": {
33
+ "register": "smoz register",
34
+ "openapi": "smoz register && tsx app/config/openapi && prettier -w app/generated/openapi.json",
35
+ "package": "smoz register && serverless package",
36
+ "dev": "smoz dev",
37
+ "dev:offline": "smoz dev --local offline",
38
+ "typecheck": "tsc -p tsconfig.json --noEmit",
39
+ "lint": "eslint .",
40
+ "lint:fix": "eslint --fix .",
41
+ "test": "vitest run",
42
+ "docs": "typedoc"
43
+ }
44
+ }
@@ -0,0 +1,113 @@
1
+ import type { AWS } from '@serverless/typescript';
2
+
3
+ import { app } from '@/app/config/app.config';
4
+ /**
5
+ * Template note:
6
+ * - Templates do NOT commit generated register files under app/generated; they
7
+ * are declared via ambient types (templates/minimal/types/registers.d.ts) so
8
+ * TypeScript can typecheck without artifacts.
9
+ * - To ensure side effects still run (endpoint/serverless registration) and to
10
+ * satisfy noUncheckedSideEffectImports, import register modules as namespaces
11
+ * and reference them via `void`.
12
+ * - In real apps, `smoz init` seeds placeholders and `smoz register` rewrites
13
+ * app/generated/register.*.ts at author time.
14
+ */
15
+ import * as __register_functions from '@/app/generated/register.functions';
16
+ import * as __register_serverless from '@/app/generated/register.serverless';
17
+ void __register_functions;
18
+ void __register_serverless;
19
+
20
+ const config: AWS = {
21
+ service: '${param:SERVICE_NAME}',
22
+ frameworkVersion: '4',
23
+ plugins: [
24
+ 'serverless-apigateway-log-retention',
25
+ 'serverless-deployment-bucket',
26
+ 'serverless-domain-manager',
27
+ 'serverless-plugin-common-excludes',
28
+ 'serverless-offline',
29
+ ],
30
+ package: {
31
+ individually: true,
32
+ patterns: ['!**/?(*.)test.+(!(.))'],
33
+ },
34
+ custom: {
35
+ apiGatewayLogRetention: {
36
+ accessLogging: {
37
+ enabled: true,
38
+ days: 5,
39
+ },
40
+ executionLogging: {
41
+ enabled: false,
42
+ },
43
+ },
44
+ customDomain: {
45
+ autoDomain: true,
46
+ basePath: '',
47
+ certificateArn: '${param:DOMAIN_CERTIFICATE_ARN}',
48
+ domainName: '${param:DOMAIN_NAME}',
49
+ preserveExternalPathMappings: true,
50
+ },
51
+ deploymentBucket: {
52
+ accelerate: true,
53
+ blockPublicAccess: true,
54
+ },
55
+ // Local emulation defaults (serverless-offline)
56
+ 'serverless-offline': {
57
+ httpPort: 3000,
58
+ noPrependStageInUrl: true,
59
+ },
60
+ },
61
+ stages: app.stages as NonNullable<AWS['stages']>,
62
+ provider: {
63
+ apiGateway: {
64
+ apiKeys: ['${param:SERVICE_NAME}-${param:STAGE}'],
65
+ disableDefaultEndpoint: true,
66
+ },
67
+ apiName: '${param:SERVICE_NAME}',
68
+ deploymentBucket: {
69
+ name: '${param:SERVICE_NAME}-deployment',
70
+ serverSideEncryption: 'AES256',
71
+ },
72
+ deploymentMethod: 'direct',
73
+ endpointType: 'edge',
74
+ environment: app.environment as NonNullable<AWS['provider']['environment']>,
75
+ iam: {
76
+ role: {
77
+ managedPolicies: [
78
+ 'arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy',
79
+ ],
80
+ statements: [{ Effect: 'Allow', Action: '*', Resource: '*' }],
81
+ },
82
+ },
83
+ logRetentionInDays: 5,
84
+ logs: {
85
+ lambda: { applicationLogLevel: 'DEBUG', logFormat: 'JSON' },
86
+ restApi: {
87
+ accessLogging: true,
88
+ executionLogging: false,
89
+ format:
90
+ '{ "accountId": "$context.accountId", "apiId": "$context.apiId", "domainName": "$context.domainName", "domainPrefix": "$context.domainPrefix", "error": { "message": "$context.error.message", "responseType": "$context.error.responseType" }, "extendedRequestId": "$context.extendedRequestId", "httpMethod": "$context.httpMethod", "identity" { "accountId": "$context.identity.accountId", "apiKey": "$context.identity.apiKey", "caller": "$context.identity.caller", "clientCert": { "clientCertPem": "$context.identity.clientCert.clientCertPem", "subjectDN": "$context.identity.clientCert.subjectDN", "issuerDN": "$context.identity.clientCert.issuerDN", "serialNumber": "$context.identity.clientCert.serialNumber", "validity": { "notBefore": "$context.identity.clientCert.validity.notBefore", "notAfter": "$context.identity.clientCert.validity.notAfter" } }, "sourceIp": "$context.identity.sourceIp", "user": "$context.identity.user", "userArn": "$context.identity.userArn", "userAgent": "$context.identity.userAgent", }, "integration": { "latency": "$context.integration.latency" }, "path": "$context.path", "protocol": "$context.protocol", "requestId": "$context.requestId", "requestTime": "$context.requestTime", "requestTimeEpoch": "$context.requestTimeEpoch", "resourceId": "$context.resourceId", "resourcePath": "$context.resourcePath", "stage": "$context.stage", "responseLatency": "$context.responseLatency", "responseLength": "$context.responseLength", "status": "$context.status" }',
91
+ },
92
+ },
93
+ memorySize: 256,
94
+ name: 'aws',
95
+ region: '${param:REGION}' as NonNullable<AWS['provider']['region']>,
96
+ runtime: 'nodejs22.x',
97
+ profile: '${param:PROFILE}',
98
+ stackName: '${param:SERVICE_NAME}-${param:STAGE}',
99
+ stackTags: {
100
+ service: '${param:SERVICE_NAME}',
101
+ stage: '${param:STAGE}',
102
+ },
103
+ stage: '${opt:stage, "dev"}',
104
+ tracing: {
105
+ apiGateway: true,
106
+ lambda: true,
107
+ },
108
+ versionFunctions: false,
109
+ },
110
+ functions: app.buildAllServerlessFunctions() as NonNullable<AWS['functions']>,
111
+ };
112
+
113
+ export default config;
@@ -0,0 +1,7 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ describe('template smoke', () => {
4
+ it('runs vitest', () => {
5
+ expect(1 + 1).toBe(2);
6
+ });
7
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "paths": {
6
+ "@/*": ["./*"],
7
+ "@karmaniverous/smoz": [
8
+ "../../.stan/dist/index.d.ts",
9
+ "../../dist/index.d.ts"
10
+ ]
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
3
+ "noStandardTags": false,
4
+ "tagDefinitions": [
5
+ { "tagName": "@author", "syntaxKind": "block" },
6
+ { "tagName": "@module", "syntaxKind": "block" },
7
+ { "tagName": "@type", "syntaxKind": "block" },
8
+ { "tagName": "@typedef", "syntaxKind": "block" },
9
+ { "tagName": "@callback", "syntaxKind": "block" },
10
+ { "tagName": "@prop", "syntaxKind": "block", "allowMultiple": true },
11
+ { "tagName": "@property", "syntaxKind": "block", "allowMultiple": true },
12
+ { "tagName": "@group", "syntaxKind": "block", "allowMultiple": true },
13
+ { "tagName": "@groupDescription", "syntaxKind": "block", "allowMultiple": true },
14
+ { "tagName": "@category", "syntaxKind": "block", "allowMultiple": true },
15
+ { "tagName": "@categoryDescription", "syntaxKind": "block", "allowMultiple": true },
16
+ { "tagName": "@hidden", "syntaxKind": "modifier" },
17
+ { "tagName": "@ignore", "syntaxKind": "modifier" },
18
+ { "tagName": "@class", "syntaxKind": "modifier" },
19
+ { "tagName": "@document", "syntaxKind": "block" },
20
+ { "tagName": "@default", "syntaxKind": "block" },
21
+ { "tagName": "@extends", "syntaxKind": "block" },
22
+ { "tagName": "@augments", "syntaxKind": "block" },
23
+ { "tagName": "@return", "syntaxKind": "block" },
24
+ { "tagName": "@yields", "syntaxKind": "block" },
25
+ { "tagName": "@enum", "syntaxKind": "modifier" },
26
+ { "tagName": "@event", "syntaxKind": "modifier" },
27
+ { "tagName": "@template", "syntaxKind": "block", "allowMultiple": true },
28
+ { "tagName": "@linkcode", "syntaxKind": "inline", "allowMultiple": true },
29
+ { "tagName": "@linkplain", "syntaxKind": "inline", "allowMultiple": true },
30
+ { "tagName": "@private", "syntaxKind": "modifier" },
31
+ { "tagName": "@protected", "syntaxKind": "modifier" },
32
+ { "tagName": "@satisfies", "syntaxKind": "block" },
33
+ { "tagName": "@since", "syntaxKind": "block" },
34
+ { "tagName": "@license", "syntaxKind": "block" },
35
+ { "tagName": "@import", "syntaxKind": "block" },
36
+ { "tagName": "@overload", "syntaxKind": "modifier" },
37
+ { "tagName": "@namespace", "syntaxKind": "modifier" },
38
+ { "tagName": "@interface", "syntaxKind": "modifier" },
39
+ { "tagName": "@showCategories", "syntaxKind": "modifier" },
40
+ { "tagName": "@hideCategories", "syntaxKind": "modifier" },
41
+ { "tagName": "@showGroups", "syntaxKind": "modifier" },
42
+ { "tagName": "@hideGroups", "syntaxKind": "modifier" },
43
+ { "tagName": "@hideconstructor", "syntaxKind": "modifier" },
44
+ { "tagName": "@jsx", "syntaxKind": "block" }
45
+ ]
46
+ }
@@ -1,11 +1,11 @@
1
- // Ambient declarations to satisfy template typechecking without requiring
2
- // generated register files to exist on disk.
3
- declare module '@/app/generated/register.functions' {
4
- export {};
5
- }
6
- declare module '@/app/generated/register.openapi' {
7
- export {};
8
- }
9
- declare module '@/app/generated/register.serverless' {
10
- export {};
11
- }
1
+ // Ambient declarations to satisfy template typechecking without requiring
2
+ // generated register files to exist on disk.
3
+ declare module '@/app/generated/register.functions' {
4
+ export {};
5
+ }
6
+ declare module '@/app/generated/register.openapi' {
7
+ export {};
8
+ }
9
+ declare module '@/app/generated/register.serverless' {
10
+ export {};
11
+ }
@@ -1,41 +0,0 @@
1
- import eslint from '@eslint/js';
2
- import prettierConfig from 'eslint-config-prettier';
3
- import prettierPlugin from 'eslint-plugin-prettier';
4
- import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
5
- import tseslint from 'typescript-eslint';
6
- import { dirname } from 'path';
7
- import { fileURLToPath } from 'url';
8
-
9
- const tsconfigRootDir = dirname(fileURLToPath(import.meta.url));
10
-
11
- export default tseslint.config(
12
- { ignores: [
13
- '**/node_modules/**',
14
- '**/dist/**',
15
- '**/.tsbuild/**',
16
- ],
17
- },
18
- eslint.configs.recommended,
19
- tseslint.configs.strictTypeChecked,
20
- prettierConfig,
21
- {
22
- languageOptions: {
23
- parser: tseslint.parser,
24
- parserOptions: {
25
- project: ['./tsconfig.minimal.json'],
26
- tsconfigRootDir,
27
- },
28
- },
29
- plugins: { prettier: prettierPlugin,
30
- 'simple-import-sort': simpleImportSortPlugin,
31
- },
32
- rules: {
33
- '@typescript-eslint/consistent-type-imports': 'error',
34
- '@typescript-eslint/no-unused-expressions': 'off',
35
- '@typescript-eslint/no-unused-vars': 'error',
36
- 'no-unused-vars': 'off',
37
- 'simple-import-sort/imports': 'error',
38
- 'simple-import-sort/exports': 'error',
39
- },
40
- },
41
- );
@@ -1,60 +0,0 @@
1
- import eslint from '@eslint/js';
2
- import prettierConfig from 'eslint-config-prettier';
3
- import prettierPlugin from 'eslint-plugin-prettier';
4
- import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
5
- import { dirname } from 'path';
6
- import tseslint from 'typescript-eslint';
7
- import { fileURLToPath } from 'url';
8
-
9
- // Unified ESLint config for all templates under templates/*
10
- // - Uses projectService so type info is picked up from each template's tsconfig.json
11
- // - ESLint drives Prettier via 'prettier/prettier': 'error'
12
- const tsconfigRootDir = dirname(fileURLToPath(import.meta.url));
13
-
14
- export default [
15
- {
16
- ignores: [
17
- '**/node_modules/**',
18
- '**/dist/**',
19
- '**/.tsbuild/**',
20
- '**/generated/**',
21
- '**/.check/**',
22
- ],
23
- },
24
- eslint.configs.recommended,
25
- ...tseslint.configs.strictTypeChecked,
26
- prettierConfig,
27
- {
28
- languageOptions: {
29
- parser: tseslint.parser,
30
- parserOptions: {
31
- // Let the project service discover the nearest tsconfig.json per file
32
- // (typed where possible; falls back to default project when unmatched).
33
- project: true,
34
- projectService: true,
35
- allowDefaultProject: true,
36
- tsconfigRootDir,
37
- },
38
- },
39
- plugins: {
40
- prettier: prettierPlugin,
41
- 'simple-import-sort': simpleImportSortPlugin,
42
- },
43
- rules: {
44
- // Formatting via Prettier
45
- 'prettier/prettier': 'error',
46
- // Code-quality and sorting
47
- '@typescript-eslint/consistent-type-imports': 'error',
48
- '@typescript-eslint/no-empty-object-type': 'off',
49
- '@typescript-eslint/no-unused-expressions': 'off',
50
- '@typescript-eslint/no-unused-vars': 'error',
51
- 'no-unused-vars': 'off',
52
- 'simple-import-sort/imports': 'error',
53
- 'simple-import-sort/exports': 'error',
54
- // Keep strictness reasonable for templates
55
- '@typescript-eslint/no-unsafe-assignment': 'error',
56
- '@typescript-eslint/no-unsafe-member-access': 'error',
57
- '@typescript-eslint/no-unsafe-return': 'error',
58
- },
59
- },
60
- ];
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "../project/tsconfig.base.json",
3
- "include": [
4
- "./eslint.templates.config.ts"
5
- ]
6
- }