@friggframework/schemas 2.0.0-next.123 → 2.0.0-next.125
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/README.md +26 -0
- package/app-definition.js +113 -0
- package/index.js +13 -1
- package/package.json +3 -2
- package/schemas/app-definition.schema.json +534 -165
package/README.md
CHANGED
|
@@ -41,6 +41,32 @@ if (result.valid) {
|
|
|
41
41
|
}
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
### Integration classes and defaults (ADR-051)
|
|
45
|
+
|
|
46
|
+
Apps list integration classes, which JSON Schema cannot describe.
|
|
47
|
+
`validateAppDefinition` validates a view of the definition in which each
|
|
48
|
+
class in `integrations`, `adminScripts` and `reports` is replaced by
|
|
49
|
+
`{ Definition }`; `frigg validate` checks the classes themselves.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
const { applyAppDefinitionDefaults } = require('@friggframework/schemas');
|
|
53
|
+
// or, without loading Ajv:
|
|
54
|
+
// require('@friggframework/schemas/app-definition').applyAppDefinitionDefaults
|
|
55
|
+
|
|
56
|
+
const definition = applyAppDefinitionDefaults(require('./index').Definition);
|
|
57
|
+
definition.user.individualUserRequired; // true (schema default)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`applyAppDefinitionDefaults` returns a copy with every `default` declared in
|
|
61
|
+
the app-definition schema applied (only inside blocks the app sets, plus
|
|
62
|
+
blocks that have a default themselves, such as `user`). core's
|
|
63
|
+
`loadAppDefinition` and devtools' `createFriggInfrastructure` call it, so a
|
|
64
|
+
schema default is the runtime default. A schema default must equal what the
|
|
65
|
+
code does when the key is absent; the contract test in
|
|
66
|
+
`packages/devtools/infrastructure/app-definition-schema-contract.test.js`
|
|
67
|
+
checks this for the infrastructure builders. Keys nothing reads are marked
|
|
68
|
+
`"deprecated": true`.
|
|
69
|
+
|
|
44
70
|
### Advanced Validation
|
|
45
71
|
|
|
46
72
|
```javascript
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App definition helpers shared by the runtime (core) and the tooling
|
|
3
|
+
* (devtools, frigg CLI). See ADR-051.
|
|
4
|
+
*
|
|
5
|
+
* This file loads only the JSON schema, not Ajv, so the runtime can apply
|
|
6
|
+
* the schema defaults at cold start without compiling a validator.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const appDefinitionSchema = require('./schemas/app-definition.schema.json');
|
|
10
|
+
|
|
11
|
+
function isPlainObject(value) {
|
|
12
|
+
if (value === null || typeof value !== 'object') return false;
|
|
13
|
+
const proto = Object.getPrototypeOf(value);
|
|
14
|
+
return proto === Object.prototype || proto === null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function cloneDefault(value) {
|
|
18
|
+
// Schema defaults are JSON values: a JSON round trip copies them fully.
|
|
19
|
+
return value === undefined ? value : JSON.parse(JSON.stringify(value));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Copy plain objects and arrays, keep everything else (classes, functions,
|
|
24
|
+
* instances) by reference.
|
|
25
|
+
*/
|
|
26
|
+
function clonePlain(value) {
|
|
27
|
+
if (Array.isArray(value)) return value.map(clonePlain);
|
|
28
|
+
if (isPlainObject(value)) {
|
|
29
|
+
const copy = {};
|
|
30
|
+
for (const [key, inner] of Object.entries(value)) {
|
|
31
|
+
copy[key] = clonePlain(inner);
|
|
32
|
+
}
|
|
33
|
+
return copy;
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function applyDefaultsInPlace(schema, data) {
|
|
39
|
+
if (!schema || !isPlainObject(data)) return;
|
|
40
|
+
const properties = schema.properties || {};
|
|
41
|
+
for (const [key, propertySchema] of Object.entries(properties)) {
|
|
42
|
+
if (data[key] === undefined && propertySchema.default !== undefined) {
|
|
43
|
+
data[key] = cloneDefault(propertySchema.default);
|
|
44
|
+
}
|
|
45
|
+
if (isPlainObject(data[key]) && propertySchema.properties) {
|
|
46
|
+
applyDefaultsInPlace(propertySchema, data[key]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Return a copy of the app definition with every `default` that the
|
|
53
|
+
* app-definition schema declares applied, the way Ajv `useDefaults` does:
|
|
54
|
+
* only for properties of objects that exist (a block the app leaves out is
|
|
55
|
+
* not created unless the block itself has a default, as `user` does). It
|
|
56
|
+
* also copies the deprecated `user.password` into `user.usePassword` when
|
|
57
|
+
* only the old spelling is set. Classes and other non-plain values are kept by reference.
|
|
58
|
+
* The input is not mutated, and the function is idempotent.
|
|
59
|
+
*
|
|
60
|
+
* This is the only place schema defaults are applied. core's
|
|
61
|
+
* loadAppDefinition and devtools' createFriggInfrastructure both call it,
|
|
62
|
+
* so a default in the schema is a default at runtime.
|
|
63
|
+
*
|
|
64
|
+
* @param {object} definition the `Definition` exported by the backend
|
|
65
|
+
* @returns {object} the definition with defaults applied
|
|
66
|
+
*/
|
|
67
|
+
function applyAppDefinitionDefaults(definition) {
|
|
68
|
+
if (!isPlainObject(definition)) return definition;
|
|
69
|
+
const copy = clonePlain(definition);
|
|
70
|
+
// user.password is the deprecated spelling of user.usePassword.
|
|
71
|
+
if (
|
|
72
|
+
isPlainObject(copy.user) &&
|
|
73
|
+
copy.user.usePassword === undefined &&
|
|
74
|
+
typeof copy.user.password === 'boolean'
|
|
75
|
+
) {
|
|
76
|
+
copy.user.usePassword = copy.user.password;
|
|
77
|
+
}
|
|
78
|
+
applyDefaultsInPlace(appDefinitionSchema, copy);
|
|
79
|
+
return copy;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Keys whose entries are classes with a static Definition.
|
|
83
|
+
const CLASS_LIST_KEYS = ['integrations', 'adminScripts', 'reports'];
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* JSON Schema cannot describe a JavaScript class, and apps list integration
|
|
87
|
+
* (and admin script, and report) classes. Validators therefore check this serialisable view, in which each
|
|
88
|
+
* class is replaced by `{ Definition }` (its static Definition). The schema
|
|
89
|
+
* describes that view; `frigg validate` checks the Definition itself.
|
|
90
|
+
*
|
|
91
|
+
* @param {object} definition the `Definition` exported by the backend
|
|
92
|
+
* @returns {object} a shallow copy with the class lists mapped to views
|
|
93
|
+
*/
|
|
94
|
+
function toAppDefinitionSchemaView(definition) {
|
|
95
|
+
if (!isPlainObject(definition)) return definition;
|
|
96
|
+
const view = { ...definition };
|
|
97
|
+
for (const key of CLASS_LIST_KEYS) {
|
|
98
|
+
if (Array.isArray(definition[key])) {
|
|
99
|
+
view[key] = definition[key].map((entry) =>
|
|
100
|
+
typeof entry === 'function'
|
|
101
|
+
? { Definition: entry.Definition }
|
|
102
|
+
: entry
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return view;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
applyAppDefinitionDefaults,
|
|
111
|
+
toAppDefinitionSchemaView,
|
|
112
|
+
appDefinitionSchema,
|
|
113
|
+
};
|
package/index.js
CHANGED
|
@@ -12,6 +12,10 @@ const path = require('path');
|
|
|
12
12
|
|
|
13
13
|
// Import middleware
|
|
14
14
|
const schemaValidationMiddleware = require('./middleware/schema-validation');
|
|
15
|
+
const {
|
|
16
|
+
applyAppDefinitionDefaults,
|
|
17
|
+
toAppDefinitionSchemaView,
|
|
18
|
+
} = require('./app-definition');
|
|
15
19
|
|
|
16
20
|
// Initialize AJV with formats
|
|
17
21
|
const ajv = new Ajv({
|
|
@@ -76,7 +80,13 @@ function validate(schemaName, data) {
|
|
|
76
80
|
* @returns {object} - Validation result
|
|
77
81
|
*/
|
|
78
82
|
function validateAppDefinition(appDefinition) {
|
|
79
|
-
|
|
83
|
+
// Apps list integration classes, which JSON Schema cannot describe:
|
|
84
|
+
// validate the serialisable view and return the original definition.
|
|
85
|
+
const result = validate(
|
|
86
|
+
'app-definition',
|
|
87
|
+
toAppDefinitionSchemaView(appDefinition)
|
|
88
|
+
);
|
|
89
|
+
return { ...result, data: appDefinition };
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
/**
|
|
@@ -357,6 +367,8 @@ module.exports = {
|
|
|
357
367
|
// Validation functions
|
|
358
368
|
validate,
|
|
359
369
|
validateAppDefinition,
|
|
370
|
+
applyAppDefinitionDefaults,
|
|
371
|
+
toAppDefinitionSchemaView,
|
|
360
372
|
validateIntegrationDefinition,
|
|
361
373
|
validateApiModuleDefinition,
|
|
362
374
|
validateServerlessConfig,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/schemas",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.125",
|
|
4
4
|
"description": "Canonical JSON Schema definitions for Frigg Framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"validators/",
|
|
40
40
|
"mocks/",
|
|
41
41
|
"middleware/",
|
|
42
|
+
"app-definition.js",
|
|
42
43
|
"index.js"
|
|
43
44
|
],
|
|
44
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "a64e5964dd1a945ce6439df062d79d637d861caf"
|
|
45
46
|
}
|
|
@@ -22,22 +22,35 @@
|
|
|
22
22
|
},
|
|
23
23
|
"label": {
|
|
24
24
|
"type": "string",
|
|
25
|
-
"description": "Human-readable display name for the application",
|
|
25
|
+
"description": "Human-readable display name for the application. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
26
26
|
"minLength": 1,
|
|
27
27
|
"maxLength": 200,
|
|
28
|
-
"examples": ["My Frigg Application", "Customer Portal Integrations"]
|
|
28
|
+
"examples": ["My Frigg Application", "Customer Portal Integrations"],
|
|
29
|
+
"deprecated": true
|
|
30
|
+
},
|
|
31
|
+
"region": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "AWS region. The deploy region comes from AWS_REGION (default us-east-1), not from this key. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
34
|
+
"deprecated": true
|
|
35
|
+
},
|
|
36
|
+
"stage": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Stage name used only to infer the KMS key alias. The deployed stage comes from `--stage`."
|
|
29
39
|
},
|
|
30
40
|
"managementMode": {
|
|
31
41
|
"type": "string",
|
|
32
|
-
"description": "Infrastructure management mode
|
|
33
|
-
"enum": ["managed", "discover", "custom"]
|
|
34
|
-
"default": "managed"
|
|
42
|
+
"description": "Infrastructure management mode. 'managed': Frigg creates and owns the VPC, database and KMS key it needs (with vpcIsolation 'isolated', per stage). 'existing': use existing resources given by id. 'discover' (also the behaviour when omitted): find existing resources and create what is missing. 'custom' is accepted for compatibility and behaves like 'discover'.",
|
|
43
|
+
"enum": ["managed", "discover", "existing", "custom"]
|
|
35
44
|
},
|
|
36
45
|
"vpcIsolation": {
|
|
37
46
|
"type": "string",
|
|
38
|
-
"description": "
|
|
39
|
-
"enum": ["isolated", "shared"]
|
|
40
|
-
|
|
47
|
+
"description": "With managementMode 'managed': 'isolated' gives each stage its own VPC, database and key; 'shared' reuses them across stages. Set it explicitly: when it is omitted the builders do not agree on a default (see ADR-051).",
|
|
48
|
+
"enum": ["isolated", "shared"]
|
|
49
|
+
},
|
|
50
|
+
"usePrismaLambdaLayer": {
|
|
51
|
+
"type": "boolean",
|
|
52
|
+
"description": "Ship Prisma in a shared Lambda layer. false bundles Prisma into each function instead.",
|
|
53
|
+
"default": true
|
|
41
54
|
},
|
|
42
55
|
"environment": {
|
|
43
56
|
"type": "object",
|
|
@@ -68,93 +81,72 @@
|
|
|
68
81
|
},
|
|
69
82
|
"integrations": {
|
|
70
83
|
"type": "array",
|
|
71
|
-
"description": "
|
|
84
|
+
"description": "The IntegrationBase subclasses this application exposes. JSON Schema cannot describe a JavaScript class, so validateAppDefinition checks a serialisable view in which each class is replaced by { Definition: <its static Definition> }; `frigg validate` checks each Definition structurally (name, version, modules and their API module definitions).",
|
|
72
85
|
"items": {
|
|
73
86
|
"type": "object",
|
|
74
|
-
"description": "
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"items": {
|
|
82
|
-
"description": "Admin script class"
|
|
83
|
-
},
|
|
84
|
-
"default": []
|
|
85
|
-
},
|
|
86
|
-
"reports": {
|
|
87
|
-
"type": "array",
|
|
88
|
-
"description": "Report classes served by the admin report runner",
|
|
89
|
-
"items": {
|
|
90
|
-
"description": "Report class"
|
|
91
|
-
},
|
|
92
|
-
"default": []
|
|
93
|
-
},
|
|
94
|
-
"admin": {
|
|
95
|
-
"type": "object",
|
|
96
|
-
"description": "Admin script and report runner options",
|
|
97
|
-
"properties": {
|
|
98
|
-
"enableScheduling": {
|
|
99
|
-
"type": "boolean",
|
|
100
|
-
"description": "Provision the EventBridge Scheduler group and role so admin scripts and reports can run on a schedule",
|
|
101
|
-
"default": false
|
|
102
|
-
},
|
|
103
|
-
"includeBuiltinReports": {
|
|
104
|
-
"type": "boolean",
|
|
105
|
-
"description": "Serve the built-in reports alongside the app's own reports",
|
|
106
|
-
"default": false
|
|
87
|
+
"description": "An integration class, seen as { Definition } (see the integrations description)",
|
|
88
|
+
"required": ["Definition"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"Definition": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"description": "The integration's static Definition (see integration-definition.schema.json)"
|
|
93
|
+
}
|
|
107
94
|
}
|
|
108
95
|
},
|
|
109
|
-
"
|
|
96
|
+
"default": []
|
|
110
97
|
},
|
|
111
98
|
"user": {
|
|
112
99
|
"type": "object",
|
|
113
|
-
"description": "User management and authentication
|
|
100
|
+
"description": "User management and authentication. Read by core when it loads the app definition; an omitted block gets the defaults below (ADR-051).",
|
|
114
101
|
"properties": {
|
|
115
102
|
"usePassword": {
|
|
116
103
|
"type": "boolean",
|
|
117
|
-
"description": "
|
|
118
|
-
"default":
|
|
104
|
+
"description": "Users log in with username and password (POST /user/login). false: users are identified by appUserId (x-frigg-appuserid) instead.",
|
|
105
|
+
"default": false
|
|
119
106
|
},
|
|
120
107
|
"password": {
|
|
121
108
|
"type": "boolean",
|
|
122
|
-
"description": "DEPRECATED:
|
|
123
|
-
"
|
|
109
|
+
"description": "DEPRECATED alias of usePassword: when usePassword is not set, the loader copies this value into it.",
|
|
110
|
+
"deprecated": true
|
|
124
111
|
},
|
|
125
112
|
"primary": {
|
|
126
113
|
"type": "string",
|
|
127
|
-
"description": "Primary user type
|
|
114
|
+
"description": "Primary user type. Any value other than 'organization' is treated as 'individual'.",
|
|
128
115
|
"enum": ["individual", "organization"],
|
|
129
116
|
"default": "individual"
|
|
130
117
|
},
|
|
131
118
|
"individualUserRequired": {
|
|
132
119
|
"type": "boolean",
|
|
133
|
-
"description": "Require individual user
|
|
120
|
+
"description": "Require an individual user. POST /user/login logs in individual users only when this is true.",
|
|
134
121
|
"default": true
|
|
135
122
|
},
|
|
136
123
|
"organizationUserRequired": {
|
|
137
124
|
"type": "boolean",
|
|
138
|
-
"description": "Require organization user
|
|
125
|
+
"description": "Require an organization user (looked up by appOrgId).",
|
|
126
|
+
"default": false
|
|
127
|
+
},
|
|
128
|
+
"strictUserValidation": {
|
|
129
|
+
"type": "boolean",
|
|
130
|
+
"description": "With x-frigg headers, reject a user id that does not exist instead of creating and linking it.",
|
|
139
131
|
"default": false
|
|
140
132
|
},
|
|
141
133
|
"authModes": {
|
|
142
134
|
"type": "object",
|
|
143
|
-
"description": "Authentication
|
|
135
|
+
"description": "Authentication modes. When the block is omitted, Frigg tokens and the shared secret are accepted. x-frigg-appUserId and x-frigg-appOrgId headers identify the user with any mode.",
|
|
144
136
|
"properties": {
|
|
145
137
|
"friggToken": {
|
|
146
138
|
"type": "boolean",
|
|
147
|
-
"description": "
|
|
139
|
+
"description": "Accept Frigg bearer tokens from /user/login. Enabled unless false.",
|
|
148
140
|
"default": true
|
|
149
141
|
},
|
|
150
142
|
"sharedSecret": {
|
|
151
143
|
"type": "boolean",
|
|
152
|
-
"description": "
|
|
153
|
-
"default":
|
|
144
|
+
"description": "Accept the x-frigg-api-key header (checked against FRIGG_API_KEY) for backend-to-backend calls. Enabled unless false.",
|
|
145
|
+
"default": true
|
|
154
146
|
},
|
|
155
147
|
"adopterJwt": {
|
|
156
148
|
"type": "boolean",
|
|
157
|
-
"description": "
|
|
149
|
+
"description": "Accept JWTs from the adopter's own auth system (requires jwtConfig). Enabled only when true.",
|
|
158
150
|
"default": false
|
|
159
151
|
}
|
|
160
152
|
},
|
|
@@ -166,7 +158,7 @@
|
|
|
166
158
|
"properties": {
|
|
167
159
|
"secret": {
|
|
168
160
|
"type": "string",
|
|
169
|
-
"description": "JWT secret key for signature validation (
|
|
161
|
+
"description": "JWT secret key for signature validation, usually `process.env.JWT_SECRET`. Required when authModes.adopterJwt is true; `frigg validate` errors when the key is missing from the definition and warns when its value is empty in the shell that runs it (build and deploy validate before `.env` is loaded)."
|
|
170
162
|
},
|
|
171
163
|
"userIdClaim": {
|
|
172
164
|
"type": "string",
|
|
@@ -185,27 +177,29 @@
|
|
|
185
177
|
"default": "HS256"
|
|
186
178
|
}
|
|
187
179
|
},
|
|
188
|
-
"required": ["secret"],
|
|
189
180
|
"additionalProperties": false
|
|
190
181
|
},
|
|
191
182
|
"fields": {
|
|
192
183
|
"type": "array",
|
|
193
|
-
"description": "Additional user fields",
|
|
194
|
-
"items": {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
184
|
+
"description": "Additional user fields. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
185
|
+
"items": {"type": "string"},
|
|
186
|
+
"examples": [
|
|
187
|
+
["email", "firstName", "lastName"]
|
|
188
|
+
],
|
|
189
|
+
"deprecated": true
|
|
198
190
|
},
|
|
199
191
|
"model": {
|
|
200
192
|
"type": "object",
|
|
201
|
-
"description": "Custom user model class"
|
|
193
|
+
"description": "Custom user model class. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
194
|
+
"deprecated": true
|
|
202
195
|
}
|
|
203
196
|
},
|
|
204
|
-
"additionalProperties": false
|
|
197
|
+
"additionalProperties": false,
|
|
198
|
+
"default": {}
|
|
205
199
|
},
|
|
206
200
|
"auth": {
|
|
207
201
|
"type": "object",
|
|
208
|
-
"description": "Authentication configuration
|
|
202
|
+
"description": "Authentication configuration. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
209
203
|
"properties": {
|
|
210
204
|
"jwtSecret": {
|
|
211
205
|
"type": "string",
|
|
@@ -214,17 +208,16 @@
|
|
|
214
208
|
"tokenExpiry": {
|
|
215
209
|
"type": "string",
|
|
216
210
|
"description": "Token expiration time",
|
|
217
|
-
"pattern": "^\\d+[smhd]$"
|
|
218
|
-
"default": "24h"
|
|
211
|
+
"pattern": "^\\d+[smhd]$"
|
|
219
212
|
},
|
|
220
213
|
"refreshTokenExpiry": {
|
|
221
214
|
"type": "string",
|
|
222
|
-
"description": "Refresh token expiration time",
|
|
223
|
-
"pattern": "^\\d+[smhd]$"
|
|
224
|
-
"default": "7d"
|
|
215
|
+
"description": "Refresh token expiration time",
|
|
216
|
+
"pattern": "^\\d+[smhd]$"
|
|
225
217
|
}
|
|
226
218
|
},
|
|
227
|
-
"additionalProperties": false
|
|
219
|
+
"additionalProperties": false,
|
|
220
|
+
"deprecated": true
|
|
228
221
|
},
|
|
229
222
|
"database": {
|
|
230
223
|
"type": "object",
|
|
@@ -232,8 +225,8 @@
|
|
|
232
225
|
"properties": {
|
|
233
226
|
"uri": {
|
|
234
227
|
"type": "string",
|
|
235
|
-
"description": "Database connection URI (should be set via environment variable)",
|
|
236
|
-
"
|
|
228
|
+
"description": "Database connection URI (should be set via environment variable). Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
229
|
+
"deprecated": true
|
|
237
230
|
},
|
|
238
231
|
"mongoDB": {
|
|
239
232
|
"type": "object",
|
|
@@ -246,7 +239,8 @@
|
|
|
246
239
|
},
|
|
247
240
|
"uri": {
|
|
248
241
|
"type": "string",
|
|
249
|
-
"description": "MongoDB connection URI"
|
|
242
|
+
"description": "MongoDB connection URI. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set. The connection string comes from DATABASE_URL.",
|
|
243
|
+
"deprecated": true
|
|
250
244
|
}
|
|
251
245
|
},
|
|
252
246
|
"additionalProperties": true
|
|
@@ -274,18 +268,16 @@
|
|
|
274
268
|
"properties": {
|
|
275
269
|
"enable": {
|
|
276
270
|
"type": "boolean",
|
|
277
|
-
"description": "
|
|
278
|
-
"default": false
|
|
271
|
+
"description": "Use PostgreSQL. true provisions or discovers Aurora (unless management says otherwise). When omitted, Aurora is not provisioned, but migrations and the Prisma layer still include PostgreSQL; set false for a MongoDB/DocumentDB app."
|
|
279
272
|
},
|
|
280
273
|
"management": {
|
|
281
274
|
"type": "string",
|
|
282
|
-
"description": "How
|
|
283
|
-
"enum": ["discover", "
|
|
284
|
-
"default": "discover"
|
|
275
|
+
"description": "How Frigg gets the Aurora cluster (ignored when managementMode is 'managed' or 'existing'). 'discover' (also when omitted): find one, else create one in the stack. 'managed': create it in the stack. 'use-existing': connect to `endpoint` without creating anything. 'external': Frigg provisions and discovers no database (no RDS/Aurora, no VPC requirement); the app connects to any PostgreSQL through the DATABASE_URL environment variable.",
|
|
276
|
+
"enum": ["discover", "managed", "use-existing", "external"]
|
|
285
277
|
},
|
|
286
278
|
"endpoint": {
|
|
287
279
|
"type": "string",
|
|
288
|
-
"description": "Existing database endpoint (when management='existing')",
|
|
280
|
+
"description": "Existing database endpoint (required when management='use-existing')",
|
|
289
281
|
"examples": ["mydb.cluster-abc123.us-east-1.rds.amazonaws.com"]
|
|
290
282
|
},
|
|
291
283
|
"port": {
|
|
@@ -303,10 +295,15 @@
|
|
|
303
295
|
"description": "Database username",
|
|
304
296
|
"default": "postgres"
|
|
305
297
|
},
|
|
298
|
+
"engineVersion": {
|
|
299
|
+
"type": "string",
|
|
300
|
+
"description": "Aurora PostgreSQL engine version for a cluster Frigg creates",
|
|
301
|
+
"default": "15.13"
|
|
302
|
+
},
|
|
306
303
|
"selfHeal": {
|
|
307
304
|
"type": "boolean",
|
|
308
|
-
"description": "Automatically fix database configuration issues",
|
|
309
|
-
"
|
|
305
|
+
"description": "Automatically fix database configuration issues. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
306
|
+
"deprecated": true
|
|
310
307
|
},
|
|
311
308
|
"publiclyAccessible": {
|
|
312
309
|
"type": "boolean",
|
|
@@ -315,7 +312,7 @@
|
|
|
315
312
|
},
|
|
316
313
|
"autoCreateCredentials": {
|
|
317
314
|
"type": "boolean",
|
|
318
|
-
"description": "
|
|
315
|
+
"description": "Create a Secrets Manager secret and rotate the Aurora password when a discovered cluster has none (management='discover' only)",
|
|
319
316
|
"default": false
|
|
320
317
|
},
|
|
321
318
|
"minCapacity": {
|
|
@@ -330,7 +327,65 @@
|
|
|
330
327
|
"description": "Maximum Aurora Serverless capacity units (0.5-128)",
|
|
331
328
|
"minimum": 0.5,
|
|
332
329
|
"maximum": 128,
|
|
333
|
-
"default":
|
|
330
|
+
"default": 4
|
|
331
|
+
},
|
|
332
|
+
"clusterId": {
|
|
333
|
+
"type": "string",
|
|
334
|
+
"description": "Only discover the Aurora cluster with this identifier"
|
|
335
|
+
},
|
|
336
|
+
"instanceId": {
|
|
337
|
+
"type": "string",
|
|
338
|
+
"description": "Only discover the Aurora instance with this identifier"
|
|
339
|
+
},
|
|
340
|
+
"ownership": {
|
|
341
|
+
"type": "object",
|
|
342
|
+
"description": "Per-resource ownership. When set, `management` is not translated.",
|
|
343
|
+
"properties": {
|
|
344
|
+
"cluster": {
|
|
345
|
+
"type": "string",
|
|
346
|
+
"enum": ["stack", "external", "auto"],
|
|
347
|
+
"description": "Aurora cluster. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
348
|
+
},
|
|
349
|
+
"instance": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"enum": ["stack", "external", "auto"],
|
|
352
|
+
"description": "Aurora instance. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
353
|
+
},
|
|
354
|
+
"subnetGroup": {
|
|
355
|
+
"type": "string",
|
|
356
|
+
"enum": ["stack", "external", "auto"],
|
|
357
|
+
"description": "DB subnet group. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
358
|
+
},
|
|
359
|
+
"secret": {
|
|
360
|
+
"type": "string",
|
|
361
|
+
"enum": ["stack", "external", "auto"],
|
|
362
|
+
"description": "Secrets Manager credentials secret. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
"additionalProperties": false
|
|
366
|
+
},
|
|
367
|
+
"external": {
|
|
368
|
+
"type": "object",
|
|
369
|
+
"description": "Ids of externally owned resources (ownership 'external')",
|
|
370
|
+
"properties": {
|
|
371
|
+
"clusterIdentifier": {"type": "string"},
|
|
372
|
+
"instanceIdentifier": {"type": "string"},
|
|
373
|
+
"subnetGroupName": {"type": "string"},
|
|
374
|
+
"secretArn": {"type": "string"}
|
|
375
|
+
},
|
|
376
|
+
"additionalProperties": false
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
"additionalProperties": false
|
|
380
|
+
},
|
|
381
|
+
"dynamodb": {
|
|
382
|
+
"type": "object",
|
|
383
|
+
"description": "DynamoDB access from inside the VPC",
|
|
384
|
+
"properties": {
|
|
385
|
+
"enable": {
|
|
386
|
+
"type": "boolean",
|
|
387
|
+
"description": "Add a DynamoDB VPC endpoint",
|
|
388
|
+
"default": false
|
|
334
389
|
}
|
|
335
390
|
},
|
|
336
391
|
"additionalProperties": false
|
|
@@ -344,14 +399,12 @@
|
|
|
344
399
|
"properties": {
|
|
345
400
|
"fieldLevelEncryptionMethod": {
|
|
346
401
|
"type": "string",
|
|
347
|
-
"description": "
|
|
348
|
-
"enum": ["kms", "aes"]
|
|
349
|
-
"default": "aes"
|
|
402
|
+
"description": "Field-level encryption key. 'kms': Frigg creates or discovers a KMS key and sets KMS_KEY_ARN. 'aes': the app supplies AES_KEY_ID and AES_KEY (list both in `environment`). 'none': no field-level encryption, chosen explicitly; no key is provisioned and deployed stages store sensitive fields unencrypted. Omitted: no key is provisioned and deployed stages store sensitive fields unencrypted (core logs a warning). Stages dev, test and local never encrypt.",
|
|
403
|
+
"enum": ["kms", "aes", "none"]
|
|
350
404
|
},
|
|
351
405
|
"createResourceIfNoneFound": {
|
|
352
406
|
"type": "boolean",
|
|
353
|
-
"description": "
|
|
354
|
-
"default": false
|
|
407
|
+
"description": "With 'kms' outside managementMode 'managed': create a KMS key when discovery finds none. When omitted, KMS_KEY_ARN falls back to the AWS_DISCOVERY_KMS_KEY_ID environment variable."
|
|
355
408
|
},
|
|
356
409
|
"schema": {
|
|
357
410
|
"type": "object",
|
|
@@ -388,6 +441,48 @@
|
|
|
388
441
|
}
|
|
389
442
|
}
|
|
390
443
|
]
|
|
444
|
+
},
|
|
445
|
+
"ownership": {
|
|
446
|
+
"type": "object",
|
|
447
|
+
"description": "Per-resource ownership. When set, createResourceIfNoneFound is not translated.",
|
|
448
|
+
"properties": {
|
|
449
|
+
"key": {
|
|
450
|
+
"type": "string",
|
|
451
|
+
"enum": ["stack", "external", "auto"],
|
|
452
|
+
"description": "KMS key. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
"additionalProperties": false
|
|
456
|
+
},
|
|
457
|
+
"kmsKeyAlias": {
|
|
458
|
+
"type": "boolean",
|
|
459
|
+
"description": "Create an alias for a KMS key Frigg creates",
|
|
460
|
+
"default": false
|
|
461
|
+
},
|
|
462
|
+
"keyAlias": {
|
|
463
|
+
"type": "string",
|
|
464
|
+
"description": "Only discover the KMS key with this alias",
|
|
465
|
+
"pattern": "^alias/",
|
|
466
|
+
"examples": ["alias/my-app-key"]
|
|
467
|
+
},
|
|
468
|
+
"disable": {
|
|
469
|
+
"type": "object",
|
|
470
|
+
"description": "Opt specific core-encrypted fields out of encryption: { Model: ['field.path'] }. Existing encrypted values still decrypt.",
|
|
471
|
+
"patternProperties": {
|
|
472
|
+
"^[A-Z][a-zA-Z0-9]*$": {
|
|
473
|
+
"type": "array",
|
|
474
|
+
"items": {
|
|
475
|
+
"type": "string",
|
|
476
|
+
"minLength": 1
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
"additionalProperties": false
|
|
481
|
+
},
|
|
482
|
+
"enable": {
|
|
483
|
+
"type": "boolean",
|
|
484
|
+
"description": "Encryption is controlled by fieldLevelEncryptionMethod. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
485
|
+
"deprecated": true
|
|
391
486
|
}
|
|
392
487
|
},
|
|
393
488
|
"additionalProperties": false
|
|
@@ -398,24 +493,23 @@
|
|
|
398
493
|
"properties": {
|
|
399
494
|
"enable": {
|
|
400
495
|
"type": "boolean",
|
|
401
|
-
"description": "
|
|
496
|
+
"description": "Run the Lambda functions in a VPC",
|
|
402
497
|
"default": false
|
|
403
498
|
},
|
|
404
499
|
"management": {
|
|
405
500
|
"type": "string",
|
|
406
|
-
"description": "How
|
|
407
|
-
"enum": ["discover", "create-new", "existing"]
|
|
408
|
-
"default": "discover"
|
|
501
|
+
"description": "How Frigg gets the VPC. 'discover' (also when omitted): find one (discovery fails if none exists). 'create-new': create VPC, security group and subnets in the stack. 'use-existing': use `vpcId` (and securityGroupIds / subnets.ids when given). Ignored when `ownership` is set.",
|
|
502
|
+
"enum": ["discover", "create-new", "use-existing"]
|
|
409
503
|
},
|
|
410
504
|
"vpcId": {
|
|
411
505
|
"type": "string",
|
|
412
|
-
"description": "Existing VPC ID (when management='existing')",
|
|
506
|
+
"description": "Existing VPC ID (required when management='use-existing')",
|
|
413
507
|
"pattern": "^vpc-[a-z0-9]+$",
|
|
414
508
|
"examples": ["vpc-abc123"]
|
|
415
509
|
},
|
|
416
510
|
"cidrBlock": {
|
|
417
511
|
"type": "string",
|
|
418
|
-
"description": "CIDR block for VPC
|
|
512
|
+
"description": "CIDR block for a VPC Frigg creates",
|
|
419
513
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$",
|
|
420
514
|
"default": "10.0.0.0/16"
|
|
421
515
|
},
|
|
@@ -426,7 +520,9 @@
|
|
|
426
520
|
"type": "string",
|
|
427
521
|
"pattern": "^sg-[a-z0-9]+$"
|
|
428
522
|
},
|
|
429
|
-
"examples": [
|
|
523
|
+
"examples": [
|
|
524
|
+
["sg-abc123", "sg-def456"]
|
|
525
|
+
]
|
|
430
526
|
},
|
|
431
527
|
"subnets": {
|
|
432
528
|
"type": "object",
|
|
@@ -434,19 +530,20 @@
|
|
|
434
530
|
"properties": {
|
|
435
531
|
"management": {
|
|
436
532
|
"type": "string",
|
|
437
|
-
"description": "
|
|
438
|
-
"enum": ["discover", "create-new", "existing"]
|
|
439
|
-
"default": "discover"
|
|
533
|
+
"description": "'create': create the subnets in the stack. 'use-existing': use `ids` (at least 2). 'discover', 'create-new' and 'existing' are accepted for compatibility but have no effect (`frigg validate` warns).",
|
|
534
|
+
"enum": ["create", "use-existing", "discover", "create-new", "existing"]
|
|
440
535
|
},
|
|
441
536
|
"ids": {
|
|
442
537
|
"type": "array",
|
|
443
|
-
"description": "Existing subnet IDs",
|
|
538
|
+
"description": "Existing subnet IDs (management='use-existing')",
|
|
444
539
|
"items": {
|
|
445
540
|
"type": "string",
|
|
446
541
|
"pattern": "^subnet-[a-z0-9]+$"
|
|
447
542
|
},
|
|
448
543
|
"minItems": 2,
|
|
449
|
-
"examples": [
|
|
544
|
+
"examples": [
|
|
545
|
+
["subnet-abc123", "subnet-def456"]
|
|
546
|
+
]
|
|
450
547
|
}
|
|
451
548
|
},
|
|
452
549
|
"additionalProperties": false
|
|
@@ -457,13 +554,12 @@
|
|
|
457
554
|
"properties": {
|
|
458
555
|
"management": {
|
|
459
556
|
"type": "string",
|
|
460
|
-
"description": "
|
|
461
|
-
"enum": ["discover", "create-new", "existing"]
|
|
462
|
-
"default": "discover"
|
|
557
|
+
"description": "'createAndManage': reuse a well-placed NAT gateway or create one. 'discover', 'create-new' and 'existing' are accepted for compatibility but have no effect (`frigg validate` warns). Set `id` to use an existing NAT gateway.",
|
|
558
|
+
"enum": ["createAndManage", "discover", "create-new", "existing"]
|
|
463
559
|
},
|
|
464
560
|
"id": {
|
|
465
561
|
"type": "string",
|
|
466
|
-
"description": "Existing NAT Gateway ID",
|
|
562
|
+
"description": "Existing NAT Gateway ID (makes the NAT gateway external)",
|
|
467
563
|
"pattern": "^nat-[a-z0-9]+$",
|
|
468
564
|
"examples": ["nat-abc123"]
|
|
469
565
|
}
|
|
@@ -472,13 +568,112 @@
|
|
|
472
568
|
},
|
|
473
569
|
"enableVPCEndpoints": {
|
|
474
570
|
"type": "boolean",
|
|
475
|
-
"description": "Create VPC endpoints for AWS services (S3, DynamoDB, KMS, Secrets Manager)",
|
|
571
|
+
"description": "Create VPC endpoints for AWS services (S3, DynamoDB, KMS, Secrets Manager). Enabled unless false.",
|
|
476
572
|
"default": true
|
|
477
573
|
},
|
|
478
574
|
"selfHeal": {
|
|
479
575
|
"type": "boolean",
|
|
480
|
-
"description": "
|
|
481
|
-
|
|
576
|
+
"description": "Repair VPC configuration issues (route table associations) during discovery. When omitted, self-healing of stack-owned subnets is on."
|
|
577
|
+
},
|
|
578
|
+
"shareAcrossStages": {
|
|
579
|
+
"type": "boolean",
|
|
580
|
+
"description": "Legacy: true reuses (auto) the VPC and subnets across stages; false creates a VPC, subnets and NAT gateway per stage. Ignored when `ownership` is set."
|
|
581
|
+
},
|
|
582
|
+
"ownership": {
|
|
583
|
+
"type": "object",
|
|
584
|
+
"description": "Per-resource ownership. When set, management, subnets, natGateway, shareAcrossStages, enableVPCEndpoints and selfHeal are not translated; use `config` instead.",
|
|
585
|
+
"properties": {
|
|
586
|
+
"vpc": {
|
|
587
|
+
"type": "string",
|
|
588
|
+
"enum": ["stack", "external", "auto"],
|
|
589
|
+
"description": "VPC. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
590
|
+
},
|
|
591
|
+
"securityGroup": {
|
|
592
|
+
"type": "string",
|
|
593
|
+
"enum": ["stack", "external", "auto"],
|
|
594
|
+
"description": "Lambda security group. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
595
|
+
},
|
|
596
|
+
"subnets": {
|
|
597
|
+
"type": "string",
|
|
598
|
+
"enum": ["stack", "external", "auto"],
|
|
599
|
+
"description": "Private subnets. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
600
|
+
},
|
|
601
|
+
"natGateway": {
|
|
602
|
+
"type": "string",
|
|
603
|
+
"enum": ["stack", "external", "auto"],
|
|
604
|
+
"description": "NAT gateway. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
605
|
+
},
|
|
606
|
+
"vpcEndpoints": {
|
|
607
|
+
"type": "string",
|
|
608
|
+
"enum": ["stack", "external", "auto"],
|
|
609
|
+
"description": "VPC endpoints. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
"additionalProperties": false
|
|
613
|
+
},
|
|
614
|
+
"external": {
|
|
615
|
+
"type": "object",
|
|
616
|
+
"description": "Ids of externally owned resources (ownership 'external'); discovered ids are used when omitted",
|
|
617
|
+
"properties": {
|
|
618
|
+
"vpcId": {
|
|
619
|
+
"type": "string",
|
|
620
|
+
"pattern": "^vpc-[a-z0-9]+$"
|
|
621
|
+
},
|
|
622
|
+
"securityGroupIds": {
|
|
623
|
+
"type": "array",
|
|
624
|
+
"items": {
|
|
625
|
+
"type": "string",
|
|
626
|
+
"pattern": "^sg-[a-z0-9]+$"
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
"subnetIds": {
|
|
630
|
+
"type": "array",
|
|
631
|
+
"items": {
|
|
632
|
+
"type": "string",
|
|
633
|
+
"pattern": "^subnet-[a-z0-9]+$"
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
"natGatewayId": {
|
|
637
|
+
"type": "string",
|
|
638
|
+
"pattern": "^nat-[a-z0-9]+$"
|
|
639
|
+
},
|
|
640
|
+
"vpcEndpointIds": {
|
|
641
|
+
"type": "object",
|
|
642
|
+
"description": "Endpoint ids by type (s3, dynamodb, kms, secretsManager, sqs)",
|
|
643
|
+
"additionalProperties": {"type": "string"}
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
"additionalProperties": false
|
|
647
|
+
},
|
|
648
|
+
"config": {
|
|
649
|
+
"type": "object",
|
|
650
|
+
"description": "Settings for the ownership-based VPC configuration",
|
|
651
|
+
"properties": {
|
|
652
|
+
"cidrBlock": {
|
|
653
|
+
"type": "string",
|
|
654
|
+
"description": "CIDR block for a VPC Frigg creates (wins over vpc.cidrBlock)",
|
|
655
|
+
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$"
|
|
656
|
+
},
|
|
657
|
+
"selfHeal": {
|
|
658
|
+
"type": "boolean",
|
|
659
|
+
"description": "Recreate missing stack-owned subnets. Enabled unless false."
|
|
660
|
+
},
|
|
661
|
+
"natGateway": {
|
|
662
|
+
"type": "object",
|
|
663
|
+
"properties": {
|
|
664
|
+
"enable": {
|
|
665
|
+
"type": "boolean",
|
|
666
|
+
"description": "Resolve a NAT gateway. Enabled unless false."
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
"additionalProperties": false
|
|
670
|
+
},
|
|
671
|
+
"enableVpcEndpoints": {
|
|
672
|
+
"type": "boolean",
|
|
673
|
+
"description": "Create VPC endpoints. Enabled unless false."
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
"additionalProperties": false
|
|
482
677
|
}
|
|
483
678
|
},
|
|
484
679
|
"additionalProperties": false
|
|
@@ -523,9 +718,7 @@
|
|
|
523
718
|
"enum": ["standard", "advanced"],
|
|
524
719
|
"default": "standard"
|
|
525
720
|
},
|
|
526
|
-
"description": {
|
|
527
|
-
"type": "string"
|
|
528
|
-
}
|
|
721
|
+
"description": {"type": "string"}
|
|
529
722
|
}
|
|
530
723
|
}
|
|
531
724
|
},
|
|
@@ -536,15 +729,15 @@
|
|
|
536
729
|
},
|
|
537
730
|
"secretsManager": {
|
|
538
731
|
"type": "object",
|
|
539
|
-
"description": "AWS Secrets Manager configuration",
|
|
732
|
+
"description": "AWS Secrets Manager configuration. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
540
733
|
"properties": {
|
|
541
734
|
"enable": {
|
|
542
735
|
"type": "boolean",
|
|
543
|
-
"description": "Enable AWS Secrets Manager for secure credential storage"
|
|
544
|
-
"default": false
|
|
736
|
+
"description": "Enable AWS Secrets Manager for secure credential storage"
|
|
545
737
|
}
|
|
546
738
|
},
|
|
547
|
-
"additionalProperties": false
|
|
739
|
+
"additionalProperties": false,
|
|
740
|
+
"deprecated": true
|
|
548
741
|
},
|
|
549
742
|
"lambda": {
|
|
550
743
|
"type": "object",
|
|
@@ -554,6 +747,11 @@
|
|
|
554
747
|
"type": "boolean",
|
|
555
748
|
"description": "Scope framework-generated environment variables (queue URLs, migration/scheduler vars) to the functions that consume them instead of broadcasting to every function. Reduces per-function env size against the Lambda 4KB limit",
|
|
556
749
|
"default": false
|
|
750
|
+
},
|
|
751
|
+
"keepNestedNodeModules": {
|
|
752
|
+
"type": "boolean",
|
|
753
|
+
"description": "Keep nested node_modules in function packages (nested Frigg, AWS SDK and Prisma packages are still excluded)",
|
|
754
|
+
"default": false
|
|
557
755
|
}
|
|
558
756
|
},
|
|
559
757
|
"additionalProperties": false
|
|
@@ -569,15 +767,15 @@
|
|
|
569
767
|
},
|
|
570
768
|
"routeSelectionExpression": {
|
|
571
769
|
"type": "string",
|
|
572
|
-
"description": "Route selection expression for WebSocket",
|
|
573
|
-
"
|
|
770
|
+
"description": "Route selection expression for WebSocket. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
771
|
+
"deprecated": true
|
|
574
772
|
}
|
|
575
773
|
},
|
|
576
774
|
"additionalProperties": false
|
|
577
775
|
},
|
|
578
776
|
"security": {
|
|
579
777
|
"type": "object",
|
|
580
|
-
"description": "Security settings for the application",
|
|
778
|
+
"description": "Security settings for the application. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
581
779
|
"properties": {
|
|
582
780
|
"cors": {
|
|
583
781
|
"type": "object",
|
|
@@ -586,16 +784,17 @@
|
|
|
586
784
|
"origin": {
|
|
587
785
|
"oneOf": [
|
|
588
786
|
{"type": "string"},
|
|
589
|
-
{
|
|
787
|
+
{
|
|
788
|
+
"type": "array",
|
|
789
|
+
"items": {"type": "string"}
|
|
790
|
+
},
|
|
590
791
|
{"type": "boolean"}
|
|
591
792
|
],
|
|
592
|
-
"description": "Allowed origins for CORS requests"
|
|
593
|
-
"default": "http://localhost:3000"
|
|
793
|
+
"description": "Allowed origins for CORS requests"
|
|
594
794
|
},
|
|
595
795
|
"credentials": {
|
|
596
796
|
"type": "boolean",
|
|
597
|
-
"description": "Allow credentials in CORS requests"
|
|
598
|
-
"default": true
|
|
797
|
+
"description": "Allow credentials in CORS requests"
|
|
599
798
|
},
|
|
600
799
|
"methods": {
|
|
601
800
|
"type": "array",
|
|
@@ -620,24 +819,23 @@
|
|
|
620
819
|
"windowMs": {
|
|
621
820
|
"type": "integer",
|
|
622
821
|
"description": "Time window in milliseconds",
|
|
623
|
-
"minimum": 1000
|
|
624
|
-
"default": 900000
|
|
822
|
+
"minimum": 1000
|
|
625
823
|
},
|
|
626
824
|
"max": {
|
|
627
|
-
"type": "integer",
|
|
825
|
+
"type": "integer",
|
|
628
826
|
"description": "Maximum requests per window",
|
|
629
|
-
"minimum": 1
|
|
630
|
-
"default": 100
|
|
827
|
+
"minimum": 1
|
|
631
828
|
}
|
|
632
829
|
},
|
|
633
830
|
"additionalProperties": false
|
|
634
831
|
}
|
|
635
832
|
},
|
|
636
|
-
"additionalProperties": false
|
|
833
|
+
"additionalProperties": false,
|
|
834
|
+
"deprecated": true
|
|
637
835
|
},
|
|
638
836
|
"webhooks": {
|
|
639
837
|
"type": "object",
|
|
640
|
-
"description": "Webhook handling configuration",
|
|
838
|
+
"description": "Webhook handling configuration. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set. Webhooks are declared per integration (Definition.webhooks).",
|
|
641
839
|
"properties": {
|
|
642
840
|
"secret": {
|
|
643
841
|
"type": "string",
|
|
@@ -646,11 +844,11 @@
|
|
|
646
844
|
"prefix": {
|
|
647
845
|
"type": "string",
|
|
648
846
|
"description": "Webhook endpoint prefix",
|
|
649
|
-
"pattern": "^/[a-zA-Z0-9/_-]*$"
|
|
650
|
-
"default": "/webhooks"
|
|
847
|
+
"pattern": "^/[a-zA-Z0-9/_-]*$"
|
|
651
848
|
}
|
|
652
849
|
},
|
|
653
|
-
"additionalProperties": false
|
|
850
|
+
"additionalProperties": false,
|
|
851
|
+
"deprecated": true
|
|
654
852
|
},
|
|
655
853
|
"logging": {
|
|
656
854
|
"type": "object",
|
|
@@ -658,9 +856,8 @@
|
|
|
658
856
|
"properties": {
|
|
659
857
|
"level": {
|
|
660
858
|
"type": "string",
|
|
661
|
-
"description": "Minimum log level, in lower or upper case. Sets FRIGG_LOG_LEVEL (when not info) and the Lambda application log level.",
|
|
662
|
-
"enum": ["trace", "debug", "info", "warn", "error", "fatal", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"]
|
|
663
|
-
"default": "info"
|
|
859
|
+
"description": "Minimum log level, in lower or upper case. Sets FRIGG_LOG_LEVEL (when not info) and the Lambda application log level. When omitted, core logs at info and no Lambda log level is set.",
|
|
860
|
+
"enum": ["trace", "debug", "info", "warn", "error", "fatal", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"]
|
|
664
861
|
},
|
|
665
862
|
"retentionInDays": {
|
|
666
863
|
"type": "integer",
|
|
@@ -669,46 +866,225 @@
|
|
|
669
866
|
},
|
|
670
867
|
"format": {
|
|
671
868
|
"type": "string",
|
|
672
|
-
"description": "Log format. Records are always JSON lines.",
|
|
673
|
-
"enum": ["json"]
|
|
674
|
-
|
|
869
|
+
"description": "Log format. Records are always JSON lines; this key is informational and has no default.",
|
|
870
|
+
"enum": ["json"]
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
"additionalProperties": false
|
|
874
|
+
},
|
|
875
|
+
"scheduler": {
|
|
876
|
+
"type": "object",
|
|
877
|
+
"description": "EventBridge Scheduler resources for one-time jobs. Also enabled automatically when an integration declares webhooks.",
|
|
878
|
+
"properties": {
|
|
879
|
+
"enable": {
|
|
880
|
+
"type": "boolean",
|
|
881
|
+
"description": "Provision the scheduler role and dead-letter queue",
|
|
882
|
+
"default": false
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
"additionalProperties": false
|
|
886
|
+
},
|
|
887
|
+
"aws": {
|
|
888
|
+
"type": "object",
|
|
889
|
+
"description": "AWS options for the build",
|
|
890
|
+
"properties": {
|
|
891
|
+
"discovery": {
|
|
892
|
+
"type": "object",
|
|
893
|
+
"description": "AWS resource discovery during build/deploy",
|
|
894
|
+
"properties": {
|
|
895
|
+
"enabled": {
|
|
896
|
+
"type": "boolean",
|
|
897
|
+
"description": "Force discovery on or off. When omitted, discovery runs when a feature needs it (VPC, KMS, SSM, PostgreSQL) and FRIGG_SKIP_AWS_DISCOVERY is not set."
|
|
898
|
+
},
|
|
899
|
+
"failOnError": {
|
|
900
|
+
"type": "boolean",
|
|
901
|
+
"description": "Fail the build when discovery fails",
|
|
902
|
+
"default": false
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
"additionalProperties": false
|
|
906
|
+
}
|
|
907
|
+
},
|
|
908
|
+
"additionalProperties": false
|
|
909
|
+
},
|
|
910
|
+
"migration": {
|
|
911
|
+
"type": "object",
|
|
912
|
+
"description": "Database migration resources",
|
|
913
|
+
"properties": {
|
|
914
|
+
"ownership": {
|
|
915
|
+
"type": "object",
|
|
916
|
+
"properties": {
|
|
917
|
+
"bucket": {
|
|
918
|
+
"type": "string",
|
|
919
|
+
"enum": ["stack", "external", "auto"],
|
|
920
|
+
"description": "Migration S3 bucket. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
921
|
+
},
|
|
922
|
+
"queue": {
|
|
923
|
+
"type": "string",
|
|
924
|
+
"enum": ["stack", "external", "auto"],
|
|
925
|
+
"description": "Migration SQS queue. Who owns the resource: 'stack' (this stack creates it), 'external' (use the id in `external`), 'auto' (reuse what discovery finds, else create)"
|
|
926
|
+
}
|
|
927
|
+
},
|
|
928
|
+
"additionalProperties": false
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
"additionalProperties": false
|
|
932
|
+
},
|
|
933
|
+
"telemetry": {
|
|
934
|
+
"type": "object",
|
|
935
|
+
"description": "Telemetry and usage tracking (ADR-011). An invalid block disables telemetry at runtime instead of failing.",
|
|
936
|
+
"properties": {
|
|
937
|
+
"exporter": {
|
|
938
|
+
"type": "object",
|
|
939
|
+
"description": "Where traces and metrics go. When omitted: 'console' for STAGE=local, else 'none'.",
|
|
940
|
+
"properties": {
|
|
941
|
+
"type": {
|
|
942
|
+
"type": "string",
|
|
943
|
+
"enum": ["none", "noop", "console", "otlp", "honeycomb", "datadog"]
|
|
944
|
+
},
|
|
945
|
+
"endpoint": {
|
|
946
|
+
"type": "string",
|
|
947
|
+
"description": "OTLP endpoint (honeycomb defaults to https://api.honeycomb.io)"
|
|
948
|
+
},
|
|
949
|
+
"headers": {
|
|
950
|
+
"type": "object",
|
|
951
|
+
"additionalProperties": {"type": "string"}
|
|
952
|
+
},
|
|
953
|
+
"apiKey": {
|
|
954
|
+
"type": "string",
|
|
955
|
+
"description": "Honeycomb API key (sent as x-honeycomb-team)"
|
|
956
|
+
},
|
|
957
|
+
"traceExporter": {
|
|
958
|
+
"description": "A pre-built OTel trace exporter instance (advanced)"
|
|
959
|
+
},
|
|
960
|
+
"metricExporter": {
|
|
961
|
+
"description": "A pre-built OTel metric exporter instance (advanced)"
|
|
962
|
+
}
|
|
963
|
+
},
|
|
964
|
+
"additionalProperties": false
|
|
965
|
+
},
|
|
966
|
+
"sampleRatio": {
|
|
967
|
+
"type": "number",
|
|
968
|
+
"description": "Fraction of traces exported",
|
|
969
|
+
"minimum": 0,
|
|
970
|
+
"maximum": 1,
|
|
971
|
+
"default": 1
|
|
972
|
+
},
|
|
973
|
+
"northStar": {
|
|
974
|
+
"type": "object",
|
|
975
|
+
"description": "The usage counter that measures each integration type's value: { default: { name }, byType: { <type>: { name } } }",
|
|
976
|
+
"properties": {
|
|
977
|
+
"default": {
|
|
978
|
+
"type": "object",
|
|
979
|
+
"required": ["name"],
|
|
980
|
+
"properties": {
|
|
981
|
+
"name": {"type": "string"}
|
|
982
|
+
}
|
|
983
|
+
},
|
|
984
|
+
"byType": {
|
|
985
|
+
"type": "object",
|
|
986
|
+
"additionalProperties": {
|
|
987
|
+
"type": "object",
|
|
988
|
+
"required": ["name"],
|
|
989
|
+
"properties": {
|
|
990
|
+
"name": {"type": "string"}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
"additionalProperties": false
|
|
996
|
+
},
|
|
997
|
+
"subscribers": {
|
|
998
|
+
"type": "array",
|
|
999
|
+
"description": "Telemetry event subscribers: functions or { handler } objects",
|
|
1000
|
+
"items": {
|
|
1001
|
+
"description": "A function or { handler }"
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
"additionalProperties": false
|
|
1006
|
+
},
|
|
1007
|
+
"admin": {
|
|
1008
|
+
"type": "object",
|
|
1009
|
+
"description": "Admin Script Runner options (ADR-005, ADR-010)",
|
|
1010
|
+
"properties": {
|
|
1011
|
+
"includeBuiltinReports": {
|
|
1012
|
+
"type": "boolean",
|
|
1013
|
+
"description": "Register Frigg's built-in reports",
|
|
1014
|
+
"default": false
|
|
1015
|
+
},
|
|
1016
|
+
"enableScheduling": {
|
|
1017
|
+
"type": "boolean",
|
|
1018
|
+
"description": "Provision scheduling for admin scripts"
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
"additionalProperties": false
|
|
1022
|
+
},
|
|
1023
|
+
"adminScripts": {
|
|
1024
|
+
"type": "array",
|
|
1025
|
+
"description": "Admin script classes (each with a static Definition). Validators see each class as { Definition }.",
|
|
1026
|
+
"items": {
|
|
1027
|
+
"type": "object",
|
|
1028
|
+
"required": ["Definition"],
|
|
1029
|
+
"properties": {
|
|
1030
|
+
"Definition": {"type": "object"}
|
|
1031
|
+
}
|
|
1032
|
+
},
|
|
1033
|
+
"default": []
|
|
1034
|
+
},
|
|
1035
|
+
"reports": {
|
|
1036
|
+
"type": "array",
|
|
1037
|
+
"description": "Report classes (each with a static Definition). Validators see each class as { Definition }.",
|
|
1038
|
+
"items": {
|
|
1039
|
+
"type": "object",
|
|
1040
|
+
"required": ["Definition"],
|
|
1041
|
+
"properties": {
|
|
1042
|
+
"Definition": {"type": "object"}
|
|
1043
|
+
}
|
|
1044
|
+
},
|
|
1045
|
+
"default": []
|
|
1046
|
+
},
|
|
1047
|
+
"deployment": {
|
|
1048
|
+
"type": "object",
|
|
1049
|
+
"description": "`frigg deploy` options",
|
|
1050
|
+
"properties": {
|
|
1051
|
+
"skipPostDeploymentHealthCheck": {
|
|
1052
|
+
"type": "boolean",
|
|
1053
|
+
"description": "Skip `frigg doctor` after a deploy",
|
|
1054
|
+
"default": false
|
|
675
1055
|
}
|
|
676
1056
|
},
|
|
677
1057
|
"additionalProperties": false
|
|
678
1058
|
},
|
|
679
1059
|
"custom": {
|
|
680
1060
|
"type": "object",
|
|
681
|
-
"description": "Custom application-specific configuration",
|
|
1061
|
+
"description": "Custom application-specific configuration. Not read by the Frigg runtime: it has no effect. Kept so existing definitions stay valid; `frigg validate` warns when it is set.",
|
|
682
1062
|
"properties": {
|
|
683
1063
|
"appName": {
|
|
684
1064
|
"type": "string",
|
|
685
|
-
"description": "Application display name"
|
|
686
|
-
"default": "My Frigg Application"
|
|
1065
|
+
"description": "Application display name"
|
|
687
1066
|
},
|
|
688
1067
|
"version": {
|
|
689
1068
|
"type": "string",
|
|
690
1069
|
"description": "Application version",
|
|
691
|
-
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$"
|
|
692
|
-
"default": "1.0.0"
|
|
1070
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$"
|
|
693
1071
|
},
|
|
694
1072
|
"environment": {
|
|
695
1073
|
"type": "string",
|
|
696
1074
|
"description": "Deployment environment/stage",
|
|
697
|
-
"enum": ["development", "staging", "production", "test"]
|
|
698
|
-
"default": "development"
|
|
1075
|
+
"enum": ["development", "staging", "production", "test"]
|
|
699
1076
|
},
|
|
700
1077
|
"features": {
|
|
701
1078
|
"type": "object",
|
|
702
1079
|
"description": "Feature flags and toggles",
|
|
703
1080
|
"patternProperties": {
|
|
704
|
-
"^[a-zA-Z][a-zA-Z0-9_]*$": {
|
|
705
|
-
"type": "boolean"
|
|
706
|
-
}
|
|
1081
|
+
"^[a-zA-Z][a-zA-Z0-9_]*$": {"type": "boolean"}
|
|
707
1082
|
},
|
|
708
1083
|
"additionalProperties": false
|
|
709
1084
|
}
|
|
710
1085
|
},
|
|
711
|
-
"additionalProperties": true
|
|
1086
|
+
"additionalProperties": true,
|
|
1087
|
+
"deprecated": true
|
|
712
1088
|
}
|
|
713
1089
|
},
|
|
714
1090
|
"additionalProperties": false,
|
|
@@ -722,12 +1098,15 @@
|
|
|
722
1098
|
},
|
|
723
1099
|
"integrations": [],
|
|
724
1100
|
"user": {
|
|
725
|
-
"
|
|
1101
|
+
"usePassword": true,
|
|
1102
|
+
"primary": "individual",
|
|
1103
|
+
"individualUserRequired": true,
|
|
1104
|
+
"organizationUserRequired": false
|
|
726
1105
|
},
|
|
727
1106
|
"database": {
|
|
728
1107
|
"postgres": {
|
|
729
1108
|
"enable": true,
|
|
730
|
-
"management": "
|
|
1109
|
+
"management": "managed"
|
|
731
1110
|
}
|
|
732
1111
|
},
|
|
733
1112
|
"encryption": {
|
|
@@ -740,18 +1119,8 @@
|
|
|
740
1119
|
"cidrBlock": "10.0.0.0/16",
|
|
741
1120
|
"enableVPCEndpoints": true
|
|
742
1121
|
},
|
|
743
|
-
"ssm": {
|
|
744
|
-
|
|
745
|
-
},
|
|
746
|
-
"websockets": {
|
|
747
|
-
"enable": true
|
|
748
|
-
},
|
|
749
|
-
"security": {
|
|
750
|
-
"cors": {
|
|
751
|
-
"origin": "http://localhost:3000",
|
|
752
|
-
"credentials": true
|
|
753
|
-
}
|
|
754
|
-
},
|
|
1122
|
+
"ssm": {"enable": true},
|
|
1123
|
+
"websockets": {"enable": true},
|
|
755
1124
|
"logging": {
|
|
756
1125
|
"level": "info",
|
|
757
1126
|
"retentionInDays": 30
|