@friggframework/schemas 2.0.0--canary.701.3b01ea3.0 → 2.0.0--canary.705.f070722.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -4
- package/index.js +24 -18
- package/middleware/schema-validation.js +2 -1
- package/package.json +6 -4
- package/schema-ids.js +69 -0
- package/schemas/api-authorization.schema.json +1 -1
- package/schemas/api-credentials.schema.json +1 -1
- package/schemas/api-entities.schema.json +1 -1
- package/schemas/api-module-definition.schema.json +1 -24
- package/schemas/api-proxy.schema.json +1 -1
- package/schemas/app-definition.schema.json +1 -1
- package/schemas/core-models.schema.json +1 -1
- package/schemas/environment-config.schema.json +1 -1
- package/schemas/integration-definition.schema.json +1 -1
- package/schemas/serverless-config.schema.json +1 -1
- package/api-module-definition.js +0 -93
package/README.md
CHANGED
|
@@ -95,6 +95,31 @@ const appSchema = getSchema('app-definition');
|
|
|
95
95
|
console.log('App definition schema:', appSchema);
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
## Schema Identifiers and Hosting
|
|
99
|
+
|
|
100
|
+
Every schema's `$id` is its public URL:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
https://friggframework.org/schemas/<name>/v<major>.<minor>.json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
for example `https://friggframework.org/schemas/app-definition/v1.0.json`.
|
|
107
|
+
friggframework.org serves each file at that URL (with
|
|
108
|
+
`Content-Type: application/schema+json` and open CORS), so editors can fetch
|
|
109
|
+
it from a `$schema` reference. The URL is a name, not a dependency: this
|
|
110
|
+
package, `frigg validate` and the runtime resolve every `$id` from the
|
|
111
|
+
installed files and never fetch it.
|
|
112
|
+
|
|
113
|
+
- A version is immutable once a stable release ships it. A backward-compatible
|
|
114
|
+
change gets a new minor version, a breaking change a new major version.
|
|
115
|
+
- `validate()` and `getSchema()` accept a schema name, its `$id`, or the
|
|
116
|
+
unversioned id it had before 2.0.1 (kept as an alias for one release).
|
|
117
|
+
- The website copies live in `website/schemas/` and are committed. After you
|
|
118
|
+
change a schema, run `npm run sync:hosted` here and commit the result;
|
|
119
|
+
`tests/hosted-schemas.test.js` fails while a copy is missing or stale.
|
|
120
|
+
|
|
121
|
+
The rules are in ADR-051, "Hosted schemas" amendment.
|
|
122
|
+
|
|
98
123
|
## Available Schemas
|
|
99
124
|
|
|
100
125
|
### App Definition Schema
|
|
@@ -172,9 +197,7 @@ Defines the structure for Frigg API modules.
|
|
|
172
197
|
**Key Properties:**
|
|
173
198
|
- `moduleName` (required): Module identifier
|
|
174
199
|
- `getName` (required): Function returning module name
|
|
175
|
-
- `requiredAuthMethods` (required): Authentication configuration
|
|
176
|
-
- `modelName`: Entity/credential model name used by the Module runtime
|
|
177
|
-
- Real Definitions (classes/functions) are accepted by `validateApiModuleDefinition` via a schema view.
|
|
200
|
+
- `requiredAuthMethods` (required): Authentication configuration
|
|
178
201
|
- `env`: Environment variable configuration
|
|
179
202
|
- `config`: Module-specific configuration
|
|
180
203
|
|
|
@@ -355,7 +378,12 @@ Validates core data models (User, Entity, Credential).
|
|
|
355
378
|
Returns all available schemas as an object.
|
|
356
379
|
|
|
357
380
|
#### `getSchema(schemaName)`
|
|
358
|
-
Returns a specific schema by name.
|
|
381
|
+
Returns a specific schema by name (`app-definition`), by `$id`, or by its legacy unversioned id.
|
|
382
|
+
|
|
383
|
+
#### `parseSchemaId(id)`
|
|
384
|
+
Returns `{ name, version, hostedPath }` for an `$id` on the
|
|
385
|
+
`https://friggframework.org/schemas/<name>/v<x.y>.json` pattern, or `null`.
|
|
386
|
+
`SCHEMA_ID_PATTERN` and `LEGACY_SCHEMA_IDS` are exported too.
|
|
359
387
|
|
|
360
388
|
### Utility Functions
|
|
361
389
|
|
package/index.js
CHANGED
|
@@ -16,9 +16,7 @@ const {
|
|
|
16
16
|
applyAppDefinitionDefaults,
|
|
17
17
|
toAppDefinitionSchemaView,
|
|
18
18
|
} = require('./app-definition');
|
|
19
|
-
const
|
|
20
|
-
toApiModuleDefinitionSchemaView,
|
|
21
|
-
} = require('./api-module-definition');
|
|
19
|
+
const schemaIds = require('./schema-ids');
|
|
22
20
|
|
|
23
21
|
// Initialize AJV with formats
|
|
24
22
|
const ajv = new Ajv({
|
|
@@ -52,7 +50,16 @@ schemaFiles.forEach(file => {
|
|
|
52
50
|
const schemaName = file.replace('.schema.json', '');
|
|
53
51
|
|
|
54
52
|
schemas[schemaName] = schemaContent;
|
|
55
|
-
|
|
53
|
+
schemaIds.addSchemaWithAliases(ajv, schemaContent, schemaName);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Schema name for each `$id` and legacy id, so getSchema() also accepts a URL.
|
|
57
|
+
const schemaNamesById = {};
|
|
58
|
+
Object.entries(schemas).forEach(([schemaName, schema]) => {
|
|
59
|
+
schemaNamesById[schema.$id] = schemaName;
|
|
60
|
+
(schemaIds.LEGACY_SCHEMA_IDS[schemaName] || []).forEach(legacyId => {
|
|
61
|
+
schemaNamesById[legacyId] = schemaName;
|
|
62
|
+
});
|
|
56
63
|
});
|
|
57
64
|
|
|
58
65
|
/**
|
|
@@ -102,18 +109,12 @@ function validateIntegrationDefinition(integrationDefinition) {
|
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
/**
|
|
105
|
-
* Validate API Module Definition
|
|
106
|
-
*
|
|
107
|
-
* view and return the original definition (same pattern as validateAppDefinition).
|
|
108
|
-
* @param {object} apiModuleDefinition - API module definition object to validate
|
|
112
|
+
* Validate API Module Definition
|
|
113
|
+
* @param {object} apiModuleDefinition - API module definition object to validate
|
|
109
114
|
* @returns {object} - Validation result
|
|
110
115
|
*/
|
|
111
116
|
function validateApiModuleDefinition(apiModuleDefinition) {
|
|
112
|
-
|
|
113
|
-
'api-module-definition',
|
|
114
|
-
toApiModuleDefinitionSchemaView(apiModuleDefinition)
|
|
115
|
-
);
|
|
116
|
-
return { ...result, data: apiModuleDefinition };
|
|
117
|
+
return validate('api-module-definition', apiModuleDefinition);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
/**
|
|
@@ -341,15 +342,16 @@ function getSchemas() {
|
|
|
341
342
|
}
|
|
342
343
|
|
|
343
344
|
/**
|
|
344
|
-
* Get a specific schema by name
|
|
345
|
-
* @param {string} schemaName -
|
|
345
|
+
* Get a specific schema by name or `$id`
|
|
346
|
+
* @param {string} schemaName - Schema name (`app-definition`), its `$id`, or a legacy unversioned id
|
|
346
347
|
* @returns {object} - Schema object
|
|
347
348
|
*/
|
|
348
349
|
function getSchema(schemaName) {
|
|
349
|
-
|
|
350
|
+
const name = schemas[schemaName] ? schemaName : schemaNamesById[schemaName];
|
|
351
|
+
if (!name) {
|
|
350
352
|
throw new Error(`Schema '${schemaName}' not found. Available schemas: ${Object.keys(schemas).join(', ')}`);
|
|
351
353
|
}
|
|
352
|
-
return schemas[
|
|
354
|
+
return schemas[name];
|
|
353
355
|
}
|
|
354
356
|
|
|
355
357
|
/**
|
|
@@ -378,7 +380,6 @@ module.exports = {
|
|
|
378
380
|
validateAppDefinition,
|
|
379
381
|
applyAppDefinitionDefaults,
|
|
380
382
|
toAppDefinitionSchemaView,
|
|
381
|
-
toApiModuleDefinitionSchemaView,
|
|
382
383
|
validateIntegrationDefinition,
|
|
383
384
|
validateApiModuleDefinition,
|
|
384
385
|
validateServerlessConfig,
|
|
@@ -411,6 +412,11 @@ module.exports = {
|
|
|
411
412
|
schemas,
|
|
412
413
|
ajv,
|
|
413
414
|
|
|
415
|
+
// Schema identifiers (https://friggframework.org/schemas/<name>/v<x.y>.json)
|
|
416
|
+
SCHEMA_ID_PATTERN: schemaIds.SCHEMA_ID_PATTERN,
|
|
417
|
+
LEGACY_SCHEMA_IDS: schemaIds.LEGACY_SCHEMA_IDS,
|
|
418
|
+
parseSchemaId: schemaIds.parseSchemaId,
|
|
419
|
+
|
|
414
420
|
// Middleware exports
|
|
415
421
|
middleware: schemaValidationMiddleware,
|
|
416
422
|
validateBody: schemaValidationMiddleware.validateBody,
|
|
@@ -9,6 +9,7 @@ const Ajv = require('ajv');
|
|
|
9
9
|
const addFormats = require('ajv-formats');
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
|
+
const { addSchemaWithAliases } = require('../schema-ids');
|
|
12
13
|
|
|
13
14
|
// Initialize AJV with formats
|
|
14
15
|
const ajv = new Ajv({
|
|
@@ -33,7 +34,7 @@ schemaFiles.forEach(file => {
|
|
|
33
34
|
if (fs.existsSync(schemaPath)) {
|
|
34
35
|
const schemaContent = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));
|
|
35
36
|
const schemaName = file.replace('.schema.json', '');
|
|
36
|
-
ajv
|
|
37
|
+
addSchemaWithAliases(ajv, schemaContent, schemaName);
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/schemas",
|
|
3
|
-
"version": "2.0.0--canary.
|
|
3
|
+
"version": "2.0.0--canary.705.f070722.0",
|
|
4
4
|
"description": "Canonical JSON Schema definitions for Frigg Framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"test": "jest",
|
|
21
21
|
"validate": "node scripts/validate-schemas.js",
|
|
22
|
-
"build": "node scripts/build-schemas.js"
|
|
22
|
+
"build": "node scripts/build-schemas.js",
|
|
23
|
+
"sync:hosted": "node scripts/sync-hosted-schemas.js",
|
|
24
|
+
"check:hosted": "node scripts/sync-hosted-schemas.js --check"
|
|
23
25
|
},
|
|
24
26
|
"keywords": [
|
|
25
27
|
"frigg",
|
|
@@ -40,8 +42,8 @@
|
|
|
40
42
|
"mocks/",
|
|
41
43
|
"middleware/",
|
|
42
44
|
"app-definition.js",
|
|
43
|
-
"
|
|
45
|
+
"schema-ids.js",
|
|
44
46
|
"index.js"
|
|
45
47
|
],
|
|
46
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "f070722ad939d3221446e24653352373a5f4e0f6"
|
|
47
49
|
}
|
package/schema-ids.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema identifiers (ADR-051, "Hosted schemas" amendment).
|
|
3
|
+
*
|
|
4
|
+
* Every Frigg JSON Schema has the `$id`
|
|
5
|
+
* https://friggframework.org/schemas/<name>/v<major>.<minor>.json
|
|
6
|
+
* and friggframework.org serves the file at exactly that URL. The `$id` is a
|
|
7
|
+
* name, not a location the runtime reads: validation always resolves it from
|
|
8
|
+
* this package and never fetches it.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const SCHEMA_BASE_URL = 'https://friggframework.org/';
|
|
12
|
+
|
|
13
|
+
const SCHEMA_ID_PATTERN =
|
|
14
|
+
/^https:\/\/friggframework\.org\/schemas\/([a-z0-9]+(?:-[a-z0-9]+)*)\/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.json$/;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Unversioned ids the schemas carried before 2.0.1. They never resolved over
|
|
18
|
+
* HTTP, but code may pass them to `validate()`/`getSchema()` or Ajv, so the
|
|
19
|
+
* package still registers them as aliases of the current schema.
|
|
20
|
+
*
|
|
21
|
+
* @deprecated Remove in the release after 2.0.1.
|
|
22
|
+
*/
|
|
23
|
+
const LEGACY_SCHEMA_IDS = Object.freeze({
|
|
24
|
+
'api-authorization': ['https://friggframework.org/schemas/api-authorization.json'],
|
|
25
|
+
'api-credentials': ['https://friggframework.org/schemas/api-credentials.json'],
|
|
26
|
+
'api-entities': ['https://friggframework.org/schemas/api-entities.json'],
|
|
27
|
+
'api-proxy': ['https://friggframework.org/schemas/api-proxy.json'],
|
|
28
|
+
'api-module-definition': ['https://schemas.friggframework.org/api-module-definition.schema.json'],
|
|
29
|
+
'app-definition': ['https://schemas.friggframework.org/app-definition.schema.json'],
|
|
30
|
+
'core-models': ['https://schemas.friggframework.org/core-models.schema.json'],
|
|
31
|
+
'environment-config': ['https://schemas.friggframework.org/environment-config.schema.json'],
|
|
32
|
+
'integration-definition': ['https://schemas.friggframework.org/integration-definition.schema.json'],
|
|
33
|
+
'serverless-config': ['https://schemas.friggframework.org/serverless-config.schema.json'],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parse a schema `$id`.
|
|
38
|
+
* @param {string} id
|
|
39
|
+
* @returns {{ name: string, version: string, hostedPath: string } | null}
|
|
40
|
+
* `hostedPath` is the path under the website root (`schemas/<name>/v1.0.json`).
|
|
41
|
+
*/
|
|
42
|
+
function parseSchemaId(id) {
|
|
43
|
+
const match = typeof id === 'string' ? SCHEMA_ID_PATTERN.exec(id) : null;
|
|
44
|
+
if (!match) return null;
|
|
45
|
+
const [, name, major, minor] = match;
|
|
46
|
+
const version = `${major}.${minor}`;
|
|
47
|
+
return { name, version, hostedPath: `schemas/${name}/v${version}.json` };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Register a schema with Ajv under its file name, its `$id`, and its legacy ids.
|
|
52
|
+
* @param {import('ajv').default} ajv
|
|
53
|
+
* @param {object} schema - parsed schema (its `$id` registers automatically)
|
|
54
|
+
* @param {string} name - file name without `.schema.json`
|
|
55
|
+
*/
|
|
56
|
+
function addSchemaWithAliases(ajv, schema, name) {
|
|
57
|
+
ajv.addSchema(schema, name);
|
|
58
|
+
for (const legacyId of LEGACY_SCHEMA_IDS[name] || []) {
|
|
59
|
+
ajv.addSchema({ ...schema, $id: legacyId });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
SCHEMA_BASE_URL,
|
|
65
|
+
SCHEMA_ID_PATTERN,
|
|
66
|
+
LEGACY_SCHEMA_IDS,
|
|
67
|
+
parseSchemaId,
|
|
68
|
+
addSchemaWithAliases,
|
|
69
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://friggframework.org/schemas/api-authorization.json",
|
|
3
|
+
"$id": "https://friggframework.org/schemas/api-authorization/v1.0.json",
|
|
4
4
|
"title": "Frigg Authorization API Schemas",
|
|
5
5
|
"description": "JSON schemas for authorization and authentication API requests and responses",
|
|
6
6
|
"definitions": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://friggframework.org/schemas/api-credentials.json",
|
|
3
|
+
"$id": "https://friggframework.org/schemas/api-credentials/v1.0.json",
|
|
4
4
|
"title": "Frigg Credentials API Schemas",
|
|
5
5
|
"description": "JSON schemas for credentials API requests and responses",
|
|
6
6
|
"definitions": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://friggframework.org/schemas/api-entities.json",
|
|
3
|
+
"$id": "https://friggframework.org/schemas/api-entities/v1.0.json",
|
|
4
4
|
"title": "Frigg Entities API Schemas",
|
|
5
5
|
"description": "JSON schemas for entities API requests and responses",
|
|
6
6
|
"definitions": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/api-module-definition/v1.0.json",
|
|
4
4
|
"title": "Frigg API Module Definition",
|
|
5
5
|
"description": "Schema for defining a Frigg API module including authentication, API configuration, and required methods.",
|
|
6
6
|
"type": "object",
|
|
@@ -27,13 +27,6 @@
|
|
|
27
27
|
"minLength": 1,
|
|
28
28
|
"maxLength": 100
|
|
29
29
|
},
|
|
30
|
-
"modelName": {
|
|
31
|
-
"type": "string",
|
|
32
|
-
"description": "Entity/credential model name used by the Module runtime (e.g. 'Fathom'). Distinct from moduleName, which is the package identifier.",
|
|
33
|
-
"pattern": "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
34
|
-
"minLength": 1,
|
|
35
|
-
"maxLength": 100
|
|
36
|
-
},
|
|
37
30
|
"requiredAuthMethods": {
|
|
38
31
|
"type": "object",
|
|
39
32
|
"description": "Required authentication methods and configuration",
|
|
@@ -97,22 +90,6 @@
|
|
|
97
90
|
"type": {"type": "string", "enum": ["function"]},
|
|
98
91
|
"async": {"type": "boolean", "default": true}
|
|
99
92
|
}
|
|
100
|
-
},
|
|
101
|
-
"getAuthorizationRequirements": {
|
|
102
|
-
"type": "object",
|
|
103
|
-
"description": "Method that returns the authorization requirements (type, jsonSchema/uiSchema) for non-OAuth flows such as API key",
|
|
104
|
-
"properties": {
|
|
105
|
-
"type": {"type": "string", "enum": ["function"]},
|
|
106
|
-
"async": {"type": "boolean", "default": true}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
"setAuthParams": {
|
|
110
|
-
"type": "object",
|
|
111
|
-
"description": "Method that applies authorization parameters (e.g. API key) to the API instance",
|
|
112
|
-
"properties": {
|
|
113
|
-
"type": {"type": "string", "enum": ["function"]},
|
|
114
|
-
"async": {"type": "boolean", "default": true}
|
|
115
|
-
}
|
|
116
93
|
}
|
|
117
94
|
},
|
|
118
95
|
"additionalProperties": false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://friggframework.org/schemas/api-proxy.json",
|
|
3
|
+
"$id": "https://friggframework.org/schemas/api-proxy/v1.0.json",
|
|
4
4
|
"title": "Frigg Proxy API Schemas",
|
|
5
5
|
"description": "JSON schemas for proxy API requests and responses that forward calls to external APIs",
|
|
6
6
|
"definitions": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/app-definition/v1.0.json",
|
|
4
4
|
"title": "Frigg Application Definition",
|
|
5
5
|
"description": "Schema for defining a Frigg application configuration including integrations, infrastructure, security settings, and deployment options.",
|
|
6
6
|
"type": "object",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/core-models/v1.0.json",
|
|
4
4
|
"title": "Frigg Core Data Models",
|
|
5
5
|
"description": "Schema definitions for core Frigg data models including User, Entity, and Credential.",
|
|
6
6
|
"definitions": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/environment-config/v1.0.json",
|
|
4
4
|
"title": "Frigg Environment Configuration",
|
|
5
5
|
"description": "Schema for environment variable configuration and validation in Frigg applications.",
|
|
6
6
|
"type": "object",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/integration-definition/v1.0.json",
|
|
4
4
|
"title": "Frigg Integration Definition",
|
|
5
5
|
"description": "Schema for defining a Frigg integration including configuration, options, and display properties.",
|
|
6
6
|
"type": "object",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://friggframework.org/schemas/serverless-config/v1.0.json",
|
|
4
4
|
"title": "Frigg Serverless Configuration",
|
|
5
5
|
"description": "Schema for Serverless Framework configuration used in Frigg applications for AWS deployment.",
|
|
6
6
|
"type": "object",
|
package/api-module-definition.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API module definition helpers shared by validators and the frigg CLI.
|
|
3
|
-
* Real Definitions carry classes and functions that JSON Schema cannot
|
|
4
|
-
* describe; validators check the serialisable view produced here.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
function isPlainObject(value) {
|
|
8
|
-
if (value === null || typeof value !== 'object') return false;
|
|
9
|
-
const proto = Object.getPrototypeOf(value);
|
|
10
|
-
return proto === Object.prototype || proto === null;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Schema descriptor for a JavaScript function (see api-module-definition
|
|
15
|
-
* schema: `{ type: "function", async?: boolean }`).
|
|
16
|
-
*
|
|
17
|
-
* @param {Function} fn
|
|
18
|
-
* @returns {{ type: 'function', async?: boolean }}
|
|
19
|
-
*/
|
|
20
|
-
function toFunctionDescriptor(fn) {
|
|
21
|
-
const descriptor = { type: 'function' };
|
|
22
|
-
if (fn && fn.constructor && fn.constructor.name === 'AsyncFunction') {
|
|
23
|
-
descriptor.async = true;
|
|
24
|
-
}
|
|
25
|
-
return descriptor;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* JSON Schema cannot describe a JavaScript class or function. Validators
|
|
30
|
-
* therefore check this serialisable view: the API class becomes an empty
|
|
31
|
-
* object, functions become `{ type: "function" }` descriptors, and
|
|
32
|
-
* `undefined` env values are dropped (unset `process.env.*` entries).
|
|
33
|
-
*
|
|
34
|
-
* @param {object} definition the `Definition` exported by an API module
|
|
35
|
-
* @returns {object} a view suitable for the api-module-definition schema
|
|
36
|
-
*/
|
|
37
|
-
function toApiModuleDefinitionSchemaView(definition) {
|
|
38
|
-
if (!isPlainObject(definition)) return definition;
|
|
39
|
-
|
|
40
|
-
const view = { ...definition };
|
|
41
|
-
|
|
42
|
-
if (typeof view.API === 'function') {
|
|
43
|
-
view.API = {};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (typeof view.getName === 'function') {
|
|
47
|
-
view.getName = toFunctionDescriptor(view.getName);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (isPlainObject(view.requiredAuthMethods)) {
|
|
51
|
-
const methods = { ...view.requiredAuthMethods };
|
|
52
|
-
for (const [key, value] of Object.entries(methods)) {
|
|
53
|
-
if (typeof value === 'function') {
|
|
54
|
-
methods[key] = toFunctionDescriptor(value);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
view.requiredAuthMethods = methods;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (isPlainObject(view.env)) {
|
|
61
|
-
const env = {};
|
|
62
|
-
for (const [key, value] of Object.entries(view.env)) {
|
|
63
|
-
if (value !== undefined) env[key] = value;
|
|
64
|
-
}
|
|
65
|
-
view.env = env;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (isPlainObject(view.manager)) {
|
|
69
|
-
const manager = { ...view.manager };
|
|
70
|
-
for (const key of ['Entity', 'Credential']) {
|
|
71
|
-
if (typeof manager[key] === 'function') {
|
|
72
|
-
manager[key] = {};
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (isPlainObject(manager.methods)) {
|
|
76
|
-
const methods = { ...manager.methods };
|
|
77
|
-
for (const [key, value] of Object.entries(methods)) {
|
|
78
|
-
if (typeof value === 'function') {
|
|
79
|
-
methods[key] = {};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
manager.methods = methods;
|
|
83
|
-
}
|
|
84
|
-
view.manager = manager;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return view;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
module.exports = {
|
|
91
|
-
toApiModuleDefinitionSchemaView,
|
|
92
|
-
toFunctionDescriptor,
|
|
93
|
-
};
|