From 0a4a3e3961edf7d8d5d7a6c8ac28bff8757f1c5f Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 04:31:44 -0300 Subject: [PATCH 1/7] chores: add W-18830464 API specifications and examples - Introduced new API specifications for W-18830464, including JSON and YAML files. - Implemented example requests and responses for testing. - Updated ExampleGenerator to handle new data formats and improve raw data processing. - Created unit tests to validate the new API examples. --- demo/W-18830464/W-18830464.json | 118 ++++++++++++++++++ demo/W-18830464/common/common-header.json | 40 ++++++ .../request/test-otr-eapi-request.json | 45 +++++++ .../response/test-otr-eapi-response.json | 24 ++++ .../request/test-otr-eapi-request-schema.json | 62 +++++++++ .../test-otr-eapi-response-schema.json | 33 +++++ demo/index.js | 3 +- demo/model.js | 1 + src/ExampleGenerator.js | 78 +++++++++--- test/W-18830464.test.js | 63 ++++++++++ 10 files changed, 450 insertions(+), 17 deletions(-) create mode 100644 demo/W-18830464/W-18830464.json create mode 100644 demo/W-18830464/common/common-header.json create mode 100644 demo/W-18830464/examples/request/test-otr-eapi-request.json create mode 100644 demo/W-18830464/examples/response/test-otr-eapi-response.json create mode 100644 demo/W-18830464/schema/request/test-otr-eapi-request-schema.json create mode 100644 demo/W-18830464/schema/response/test-otr-eapi-response-schema.json create mode 100644 test/W-18830464.test.js diff --git a/demo/W-18830464/W-18830464.json b/demo/W-18830464/W-18830464.json new file mode 100644 index 0000000..a46d0bd --- /dev/null +++ b/demo/W-18830464/W-18830464.json @@ -0,0 +1,118 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "test-otr-eapi" + }, + "components": { + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" + } + } + }, + "security": [ + { + "basicAuth": [] + } + ], + "paths": { + "/asset": { + "post": { + "description": "Create a span", + "parameters": [ + { + "$ref": "common/common-header.json#components/parameters/SourceHeader" + }, + { + "$ref": "common/common-header.json#components/parameters/TargetHeader" + }, + { + "$ref": "common/common-header.json#components/parameters/correlationId" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "schema/request/test-otr-eapi-request-schema.json#/components/schemas/createAsset" + }, + "examples": { + "createAsset": { + "$ref": "examples/request/test-otr-eapi-request.json#/components/examples/createAsset" + } + } + } + } + }, + "responses": { + "200": { + "description": "Span created", + "content": { + "application/json": { + "schema": { + "$ref": "schema/response/test-otr-eapi-response-schema.json#/components/schemas/createAsset" + }, + "examples": { + "createAsset": { + "$ref": "examples/response/test-otr-eapi-response.json#/components/examples/createAsset" + } + } + } + } + } + } + } + }, + "/preferences": { + "post": { + "description": "Create a preferences", + "parameters": [ + { + "$ref": "common/common-header.json#components/parameters/SourceHeader" + }, + { + "$ref": "common/common-header.json#components/parameters/TargetHeader" + }, + { + "$ref": "common/common-header.json#components/parameters/correlationId" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "schema/request/test-otr-eapi-request-schema.json#/components/schemas/createPreferences" + }, + "examples": { + "createPreferences": { + "$ref": "examples/request/test-otr-eapi-request.json#/components/examples/createPreferences" + } + } + } + } + }, + "responses": { + "200": { + "description": "Preferences created", + "content": { + "application/json": { + "schema": { + "$ref": "schema/response/test-otr-eapi-response-schema.json#/components/schemas/createPreferences" + }, + "examples": { + "CreateSpanRes": { + "$ref": "examples/response/test-otr-eapi-response.json#/components/examples/createPreferences" + } + } + } + } + } + } + } + } + } + } diff --git a/demo/W-18830464/common/common-header.json b/demo/W-18830464/common/common-header.json new file mode 100644 index 0000000..e5dc35d --- /dev/null +++ b/demo/W-18830464/common/common-header.json @@ -0,0 +1,40 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "common-header" + }, + "components": { + "parameters": { + "SourceHeader": { + "description": "Source-System", + "in": "header", + "name": "Source-System", + "schema": { + "type": "string" + }, + "required": true, + "example": "SAP" + }, + "TargetHeader": { + "description": "Target-System", + "in": "header", + "name": "Target-System", + "schema": { + "type": "string" + }, + "required": true, + "example": "Salesforce" + }, + "correlationId": { + "in": "header", + "name": "X-Correlation-Id", + "schema": { + "type": "string" + }, + "required": true, + "example": "1065fe6c-9121-4b05-b6e3-df5c0cb42461" + } + } + } +} \ No newline at end of file diff --git a/demo/W-18830464/examples/request/test-otr-eapi-request.json b/demo/W-18830464/examples/request/test-otr-eapi-request.json new file mode 100644 index 0000000..98df778 --- /dev/null +++ b/demo/W-18830464/examples/request/test-otr-eapi-request.json @@ -0,0 +1,45 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "test-otr-eapi-request" + }, + "components": { + "examples": { + "createAsset" : { + "value" : [ + { + "spanID": "ENGYALERT", + "name": "EMAIL1", + "description": "CCB_IDL_Provider" + + } + ] + }, + "createPreferences" : { + "value" : [ + { + "programID": "ENERGYALERT", + "channelID": "EMAIL", + "userID": "CCB_IDL_Provider", + "customProperties": [ + { + "link": 0 + } + ] + }, + { + "programID": "ENERGYALERT", + "channelID": "EMAIL", + "userID": "CCB_IDL_Provider", + "customProperties": [ + { + "link": 0 + } + ] + } + ] + } + } + } +} \ No newline at end of file diff --git a/demo/W-18830464/examples/response/test-otr-eapi-response.json b/demo/W-18830464/examples/response/test-otr-eapi-response.json new file mode 100644 index 0000000..7badd5c --- /dev/null +++ b/demo/W-18830464/examples/response/test-otr-eapi-response.json @@ -0,0 +1,24 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "test-otr-eapi-response" + }, + "components": { + "examples" : { + "createAsset" : { + "value": { + "id": "", + "msg" : "" + } + }, + "createPreferences" : { + "value": { + "id": "", + "msg" : "" + } + } + } + } + +} \ No newline at end of file diff --git a/demo/W-18830464/schema/request/test-otr-eapi-request-schema.json b/demo/W-18830464/schema/request/test-otr-eapi-request-schema.json new file mode 100644 index 0000000..965795c --- /dev/null +++ b/demo/W-18830464/schema/request/test-otr-eapi-request-schema.json @@ -0,0 +1,62 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "test-otr-eapi-request-schema" + }, + "components": { + "schemas": { + "createAsset": { + "type": "array", + "items": { + "type": "object", + "properties": { + "spanId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + }, + "createPreferences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "programId": { + "type": "string" + }, + "channelId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "customProperties" : { + "type" : "array", + "items": { + "type": "object", + "properties": { + "link": { + "type": "integer" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/demo/W-18830464/schema/response/test-otr-eapi-response-schema.json b/demo/W-18830464/schema/response/test-otr-eapi-response-schema.json new file mode 100644 index 0000000..512a8b3 --- /dev/null +++ b/demo/W-18830464/schema/response/test-otr-eapi-response-schema.json @@ -0,0 +1,33 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "test-otr-eapi-response-schema" + }, + "components": { + "schemas" : { + "createAsset" : { + "type" : "object", + "properties": { + "id" : { + "type" : "string" + }, + "msg" : { + "type": "string" + } + } + }, + "createPreferences" : { + "type" : "object", + "properties": { + "id" : { + "type" : "string" + }, + "msg" : { + "type": "string" + } + } + } + } +} +} \ No newline at end of file diff --git a/demo/index.js b/demo/index.js index 02e49cf..81dc5ce 100644 --- a/demo/index.js +++ b/demo/index.js @@ -126,7 +126,8 @@ class ComponentDemo extends ApiDemoPage { ['W-11843862', 'W-11843862'], ['W-17309546', 'W-17309546'], ['W-17413312', 'W-17413312'], - ['v4_0_0_api_specs', 'v4_0_0_api_specs'] + ['v4_0_0_api_specs', 'v4_0_0_api_specs'], + ['W-18830464', 'W-18830464'] ].map( ([file, label]) => html` { - const shapeFragment = this._computeReferences(item) - const externalFragments = this._computeReferences(shapeFragment) + const encodesOfExternalFragments = rootReferences.flat().map((item) => { + const shapeFragment = this._computeReferences(item); + const externalFragments = this._computeReferences(shapeFragment[0]); // Get second element from externalFragments - const externalFragmentExample = externalFragments[1] - return this._computeEncodes(externalFragmentExample) - }) + const externalFragmentExample = externalFragments[1]; + return this._computeEncodes(externalFragmentExample); + }); // It finds an element in encodesOfExternalFragments where // the @id property matches referenceId and assigns @@ -733,13 +733,13 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { if (hasRaw) { if (isJson) { try { - const res = JSON.parse(raw); + const res = JSON.parse(String(raw)); const type = typeof res; if (type === 'string' || type === 'number' || type === 'boolean') { throw new Error(''); } result.hasRaw = false; - result.value = raw; + result.value = JSON.stringify(res, null, 2); result.isScalar = false; return result; } catch (_) { @@ -747,15 +747,16 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { } } if (isXml) { - if (raw.trim()[0] === '<') { + const rawValue = String(raw); + if (rawValue.trim()[0] === '<') { result.hasRaw = false; - result.value = raw; + result.value = rawValue; result.isScalar = false; return result; } } result.hasRaw = true; - result.raw = raw; + result.raw = String(raw); } const sKey = this._getAmfKey( this.ns.aml.vocabularies.document.structuredValue @@ -794,11 +795,13 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { let data; if (isJson) { data = this._jsonFromStructure(member); - } else if (isXml) { - data = this._xmlFromStructure(member, { ...opts, ignoreXmlHeader: true }); + data = this._xmlFromStructure(member, { + ...opts, + ignoreXmlHeader: true, + }); } - if (data) { + if (data !== undefined) { parts.push(data); } }); @@ -807,7 +810,7 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { // if the parse process fails then use parts to build example value if (result.raw) { try { - result.value = this.computeRaw(raw) + result.value = this.computeRaw(raw); return result } catch (_) { // ... @@ -881,7 +884,7 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { * @param {String} raw * @returns string JSON formatted */ - computeRaw(raw) { + computeRawOld(raw) { const accountEntries = raw.split('-\n'); const parsed = this.parseToJSON(accountEntries) // Ensure the parsed result is always an array @@ -890,6 +893,49 @@ export class ExampleGenerator extends AmfHelperMixin(Object) { } + computeRaw(raw) { + if (typeof raw !== 'string') { + return JSON.stringify(raw); + } + // A very basic check for a simple YAML list. + const trimmed = raw.trim(); + if (trimmed.startsWith('-') && trimmed.indexOf(':') === -1) { + const items = trimmed + .split('\n') + .map((v) => v.trim().replace(/^-/, '').trim()); + const values = items.map((v) => { + const n = Number(v); + return isNaN(n) ? v : n; + }); + return JSON.stringify(values, null, 2); + } + + // Split the string into blocks separated by hyphens + const blocks = raw.split('-\n').filter((block) => block.trim() !== ''); + + // Process each block to convert it into an object + const sanitized = blocks.map((block) => { + const lines = block.split('\n').filter((line) => line.trim() !== ''); + const obj = {}; + + lines.forEach((line) => { + const i = line.indexOf(':'); + const key = line.slice(0, i).trim().replace(/^"|"$/g, ''); + const value = line.slice(i + 1).trim(); + if (value.startsWith('"') && value.endsWith('"')) { + obj[key] = value.slice(1, -1); + } else { + const numericValue = Number(value); + obj[key] = isNaN(numericValue) ? value : numericValue; + } + }); + + return obj; + }); + + // Convert to clean JSON string + return JSON.stringify(sanitized, null, 2); + } /** * Computes list of examples for an array shape. * @param {Object} schema The AMF's array shape diff --git a/test/W-18830464.test.js b/test/W-18830464.test.js new file mode 100644 index 0000000..4cc6180 --- /dev/null +++ b/test/W-18830464.test.js @@ -0,0 +1,63 @@ +import { fixture, assert, html } from '@open-wc/testing'; +import { AmfLoader } from './amf-loader.js'; +import '../api-example-generator.js'; + +describe('W-18830464', () => { + async function basicFixture(amf) { + return (await fixture(html``)); + } + + const apiFile = 'W-18830464'; + + [ + ['json+ld data model', false], + ['Compact data model', true] + ].forEach(([label, compact]) => { + describe(label, () => { + let element; + let amf; + + before(async () => { + amf = await AmfLoader.load(compact, apiFile); + }); + + beforeEach(async () => { + element = await basicFixture(amf); + }); + + it('renders examples right', () => { + const payloads = AmfLoader.lookupPayload( + amf, + '/preferences', + 'post' + ); + const result = element.generatePayloadsExamples( + payloads, + 'application/json' + ); + const item = result[0]; + assert.equal(item.value, `[ + { + "programID": "ENERGYALERT", + "channelID": "EMAIL", + "userID": "CCB_IDL_Provider", + "customProperties": 0 + }, + { + "link": 0 + }, + { + "programID": "ENERGYALERT", + "channelID": "EMAIL", + "userID": "CCB_IDL_Provider", + "customProperties": 0 + }, + { + "link": 0 + } +]`); + }); + }); + }); +}); From 223db6d4dbf99f02dacebd040763df9769d55853 Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:44:12 -0300 Subject: [PATCH 2/7] fix: update deployment workflow to use npm ci and remove Windows testing --- .github/workflows/deployment.yml | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 698be5c..9e9c79f 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -18,12 +18,13 @@ jobs: fail-fast: false matrix: os: [ubuntu-20.04] + # os: [ubuntu-18.04, ubuntu-20.04] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 16 + node-version: 18 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -32,34 +33,15 @@ jobs: restore-keys: | ${{ runner.os }}-node- - name: Install dependencies - run: npm install - - name: Run tests - run: npm test - test_win: - name: "Windows" - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 16 - - uses: microsoft/playwright-github-action@v1 - - uses: actions/cache@v3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - name: Install dependencies - run: npm install + run: npm ci - name: Run tests run: npm test tag: name: "Publishing release" if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' - needs: + needs: - test_linux - - test_win + # - test_win runs-on: ubuntu-latest steps: - name: Checkout code From 6128c45bdced67c8fa6cb9312b273e2e7abc4f2b Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:47:03 -0300 Subject: [PATCH 3/7] fix: update deployment workflow to support Windows testing and upgrade Node.js version to 18 --- .github/workflows/deployment.yml | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 9e9c79f..50efd4d 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -18,7 +18,6 @@ jobs: fail-fast: false matrix: os: [ubuntu-20.04] - # os: [ubuntu-18.04, ubuntu-20.04] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 @@ -36,12 +35,31 @@ jobs: run: npm ci - name: Run tests run: npm test + test_win: + name: "Windows" + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 18 + - uses: microsoft/playwright-github-action@v1 + - uses: actions/cache@v3 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - name: Install dependencies + run: npm ci + - name: Run tests + run: npm test tag: name: "Publishing release" if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' - needs: + needs: - test_linux - # - test_win + - test_win runs-on: ubuntu-latest steps: - name: Checkout code @@ -50,7 +68,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v2 with: - node-version: '16.x' + node-version: '18.x' registry-url: 'https://registry.npmjs.org' - uses: actions/cache@v3 with: From 1e3665c71b3e1c7dec05be336ab589ed4c098f39 Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:48:23 -0300 Subject: [PATCH 4/7] fix: downgrade Node.js version in deployment workflow from 18 to 16 --- .github/workflows/deployment.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 50efd4d..4da461c 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 18 + node-version: 16 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 18 + node-version: 16 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -68,7 +68,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v2 with: - node-version: '18.x' + node-version: '16.x' registry-url: 'https://registry.npmjs.org' - uses: actions/cache@v3 with: From d88e5e4deef0aa9461e6b0239126aaeeb8a1de4a Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:50:59 -0300 Subject: [PATCH 5/7] fix: update deployment workflow to use Ubuntu 22.04 and change Node.js version to 1 --- .github/workflows/deployment.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 4da461c..82d1184 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -17,13 +17,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04] + os: [ubuntu-22.04] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 16 + node-version: 1 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -32,7 +32,7 @@ jobs: restore-keys: | ${{ runner.os }}-node- - name: Install dependencies - run: npm ci + run: npm install - name: Run tests run: npm test test_win: @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 16 + node-version: 1 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -51,7 +51,7 @@ jobs: restore-keys: | ${{ runner.os }}-node- - name: Install dependencies - run: npm ci + run: npm install - name: Run tests run: npm test tag: From f606d4380f485d176b75522e7279b8ac44c1d1b6 Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:52:21 -0300 Subject: [PATCH 6/7] fix: update Node.js version in deployment workflow from 1 and 16 to 18 --- .github/workflows/deployment.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 82d1184..c1027e2 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 1 + node-version: 18 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 1 + node-version: 18 - uses: microsoft/playwright-github-action@v1 - uses: actions/cache@v3 with: @@ -68,7 +68,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v2 with: - node-version: '16.x' + node-version: '18.x' registry-url: 'https://registry.npmjs.org' - uses: actions/cache@v3 with: From 1c1bae4c3bc69a222ef380658e7d25b5db7ea062 Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 17 Jul 2025 08:55:55 -0300 Subject: [PATCH 7/7] 4.4.33 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60d2425..eb4ff99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@api-components/api-example-generator", - "version": "4.4.32", + "version": "4.4.33", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@api-components/api-example-generator", - "version": "4.4.32", + "version": "4.4.33", "license": "Apache-2.0", "dependencies": { "@api-components/amf-helper-mixin": "^4.5.24", diff --git a/package.json b/package.json index 20756a6..8966412 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@api-components/api-example-generator", "description": "Examples generator from AMF model", - "version": "4.4.32", + "version": "4.4.33", "license": "Apache-2.0", "main": "index.js", "module": "index.js",