Skip to content

Commit 892542f

Browse files
committed
retrieve
1 parent cfe92a0 commit 892542f

File tree

7 files changed

+8340
-3047
lines changed

7 files changed

+8340
-3047
lines changed

.github/workflows/build.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright 2024 Ronan LE MEILLAT
2+
# Licensed under the Affero GPL v3
3+
name: Build and Deploy
4+
5+
on:
6+
push:
7+
branches:
8+
- main
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: write
13+
pages: write
14+
id-token: write
15+
packages: write
16+
attestations: write
17+
18+
jobs:
19+
build:
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Node.js
27+
uses: actions/setup-node@v4
28+
with:
29+
node-version: '20'
30+
registry-url: https://registry.npmjs.org/
31+
32+
- name: Install dependencies
33+
run: npm ci
34+
35+
- name: Build the project
36+
run: npm run build
37+
38+
- name: Run tests
39+
run: npm test
40+
41+
- name: Deploy to GitHub Pages
42+
continue-on-error: true
43+
env:
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
run: |
46+
git config --global user.name 'github-actions[bot]'
47+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
48+
git add dist
49+
git commit -m 'Update dist' dist/*
50+
git push origin main
51+
52+
- name: Publish to npm
53+
env:
54+
NODE_AUTH_TOKEN: ${{secrets.NPMJS_TOKEN}}
55+
run: npm publish
56+
continue-on-error: true
57+

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# OpenAPI Snippet
22
**Generates code snippets from Open API (previously Swagger) documents.**
33

4-
This package takes as input an OpenAPI v2.0 or v3.0.x document. It translates the document into an [HTTP Archive 1.2 request object](http://www.softwareishard.com/blog/har-12-spec/#request). It uses the [HTTP Snippet](https://github.com/Mashape/httpsnippet) library to generate code snippets for every API endpoint (URL path + HTTP method) defined in the specification in various languages & tools (`cURL`, `Node`, `Python`, `Ruby`, `Java`, `Go`, `C#`...), or for selected endpoints.
4+
This package takes as input an OpenAPI v2.0 or v3.0.x document. It translates the document into an [HTTP Archive 1.2 request object](http://www.softwareishard.com/blog/har-12-spec/#request). It uses the [HTTP Snippet](https://github.com/sctg-development/httpsnippet) library to generate code snippets for every API endpoint (URL path + HTTP method) defined in the specification in various languages & tools (`cURL`, `Node`, `Python`, `Ruby`, `Java`, `Go`, `C#`...), or for selected endpoints.
55

66
## Installation
77

index.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
*/
99
'use strict';
1010

11-
const OpenAPIToHar = require('./openapi-to-har.js');
12-
const HTTPSnippet = require('httpsnippet');
11+
import { getEndpoint, getAll } from './openapi-to-har.js';
12+
import { HTTPSnippet, availableTargets } from '@sctg/httpsnippet';
1313

1414
/**
1515
* Return snippets for endpoint identified using path and method in the given
@@ -22,16 +22,17 @@ const HTTPSnippet = require('httpsnippet');
2222
* ['cURL', 'Node']
2323
* @param {object} values Optional: Values for the query parameters if present
2424
*/
25-
const getEndpointSnippets = function (openApi, path, method, targets, values) {
25+
export const getEndpointSnippets = function (openApi, path, method, targets, values) {
2626
// if optional parameter is not provided, set it to empty object
2727
if (typeof values === 'undefined') {
2828
values = {};
2929
}
3030

31-
const hars = OpenAPIToHar.getEndpoint(openApi, path, method, values);
31+
const hars = getEndpoint(openApi, path, method, values);
3232

3333
const snippets = [];
3434
for (const har of hars) {
35+
// console.log(JSON.stringify(har, null, 4));
3536
const snippet = new HTTPSnippet(har);
3637
snippets.push(
3738
...getSnippetsForTargets(
@@ -60,8 +61,8 @@ const getEndpointSnippets = function (openApi, path, method, targets, values) {
6061
* @param {array} targets List of languages to create snippets in, e.g,
6162
* ['cURL', 'Node']
6263
*/
63-
const getSnippets = function (openApi, targets) {
64-
const endpointHarInfoList = OpenAPIToHar.getAll(openApi);
64+
export const getSnippets = function (openApi, targets) {
65+
const endpointHarInfoList = getAll(openApi);
6566

6667
const results = [];
6768
for (let i in endpointHarInfoList) {
@@ -147,7 +148,7 @@ const formatTarget = function (targetStr) {
147148
const title = capitalizeFirstLetter(language);
148149
let library = targetStr.split('_')[1];
149150

150-
const validTargets = HTTPSnippet.availableTargets();
151+
const validTargets = availableTargets();
151152
let validLanguage = false;
152153
let validLibrary = false;
153154
for (let i in validTargets) {
@@ -190,18 +191,27 @@ const formatTarget = function (targetStr) {
190191
* @param snippet {Object} Snippet object from httpsnippet to convert into the target objects
191192
* @param mimeType {string | undefined} Additional information to add uniqueness to the produced snippets
192193
*/
193-
const getSnippetsForTargets = function (targets, snippet, mimeType) {
194+
export const getSnippetsForTargets = function (targets, snippet, mimeType) {
194195
const snippets = [];
196+
let convertOptions = {};
195197
for (let j in targets) {
196198
const target = formatTarget(targets[j]);
197199
if (!target) throw new Error('Invalid target: ' + targets[j]);
200+
// console.log(target.title);
201+
if (target.title === 'Shell + Curl') {
202+
convertOptions['short'] = true;
203+
} else {
204+
convertOptions = {};
205+
}
206+
// console.log(convertOptions);
198207
snippets.push({
199208
id: targets[j],
200209
...(mimeType !== undefined && { mimeType: mimeType }),
201210
title: target.title,
202211
content: snippet.convert(
203212
target.language,
204-
typeof target.library !== 'undefined' ? target.library : null
213+
typeof target.library !== 'undefined' ? target.library : null,
214+
convertOptions
205215
),
206216
});
207217
}
@@ -212,23 +222,13 @@ const capitalizeFirstLetter = function (string) {
212222
return string.charAt(0).toUpperCase() + string.slice(1);
213223
};
214224

215-
module.exports = {
225+
export const OpenAPISnippets = {
216226
getSnippets,
217227
getEndpointSnippets,
218228
};
219229

220230
// The if is only for when this is run from the browser
221231
if (typeof window !== 'undefined') {
222-
// grab existing namespace object, or create a blank object
223-
// if it doesn't exist
224-
let OpenAPISnippets = window.OpenAPISnippets || {};
225-
226-
// define that object
227-
OpenAPISnippets = {
228-
getSnippets,
229-
getEndpointSnippets,
230-
};
231-
232232
// replace/create the global namespace
233233
window.OpenAPISnippets = OpenAPISnippets;
234-
}
234+
}

openapi-to-har.js

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* "comment" : ""
1919
* }
2020
*/
21-
const OpenAPISampler = require('openapi-sampler');
21+
import { sample as _sample } from 'openapi-sampler';
2222

2323
/**
2424
* Create HAR Request object for path and method pair described in given OpenAPI
@@ -211,7 +211,7 @@ const objectJoin = function (
211211
* parameter is used to explicitly state which value should be used.
212212
* @return {HarParameterObject[]} - An array of query string objects
213213
*/
214-
const createHarParameterObjects = function (
214+
export const createHarParameterObjects = function (
215215
{ name, in: location, style, explode },
216216
value
217217
) {
@@ -227,8 +227,8 @@ const createHarParameterObjects = function (
227227
}
228228

229229
const objects = [];
230-
style = style ?? getDefaultStyleForLocation(location);
231-
explode = explode ?? getDefaultExplodeForStyle(style);
230+
style = style || getDefaultStyleForLocation(location);
231+
explode = explode || getDefaultExplodeForStyle(style);
232232

233233
if (location === 'query' || location === 'cookie') {
234234
const separator = getArrayElementSeparator(style);
@@ -289,6 +289,52 @@ const createHarParameterObjects = function (
289289
return objects;
290290
};
291291

292+
const formatSamples = function (sample) {
293+
const params = [];
294+
295+
Object.keys(sample).map((key) => {
296+
// console.log(`key=${JSON.stringify(key, null, 4)} (${typeof(sample[key])})`);
297+
if (Array.isArray(sample[key])) {
298+
// console.log("Array.isArray(sample[key])");
299+
sample[key].forEach((entry) => {
300+
// console.log(`entry=${JSON.stringify(entry, null, 4)}\n`);
301+
params.push({
302+
name: `${key}[]`,
303+
value: entry,
304+
});
305+
});
306+
} else if (Object.prototype.toString.call(sample[key]) === '[object Object]') {
307+
// console.log("Object.prototype.toString.call(sample[key]) === '[object Object]'");
308+
Object.keys(sample[key]).map((k) => {
309+
// console.log(`k=${JSON.stringify(k, null, 4)}\n`);
310+
if (Array.isArray(sample[key][k])) {
311+
// console.log("Array.isArray(sample[key][k])");
312+
sample[key][k].forEach((entry) => {
313+
// console.log(`entry=${JSON.stringify(entry, null, 4)}\n`);
314+
params.push({
315+
name: `${key}[${k}][]`,
316+
value: entry,
317+
});
318+
});
319+
} else {
320+
params.push({
321+
name: key + '[' + k + ']',
322+
value: sample[key][k],
323+
});
324+
}
325+
});
326+
} else {
327+
// console.log("else\n");
328+
params.push({
329+
name: key,
330+
value: sample[key],
331+
});
332+
}
333+
});
334+
335+
return params;
336+
}
337+
292338
/**
293339
* Get the payload definition for the given endpoint (path + method) from the
294340
* given OAI specification. References within the payload definition are
@@ -309,7 +355,7 @@ const getPayloads = function (openApi, path, method) {
309355
typeof param.schema !== 'undefined'
310356
) {
311357
try {
312-
const sample = OpenAPISampler.sample(
358+
const sample = _sample(
313359
param.schema,
314360
{ skipReadOnly: true },
315361
openApi
@@ -350,7 +396,8 @@ const getPayloads = function (openApi, path, method) {
350396
].forEach((type) => {
351397
const content = openApi.paths[path][method].requestBody.content[type];
352398
if (content && content.schema) {
353-
const sample = OpenAPISampler.sample(
399+
// console.log(JSON.stringify(content, null, 4) + "\n");
400+
const sample = _sample(
354401
content.schema,
355402
{ skipReadOnly: true },
356403
openApi
@@ -378,13 +425,8 @@ const getPayloads = function (openApi, path, method) {
378425
} else if (type == 'application/x-www-form-urlencoded') {
379426
if (sample === undefined) return null;
380427

381-
const params = [];
382-
Object.keys(sample).map((key) =>
383-
params.push({
384-
name: encodeURIComponent(key).replace(/\%20/g, '+'),
385-
value: encodeURIComponent(sample[key]).replace(/\%20/g, '+'),
386-
})
387-
);
428+
// console.log(`sample=${JSON.stringify(sample, null, 4)}`);
429+
const params = formatSamples(sample);
388430

389431
payloads.push({
390432
mimeType: 'application/x-www-form-urlencoded',
@@ -820,8 +862,5 @@ const resolveRef = function (openApi, ref) {
820862
return recursive(openApi, 1);
821863
};
822864

823-
module.exports = {
824-
getAll: openApiToHarList,
825-
getEndpoint: createHar,
826-
createHarParameterObjects,
827-
};
865+
export const getAll = openApiToHarList;
866+
export const getEndpoint = createHar;

0 commit comments

Comments
 (0)