@kravc/dos 2.0.0-alpha.22 → 2.0.0-alpha.23

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.
@@ -16,7 +16,9 @@
16
16
  "Bash(node -e \"const ZSchema = require\\(''''/Users/ok/dev/dos/dos/node_modules/z-schema''''\\); console.log\\(Object.getOwnPropertyNames\\(ZSchema.prototype\\).join\\(''''\\\\n''''\\)\\)\")",
17
17
  "Bash(node:*)",
18
18
  "Bash(npx tsc@5.9.3 --noEmit)",
19
- "Bash(npm test:*)"
19
+ "Bash(npm test:*)",
20
+ "Bash(npx jest:*)",
21
+ "Bash(npm run:*)"
20
22
  ]
21
23
  }
22
24
  }
@@ -0,0 +1,9 @@
1
+ name: ExampleDocument
2
+ attributes:
3
+ - name: title
4
+ title: Title
5
+ description: Title of the document
6
+ required: true
7
+ type: string
8
+ isEnum: false
9
+ isArray: false
@@ -0,0 +1,5 @@
1
+ name: ExampleEnum
2
+ values:
3
+ - value: ExampleValue
4
+ name: ''
5
+ description: ''
@@ -0,0 +1,9 @@
1
+ operationId: ExampleOperation
2
+ baseAction: Read
3
+ isPublic: true
4
+ isSystem: false
5
+ permissions: []
6
+ summary: Example operation.
7
+ description: Example operation demonstrating the composer operation format.
8
+ query: {}
9
+ mutation: {}
@@ -0,0 +1,9 @@
1
+ operationId: ExampleOperation
2
+ query:
3
+ - name: id
4
+ title: ID
5
+ description: ID of the example resource
6
+ required: true
7
+ type: string
8
+ isEnum: false
9
+ isArray: false
@@ -0,0 +1,17 @@
1
+ code: E1
2
+ title: exampleScenario
3
+ summary: Example scenario demonstrating basic operation flow
4
+ parameters:
5
+ - name: id
6
+ value: EXAMPLE_1
7
+ variableNames:
8
+ - id
9
+ steps:
10
+ - summary: Operation is executed successfully
11
+ role: USER
12
+ operationId: ExampleOperation
13
+ parameters:
14
+ - name: id
15
+ result:
16
+ - has:
17
+ path: id
@@ -0,0 +1,9 @@
1
+ name: ExampleSchema
2
+ attributes:
3
+ - name: id
4
+ title: ID
5
+ description: Unique identifier
6
+ required: true
7
+ type: string
8
+ isEnum: false
9
+ isArray: false
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerMiddleware.d.ts","sourceRoot":"","sources":["../../src/Service/useComposerMiddleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAc1C,8DAA8D;AAC9D,QAAA,MAAM,qBAAqB,GAAI,UAAU,OAAO,EAAE,SAAS,OAAO;;;;;;QAqCjE,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"useComposerMiddleware.d.ts","sourceRoot":"","sources":["../../src/Service/useComposerMiddleware.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA6B1C,8DAA8D;AAC9D,QAAA,MAAM,qBAAqB,GAAI,UAAU,OAAO,EAAE,SAAS,OAAO;;;;;;QA0BjE,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -1,35 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const fs_1 = require("fs");
4
+ const path_1 = require("path");
4
5
  const js_yaml_1 = require("js-yaml");
5
6
  const useOasMiddleware_1 = require("./useOasMiddleware");
6
7
  const ROOT_PATH = process.cwd();
7
- const COMPOSER_FILES = [
8
- '/Enums.yaml',
9
- '/Schemas.yaml',
10
- '/Documents.yaml',
11
- '/Scenarios.yaml',
12
- '/Operations.yaml',
13
- '/Parameters.yaml'
14
- ];
8
+ const COMPOSER_DIR_MAP = {
9
+ '/Enums.yaml': 'enums',
10
+ '/Schemas.yaml': 'schemas',
11
+ '/Documents.yaml': 'documents',
12
+ '/Scenarios.yaml': 'scenarios',
13
+ '/Operations.yaml': 'operations',
14
+ '/Parameters.yaml': 'parameters',
15
+ };
16
+ /** Reads all YAML files in a directory and returns their parsed contents as an array. */
17
+ const readYamlDir = (dirPath) => (0, fs_1.readdirSync)(dirPath)
18
+ .filter(entry => entry.endsWith('.yaml') || entry.endsWith('.yml'))
19
+ .map(entry => (0, js_yaml_1.load)((0, fs_1.readFileSync)((0, path_1.join)(dirPath, entry), 'utf8')));
20
+ /** Reads operations directory and returns operations grouped by document (subdirectory name). */
21
+ const readOperationsDir = (dirPath) => (0, fs_1.readdirSync)(dirPath)
22
+ .filter(entry => (0, fs_1.statSync)((0, path_1.join)(dirPath, entry)).isDirectory())
23
+ .map(document => ({
24
+ document,
25
+ operations: readYamlDir((0, path_1.join)(dirPath, document)),
26
+ }));
15
27
  /** Returns result if request is for service composer file. */
16
28
  const useComposerMiddleware = (_service, context) => {
17
29
  const { httpPath, httpMethod, isDevelopment } = context;
18
30
  const isGetRequest = httpMethod === 'get';
19
- /** Returns specified composer source file. */
20
- const readFileJson = (httpPath) => {
21
- const fileName = httpPath.replace('/', '');
22
- const composerSource = (0, js_yaml_1.load)((0, fs_1.readFileSync)(`${ROOT_PATH}/.composer/${fileName}`, 'utf8'));
23
- return JSON.stringify(composerSource, null, 2);
24
- };
25
- const isComposerPath = COMPOSER_FILES.includes(httpPath);
26
- const shouldReturnComposerSource = isDevelopment &&
27
- isGetRequest &&
28
- isComposerPath;
31
+ const composerDir = COMPOSER_DIR_MAP[httpPath];
32
+ const shouldReturnComposerSource = isDevelopment && isGetRequest && !!composerDir;
29
33
  if (!shouldReturnComposerSource) {
30
34
  return null;
31
35
  }
32
- const bodyJson = readFileJson(httpPath);
36
+ const dirPath = (0, path_1.join)(ROOT_PATH, '.composer', composerDir);
37
+ const data = httpPath === '/Operations.yaml' ? readOperationsDir(dirPath) : readYamlDir(dirPath);
38
+ const bodyJson = JSON.stringify(data, null, 2);
33
39
  return {
34
40
  headers: {
35
41
  'Content-Type': useOasMiddleware_1.JSON_TYPE
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerMiddleware.js","sourceRoot":"","sources":["../../src/Service/useComposerMiddleware.ts"],"names":[],"mappings":";;AAAA,2BAAkC;AAClC,qCAA+B;AAE/B,yDAA0D;AAE1D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAEhC,MAAM,cAAc,GAAG;IACrB,aAAa;IACb,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,kBAAkB;CACnB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,qBAAqB,GAAG,CAAC,QAAiB,EAAE,OAAgB,EAAE,EAAE;IACpE,MAAM,EACJ,QAAQ,EACR,UAAU,EACV,aAAa,EACd,GAAG,OAAO,CAAC;IAEZ,MAAM,YAAY,GAAG,UAAU,KAAK,KAAK,CAAC;IAE1C,8CAA8C;IAC9C,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,cAAc,GAAG,IAAA,cAAI,EAAC,IAAA,iBAAY,EAAC,GAAG,SAAS,cAAc,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAExF,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzD,MAAM,0BAA0B,GAC9B,aAAa;QACb,YAAY;QACZ,cAAc,CAAC;IAEjB,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAExC,OAAO;QACL,OAAO,EAAE;YACP,cAAc,EAAE,4BAAS;SAC1B;QACD,UAAU,EAAE,4BAAS;QACrB,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"useComposerMiddleware.js","sourceRoot":"","sources":["../../src/Service/useComposerMiddleware.ts"],"names":[],"mappings":";;AAAA,2BAAyD;AACzD,+BAA4B;AAC5B,qCAA+B;AAE/B,yDAA0D;AAE1D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAEhC,MAAM,gBAAgB,GAA2B;IAC/C,aAAa,EAAE,OAAO;IACtB,eAAe,EAAE,SAAS;IAC1B,iBAAiB,EAAE,WAAW;IAC9B,iBAAiB,EAAE,WAAW;IAC9B,kBAAkB,EAAE,YAAY;IAChC,kBAAkB,EAAE,YAAY;CACjC,CAAC;AAEF,yFAAyF;AACzF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAa,EAAE,CACjD,IAAA,gBAAW,EAAC,OAAO,CAAC;KACjB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KAClE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAA,cAAI,EAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAEpE,iGAAiG;AACjG,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAa,EAAE,CACvD,IAAA,gBAAW,EAAC,OAAO,CAAC;KACjB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAA,aAAQ,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;KAC7D,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChB,QAAQ;IACR,UAAU,EAAE,WAAW,CAAC,IAAA,WAAI,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;CACjD,CAAC,CAAC,CAAC;AAER,8DAA8D;AAC9D,MAAM,qBAAqB,GAAG,CAAC,QAAiB,EAAE,OAAgB,EAAE,EAAE;IACpE,MAAM,EACJ,QAAQ,EACR,UAAU,EACV,aAAa,EACd,GAAG,OAAO,CAAC;IAEZ,MAAM,YAAY,GAAG,UAAU,KAAK,KAAK,CAAC;IAC1C,MAAM,WAAW,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,0BAA0B,GAAG,aAAa,IAAI,YAAY,IAAI,CAAC,CAAC,WAAW,CAAC;IAElF,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,QAAQ,KAAK,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACjG,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAE/C,OAAO;QACL,OAAO,EAAE;YACP,cAAc,EAAE,4BAAS;SAC1B;QACD,UAAU,EAAE,4BAAS;QACrB,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,qBAAqB,CAAC"}
package/jest.config.mjs CHANGED
@@ -3,5 +3,9 @@ export default {
3
3
  preset: 'ts-jest',
4
4
  testMatch: ['<rootDir>/src/**/*.test.ts'],
5
5
  maxWorkers: 1,
6
- collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
6
+ collectCoverageFrom: [
7
+ '<rootDir>/src/**/*.ts',
8
+ '!<rootDir>/src/**/index.ts',
9
+ '!<rootDir>/src/**/*.d.ts',
10
+ ],
7
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kravc/dos",
3
- "version": "2.0.0-alpha.22",
3
+ "version": "2.0.0-alpha.23",
4
4
  "description": "Convention-based, easy-to-use library for building API-driven serverless services.",
5
5
  "keywords": [
6
6
  "Service",
@@ -192,6 +192,26 @@ describe('Service', () => {
192
192
  expect(statusCode).toEqual(200);
193
193
  });
194
194
 
195
+ it('returns operations grouped by document for /Operations.yaml path', async () => {
196
+ const request = {
197
+ path: '/Operations.yaml',
198
+ method: 'get'
199
+ } as HttpRequest;
200
+
201
+ const { statusCode, body } = await service.process(request);
202
+
203
+ expect(statusCode).toEqual(200);
204
+
205
+ const data = JSON.parse(body!);
206
+
207
+ expect(data).toEqual(expect.arrayContaining([
208
+ expect.objectContaining({
209
+ document: expect.any(String),
210
+ operations: expect.any(Array),
211
+ }),
212
+ ]));
213
+ });
214
+
195
215
  it('supports operations without parameters', async () => {
196
216
  const request = {
197
217
  path: '/Health',
@@ -1,18 +1,34 @@
1
- import { readFileSync } from 'fs';
1
+ import { readFileSync, readdirSync, statSync } from 'fs';
2
+ import { join } from 'path';
2
3
  import { load } from 'js-yaml';
3
4
  import type { Context } from '../Context';
4
5
  import { OK_STATUS, JSON_TYPE } from './useOasMiddleware';
5
6
 
6
7
  const ROOT_PATH = process.cwd();
7
8
 
8
- const COMPOSER_FILES = [
9
- '/Enums.yaml',
10
- '/Schemas.yaml',
11
- '/Documents.yaml',
12
- '/Scenarios.yaml',
13
- '/Operations.yaml',
14
- '/Parameters.yaml'
15
- ];
9
+ const COMPOSER_DIR_MAP: Record<string, string> = {
10
+ '/Enums.yaml': 'enums',
11
+ '/Schemas.yaml': 'schemas',
12
+ '/Documents.yaml': 'documents',
13
+ '/Scenarios.yaml': 'scenarios',
14
+ '/Operations.yaml': 'operations',
15
+ '/Parameters.yaml': 'parameters',
16
+ };
17
+
18
+ /** Reads all YAML files in a directory and returns their parsed contents as an array. */
19
+ const readYamlDir = (dirPath: string): unknown[] =>
20
+ readdirSync(dirPath)
21
+ .filter(entry => entry.endsWith('.yaml') || entry.endsWith('.yml'))
22
+ .map(entry => load(readFileSync(join(dirPath, entry), 'utf8')));
23
+
24
+ /** Reads operations directory and returns operations grouped by document (subdirectory name). */
25
+ const readOperationsDir = (dirPath: string): unknown[] =>
26
+ readdirSync(dirPath)
27
+ .filter(entry => statSync(join(dirPath, entry)).isDirectory())
28
+ .map(document => ({
29
+ document,
30
+ operations: readYamlDir(join(dirPath, document)),
31
+ }));
16
32
 
17
33
  /** Returns result if request is for service composer file. */
18
34
  const useComposerMiddleware = (_service: unknown, context: Context) => {
@@ -23,27 +39,16 @@ const useComposerMiddleware = (_service: unknown, context: Context) => {
23
39
  } = context;
24
40
 
25
41
  const isGetRequest = httpMethod === 'get';
26
-
27
- /** Returns specified composer source file. */
28
- const readFileJson = (httpPath: string) => {
29
- const fileName = httpPath.replace('/', '');
30
- const composerSource = load(readFileSync(`${ROOT_PATH}/.composer/${fileName}`, 'utf8'));
31
-
32
- return JSON.stringify(composerSource, null, 2);
33
- };
34
-
35
- const isComposerPath = COMPOSER_FILES.includes(httpPath);
36
-
37
- const shouldReturnComposerSource =
38
- isDevelopment &&
39
- isGetRequest &&
40
- isComposerPath;
42
+ const composerDir = COMPOSER_DIR_MAP[httpPath];
43
+ const shouldReturnComposerSource = isDevelopment && isGetRequest && !!composerDir;
41
44
 
42
45
  if (!shouldReturnComposerSource) {
43
46
  return null;
44
47
  }
45
48
 
46
- const bodyJson = readFileJson(httpPath);
49
+ const dirPath = join(ROOT_PATH, '.composer', composerDir);
50
+ const data = httpPath === '/Operations.yaml' ? readOperationsDir(dirPath) : readYamlDir(dirPath);
51
+ const bodyJson = JSON.stringify(data, null, 2);
47
52
 
48
53
  return {
49
54
  headers: {
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- []
@@ -1 +0,0 @@
1
- []