httpsnippet-client-api 7.0.0-beta.3 → 7.0.0-beta.4

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 CHANGED
@@ -15,10 +15,10 @@ npm install --save httpsnippet-client-api
15
15
  ## Usage
16
16
 
17
17
  ```js
18
- import { HTTPSnippet, addTargetClient } from 'httpsnippet';
19
- import client = require('httpsnippet-client-api');
18
+ import { HTTPSnippet, addClientPlugin } from 'httpsnippet';
19
+ import apiClientPlugin from 'httpsnippet-client-api';
20
20
 
21
- addTargetClient('node', client);
21
+ addClientPlugin('node', apiClientPlugin);
22
22
 
23
23
  const har = {
24
24
  "log": {
@@ -42,10 +42,12 @@ const har = {
42
42
  }
43
43
 
44
44
  const snippet = new HTTPSnippet(har);
45
- const code = snippet.convert('node', 'api', {
46
- apiDefinitionUri: 'https://api.example.com/openapi.json'
47
- apiDefinition: {
48
- /* an OpenAPI definition object */
45
+ const code = await snippet.convert('node', 'api', {
46
+ api: {
47
+ definition: {
48
+ /* an OpenAPI definition object */
49
+ }
50
+ registryURI: '@example/v2.0#17273l2glm9fq4l5'
49
51
  }
50
52
  });
51
53
 
@@ -55,7 +57,7 @@ console.log(code);
55
57
  Results in the following:
56
58
 
57
59
  ```js
58
- const sdk = require('api')('https://api.example.com/openapi.json');
60
+ import sdk from '@api/example';
59
61
 
60
62
  sdk.auth('a5a220e');
61
63
  sdk
@@ -63,3 +65,27 @@ sdk
63
65
  .then(({ data }}) => console.log(data))
64
66
  .catch(err => console.error(err));
65
67
  ```
68
+
69
+ We also support supplying a shorter `identifier` option that will take over the imported package and the variable that is created.
70
+
71
+ ```js
72
+ const code = await snippet.convert('node', 'api', {
73
+ api: {
74
+ definition: {
75
+ /* an OpenAPI definition object */
76
+ }
77
+ identifier: 'example',
78
+ registryURI: '@example/v2.0#17273l2glm9fq4l5'
79
+ }
80
+ });
81
+ ```
82
+
83
+ ```js
84
+ import example from 'example';
85
+
86
+ example.auth('a5a220e');
87
+ example
88
+ .put('/apiKey')
89
+ .then(({ data }}) => console.log(data))
90
+ .catch(err => console.error(err));
91
+ ```
package/dist/index.cjs CHANGED
@@ -1,21 +1,216 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/index.ts
2
2
  var _codebuilder = require('@readme/httpsnippet/helpers/code-builder');
3
- var _camelcase = require('camelcase'); var _camelcase2 = _interopRequireDefault(_camelcase);
3
+
4
+ // node_modules/camelcase/index.js
5
+ var UPPERCASE = /[\p{Lu}]/u;
6
+ var LOWERCASE = /[\p{Ll}]/u;
7
+ var LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
8
+ var IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
9
+ var SEPARATORS = /[_.\- ]+/;
10
+ var LEADING_SEPARATORS = new RegExp("^" + SEPARATORS.source);
11
+ var SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, "gu");
12
+ var NUMBERS_AND_IDENTIFIER = new RegExp("\\d+" + IDENTIFIER.source, "gu");
13
+ var preserveCamelCase = (string, toLowerCase, toUpperCase, preserveConsecutiveUppercase2) => {
14
+ let isLastCharLower = false;
15
+ let isLastCharUpper = false;
16
+ let isLastLastCharUpper = false;
17
+ let isLastLastCharPreserved = false;
18
+ for (let index = 0; index < string.length; index++) {
19
+ const character = string[index];
20
+ isLastLastCharPreserved = index > 2 ? string[index - 3] === "-" : true;
21
+ if (isLastCharLower && UPPERCASE.test(character)) {
22
+ string = string.slice(0, index) + "-" + string.slice(index);
23
+ isLastCharLower = false;
24
+ isLastLastCharUpper = isLastCharUpper;
25
+ isLastCharUpper = true;
26
+ index++;
27
+ } else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase2)) {
28
+ string = string.slice(0, index - 1) + "-" + string.slice(index - 1);
29
+ isLastLastCharUpper = isLastCharUpper;
30
+ isLastCharUpper = false;
31
+ isLastCharLower = true;
32
+ } else {
33
+ isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
34
+ isLastLastCharUpper = isLastCharUpper;
35
+ isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
36
+ }
37
+ }
38
+ return string;
39
+ };
40
+ var preserveConsecutiveUppercase = (input, toLowerCase) => {
41
+ LEADING_CAPITAL.lastIndex = 0;
42
+ return input.replaceAll(LEADING_CAPITAL, (match) => toLowerCase(match));
43
+ };
44
+ var postProcess = (input, toUpperCase) => {
45
+ SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
46
+ NUMBERS_AND_IDENTIFIER.lastIndex = 0;
47
+ return input.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ["_", "-"].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match)).replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));
48
+ };
49
+ function camelCase(input, options) {
50
+ if (!(typeof input === "string" || Array.isArray(input))) {
51
+ throw new TypeError("Expected the input to be `string | string[]`");
52
+ }
53
+ options = {
54
+ pascalCase: false,
55
+ preserveConsecutiveUppercase: false,
56
+ ...options
57
+ };
58
+ if (Array.isArray(input)) {
59
+ input = input.map((x) => x.trim()).filter((x) => x.length).join("-");
60
+ } else {
61
+ input = input.trim();
62
+ }
63
+ if (input.length === 0) {
64
+ return "";
65
+ }
66
+ const toLowerCase = options.locale === false ? (string) => string.toLowerCase() : (string) => string.toLocaleLowerCase(options.locale);
67
+ const toUpperCase = options.locale === false ? (string) => string.toUpperCase() : (string) => string.toLocaleUpperCase(options.locale);
68
+ if (input.length === 1) {
69
+ if (SEPARATORS.test(input)) {
70
+ return "";
71
+ }
72
+ return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
73
+ }
74
+ const hasUpperCase = input !== toLowerCase(input);
75
+ if (hasUpperCase) {
76
+ input = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);
77
+ }
78
+ input = input.replace(LEADING_SEPARATORS, "");
79
+ input = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);
80
+ if (options.pascalCase) {
81
+ input = toUpperCase(input.charAt(0)) + input.slice(1);
82
+ }
83
+ return postProcess(input, toUpperCase);
84
+ }
85
+
86
+ // src/index.ts
4
87
  var _contenttype = require('content-type'); var _contenttype2 = _interopRequireDefault(_contenttype);
5
88
  var _oas = require('oas'); var _oas2 = _interopRequireDefault(_oas);
6
89
  var _utils = require('oas/utils');
7
90
  var _reserved2 = require('reserved2');
8
- var _stringifyobject = require('stringify-object'); var _stringifyobject2 = _interopRequireDefault(_stringifyobject);
91
+
92
+ // node_modules/is-regexp/index.js
93
+ var { toString } = Object.prototype;
94
+ function isRegexp(value) {
95
+ return toString.call(value) === "[object RegExp]";
96
+ }
97
+
98
+ // node_modules/is-obj/index.js
99
+ function isObject(value) {
100
+ const type = typeof value;
101
+ return value !== null && (type === "object" || type === "function");
102
+ }
103
+
104
+ // ../../node_modules/get-own-enumerable-keys/index.js
105
+ var { propertyIsEnumerable } = Object.prototype;
106
+ function getOwnEnumerableKeys(object) {
107
+ return [
108
+ ...Object.keys(object),
109
+ ...Object.getOwnPropertySymbols(object).filter((key) => propertyIsEnumerable.call(object, key))
110
+ ];
111
+ }
112
+
113
+ // node_modules/stringify-object/index.js
114
+ function stringifyObject(input, options, pad) {
115
+ const seen = [];
116
+ return function stringify2(input2, options2 = {}, pad2 = "") {
117
+ const indent = options2.indent || " ";
118
+ let tokens;
119
+ if (options2.inlineCharacterLimit === void 0) {
120
+ tokens = {
121
+ newline: "\n",
122
+ newlineOrSpace: "\n",
123
+ pad: pad2,
124
+ indent: pad2 + indent
125
+ };
126
+ } else {
127
+ tokens = {
128
+ newline: "@@__STRINGIFY_OBJECT_NEW_LINE__@@",
129
+ newlineOrSpace: "@@__STRINGIFY_OBJECT_NEW_LINE_OR_SPACE__@@",
130
+ pad: "@@__STRINGIFY_OBJECT_PAD__@@",
131
+ indent: "@@__STRINGIFY_OBJECT_INDENT__@@"
132
+ };
133
+ }
134
+ const expandWhiteSpace = (string) => {
135
+ if (options2.inlineCharacterLimit === void 0) {
136
+ return string;
137
+ }
138
+ const oneLined = string.replace(new RegExp(tokens.newline, "g"), "").replace(new RegExp(tokens.newlineOrSpace, "g"), " ").replace(new RegExp(tokens.pad + "|" + tokens.indent, "g"), "");
139
+ if (oneLined.length <= options2.inlineCharacterLimit) {
140
+ return oneLined;
141
+ }
142
+ return string.replace(new RegExp(tokens.newline + "|" + tokens.newlineOrSpace, "g"), "\n").replace(new RegExp(tokens.pad, "g"), pad2).replace(new RegExp(tokens.indent, "g"), pad2 + indent);
143
+ };
144
+ if (seen.includes(input2)) {
145
+ return '"[Circular]"';
146
+ }
147
+ if (input2 === null || input2 === void 0 || typeof input2 === "number" || typeof input2 === "boolean" || typeof input2 === "function" || typeof input2 === "symbol" || isRegexp(input2)) {
148
+ return String(input2);
149
+ }
150
+ if (input2 instanceof Date) {
151
+ return `new Date('${input2.toISOString()}')`;
152
+ }
153
+ if (Array.isArray(input2)) {
154
+ if (input2.length === 0) {
155
+ return "[]";
156
+ }
157
+ seen.push(input2);
158
+ const returnValue = "[" + tokens.newline + input2.map((element, i) => {
159
+ const eol = input2.length - 1 === i ? tokens.newline : "," + tokens.newlineOrSpace;
160
+ let value = stringify2(element, options2, pad2 + indent);
161
+ if (options2.transform) {
162
+ value = options2.transform(input2, i, value);
163
+ }
164
+ return tokens.indent + value + eol;
165
+ }).join("") + tokens.pad + "]";
166
+ seen.pop();
167
+ return expandWhiteSpace(returnValue);
168
+ }
169
+ if (isObject(input2)) {
170
+ let objectKeys = getOwnEnumerableKeys(input2);
171
+ if (options2.filter) {
172
+ objectKeys = objectKeys.filter((element) => options2.filter(input2, element));
173
+ }
174
+ if (objectKeys.length === 0) {
175
+ return "{}";
176
+ }
177
+ seen.push(input2);
178
+ const returnValue = "{" + tokens.newline + objectKeys.map((element, index) => {
179
+ const eol = objectKeys.length - 1 === index ? tokens.newline : "," + tokens.newlineOrSpace;
180
+ const isSymbol = typeof element === "symbol";
181
+ const isClassic = !isSymbol && /^[a-z$_][$\w]*$/i.test(element);
182
+ const key = isSymbol || isClassic ? element : stringify2(element, options2);
183
+ let value = stringify2(input2[element], options2, pad2 + indent);
184
+ if (options2.transform) {
185
+ value = options2.transform(input2, element, value);
186
+ }
187
+ return tokens.indent + String(key) + ": " + value + eol;
188
+ }).join("") + tokens.pad + "}";
189
+ seen.pop();
190
+ return expandWhiteSpace(returnValue);
191
+ }
192
+ input2 = input2.replace(/\\/g, "\\\\");
193
+ input2 = String(input2).replace(/[\r\n]/g, (x) => x === "\n" ? "\\n" : "\\r");
194
+ if (options2.singleQuotes === false) {
195
+ input2 = input2.replace(/"/g, '\\"');
196
+ return `"${input2}"`;
197
+ }
198
+ input2 = input2.replace(/'/g, "\\'");
199
+ return `'${input2}'`;
200
+ }(input, options, pad);
201
+ }
202
+
203
+ // src/index.ts
9
204
  var registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;
10
205
  function getProjectPrefixFromRegistryUUID(uri) {
11
206
  const matches = uri.match(registryUUIDRegex);
12
207
  if (!matches) {
13
208
  return void 0;
14
209
  }
15
- return _optionalChain([matches, 'access', _ => _.groups, 'optionalAccess', _2 => _2.project]);
210
+ return _optionalChain([matches, 'access', _2 => _2.groups, 'optionalAccess', _3 => _3.project]);
16
211
  }
17
212
  function stringify(obj, opts = {}) {
18
- return _stringifyobject2.default.call(void 0, obj, { indent: " ", ...opts });
213
+ return stringifyObject(obj, { indent: " ", ...opts });
19
214
  }
20
215
  function buildAuthSnippet(sdkVariable, authKey) {
21
216
  if (Array.isArray(authKey)) {
@@ -68,36 +263,39 @@ var client = {
68
263
  title: "API",
69
264
  link: "https://npm.im/api",
70
265
  description: "Automatic SDK generation from an OpenAPI definition.",
71
- extname: ".js"
266
+ extname: ".js",
267
+ installation: "npx api install {packageName}"
72
268
  },
73
269
  convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {
74
270
  const opts = {
75
271
  ...options
76
272
  };
77
- if (!("apiDefinitionUri" in opts)) {
78
- throw new Error("This HTTP Snippet client must have an `apiDefinitionUri` option supplied to it.");
79
- } else if (!("apiDefinition" in opts)) {
80
- throw new Error("This HTTP Snippet client must have an `apiDefinition` option supplied to it.");
273
+ if (!_optionalChain([opts, 'optionalAccess', _4 => _4.api])) {
274
+ throw new Error("This HTTPSnippet client must have an `api` config supplied to it.");
275
+ } else if (!_optionalChain([opts, 'optionalAccess', _5 => _5.api, 'optionalAccess', _6 => _6.definition])) {
276
+ throw new Error("This HTTPSnippet client must have an `api.definition` option supplied to it.");
277
+ } else if (!_optionalChain([opts, 'optionalAccess', _7 => _7.api, 'optionalAccess', _8 => _8.registryURI])) {
278
+ throw new Error("This HTTPSnippet client must have an `api.registryURI` option supplied to it.");
81
279
  }
82
280
  const method = source.method.toLowerCase();
83
- const oas = new (0, _oas2.default)(opts.apiDefinition);
281
+ const oas = new (0, _oas2.default)(opts.api.definition);
84
282
  const apiDefinition = oas.getDefinition();
85
283
  const foundOperation = oas.findOperation(url, method);
86
284
  if (!foundOperation) {
87
285
  throw new Error(
88
- `Unable to locate a matching operation in the supplied \`apiDefinition\` for: ${source.method} ${url}`
286
+ `Unable to locate a matching operation in the supplied \`api.definition\` for: ${source.method} ${url}`
89
287
  );
90
288
  }
91
289
  let sdkPackageName;
92
290
  let sdkVariable;
93
- if (opts.identifier) {
94
- sdkPackageName = opts.identifier;
95
- sdkVariable = _camelcase2.default.call(void 0, opts.identifier);
291
+ if (opts.api.identifier) {
292
+ sdkPackageName = opts.api.identifier;
293
+ sdkVariable = camelCase(opts.api.identifier);
96
294
  if (_reserved2.isReservedOrBuiltinsLC.call(void 0, sdkVariable)) {
97
295
  sdkVariable = `_${sdkVariable}`;
98
296
  }
99
297
  } else {
100
- sdkPackageName = getProjectPrefixFromRegistryUUID(opts.apiDefinitionUri);
298
+ sdkPackageName = getProjectPrefixFromRegistryUUID(opts.api.registryURI);
101
299
  sdkVariable = "sdk";
102
300
  }
103
301
  const operationSlugs = foundOperation.url.slugs;
@@ -237,7 +435,11 @@ var client = {
237
435
  return join();
238
436
  }
239
437
  };
240
- var src_default = client;
438
+ var plugin = {
439
+ target: "node",
440
+ client
441
+ };
442
+ var src_default = plugin;
241
443
 
242
444
 
243
445
  exports.default = src_default;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAKA,SAAS,mBAAmB;AAC5B,OAAO,eAAe;AACtB,OAAO,iBAAiB;AACxB,OAAO,SAAS;AAChB,SAAS,uBAAuB;AAChC,SAAS,8BAA8B;AACvC,OAAO,qBAAqB;AAQ5B,IAAM,oBAAoB;AAK1B,SAAS,iCAAiC,KAAa;AACrD,QAAM,UAAU,IAAI,MAAM,iBAAiB;AAC3C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,QAAQ;AACzB;AAGA,SAAS,UAAU,KAAU,OAAO,CAAC,GAAG;AACtC,SAAO,gBAAgB,KAAK,EAAE,QAAQ,MAAM,GAAG,KAAK,CAAC;AACvD;AAEA,SAAS,iBAAiB,aAAqB,SAA4B;AAEzE,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,UAAM,OAAiB,CAAC;AACxB,YAAQ,QAAQ,CAAC,OAAO,MAAM;AAE5B,UAAI,MAAM,WAAW,KAAK,QAAQ,SAAS,KAAK,MAAM,QAAQ,SAAS,GAAG;AACxE;AAAA,MACF;AAEA,WAAK,KAAK,IAAI,MAAM,QAAQ,MAAM,KAAK,CAAC,GAAG;AAAA,IAC7C,CAAC;AAED,WAAO,GAAG,WAAW,SAAS,KAAK,KAAK,IAAI,CAAC;AAAA,EAC/C;AAEA,SAAO,GAAG,WAAW,UAAU,QAAQ,QAAQ,MAAM,KAAK,CAAC;AAC7D;AAEA,SAAS,eAAe,WAAsB;AAC5C,QAAM,WAAkF;AAAA,IACtF,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,QAAQ,CAAC;AAAA,EACX;AAEA,MAAI,UAAU,YAAY,EAAE,WAAW,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,UAAU,gBAAgB,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,MAAM;AACnE,YAAQ,QAAQ,YAAU;AACxB,UAAI,OAAO,SAAS,QAAQ;AAC1B,YAAI,OAAO,WAAW,SAAS;AAC7B,mBAAS,OAAO,gBAAgB;AAAA,QAClC,WAAW,OAAO,WAAW,UAAU;AACrC,mBAAS,OAAO,gBAAgB;AAAA,QAClC;AAAA,MACF,WAAW,OAAO,SAAS,UAAU;AACnC,iBAAS,OAAO,gBAAgB;AAAA,MAClC,WAAW,OAAO,SAAS,UAAU;AACnC,YAAI,OAAO,OAAO,SAAS;AACzB,mBAAS,MAAM,KAAK,OAAO,IAAI;AAAA,QACjC,WAAW,OAAO,OAAO,UAAU;AAMjC,mBAAS,OAAO,OAAO,KAAK,YAAY,CAAC,IAAI;AAAA,QAC/C,WAAW,OAAO,OAAO,UAAU;AACjC,mBAAS,OAAO,KAAK,OAAO,IAAI;AAAA,QAClC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAqBA,IAAM,SAA6B;AAAA,EACjC,MAAM;AAAA,IACJ,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA,SAAS,CAAC,EAAE,YAAY,YAAY,UAAU,UAAU,KAAK,GAAG,OAAO,GAAG,YAAY;AACpF,UAAM,OAAO;AAAA,MACX,GAAG;AAAA,IACL;AAEA,QAAI,EAAE,sBAAsB,OAAO;AACjC,YAAM,IAAI,MAAM,iFAAiF;AAAA,IACnG,WAAW,EAAE,mBAAmB,OAAO;AACrC,YAAM,IAAI,MAAM,8EAA8E;AAAA,IAChG;AAEA,UAAM,SAAS,OAAO,OAAO,YAAY;AACzC,UAAM,MAAM,IAAI,IAAI,KAAK,aAAa;AACtC,UAAM,gBAAgB,IAAI,cAAc;AACxC,UAAM,iBAAiB,IAAI,cAAc,KAAK,MAAM;AACpD,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI;AAAA,QACR,gFAAgF,OAAO,MAAM,IAAI,GAAG;AAAA,MACtG;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI,KAAK,YAAY;AACnB,uBAAiB,KAAK;AAEtB,oBAAc,UAAU,KAAK,UAAU;AACvC,UAAI,uBAAuB,WAAW,GAAG;AAGvC,sBAAc,IAAI,WAAW;AAAA,MAC/B;AAAA,IACF,OAAO;AACL,uBAAiB,iCAAiC,KAAK,gBAAgB;AACvE,oBAAc;AAAA,IAChB;AAEA,UAAM,iBAAiB,eAAe,IAAI;AAC1C,UAAM,YAAY,IAAI,UAAU,eAAe,IAAI,mBAAmB,MAAM;AAC5E,UAAM,0BAA0B,UAAU,cAAc,EAAE,OAAO,WAAS,MAAM,OAAO,MAAM;AAC7F,UAAM,OAAO,UAAU;AACvB,UAAM,WAAqB,CAAC;AAC5B,UAAM,cAAc,eAAe,SAAS;AAE5C,UAAM,EAAE,OAAO,MAAM,KAAK,IAAI,IAAI,YAAY,EAAE,QAAQ,KAAK,UAAU,KAAK,CAAC;AAE7E,SAAK,UAAU,WAAW,eAAe,cAAc,IAAI;AAC3D,UAAM;AAMN,UAAM,aAAa,CAAC;AACpB,SAAK,cAAc,WAAW,CAAC,GAAG,SAAS,GAAG;AAC5C,YAAM,WAAW,IAAI,IAAI;AACzB,YAAM,UAAU,IAAI,QAAQ,MAAM,EAAE;AACpC,UAAI,YAAY,UAAU;AACxB,cAAM,aAAa,IAAI,eAAe,OAAO;AAC7C,cAAM,YAAY,aAAa,IAAI,IAAI,WAAW,UAAU,WAAW,SAAS,IAAI;AAEpF,mBAAW,KAAK,eAAe,SAAS,KAAK;AAAA,MAC/C;AAAA,IACF;AAEA,QAAI,WAA8C,CAAC;AACnD,WAAO,KAAK,QAAQ,EAAE,QAAQ,WAAS;AACrC,UAAI,YAAY,MAAM,SAAS,KAAK,GAAG;AACrC,iBAAS,KAAK,iBAAiB,aAAa,SAAS,KAAK,CAAC,CAAC;AAI5D;AAAA,MACF;AAEA,eAAS,KAAK,IAAI,SAAS,KAAK;AAAA,IAClC,CAAC;AAED,WAAO,KAAK,UAAU,EAAE,QAAQ,YAAU;AACxC,UAAI,YAAY,OAAO,SAAS,MAAM,GAAG;AACvC,iBAAS,KAAK,iBAAiB,aAAa,WAAW,MAAM,CAAC,CAAC;AAG/D;AAAA,MACF;AAKA,eAAS,MAAM,IAAI,WAAW,MAAM;AAAA,IACtC,CAAC;AAGD,UAAM,KAAK,OAAO,QAAQ,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC,OAAO,KAAK,MAAM;AAGrE,YAAM,eAAe,MAAM,UAAU,CAAC;AAKtC,YAAM,mBAAmB,wBAAwB,KAAK,OAAK;AACzD,eAAO,EAAE,KAAK,SAAS,GAAG,KAAK,EAAE,KAAK,QAAQ,MAAM,EAAE,MAAM,eAAe,EAAE,OAAO;AAAA,MACtF,CAAC;AAED,UAAI,kBAAkB;AACpB,iBAAS,iBAAiB,IAAI,IAAI;AAAA,MACpC,OAAO;AACL,iBAAS,YAAY,IAAI;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,QAAI,OAAO,KAAK,UAAU,EAAE,QAAQ;AAClC,YAAM,UAAU;AAChB,YAAM,iBAAsC,CAAC;AAE7C,aAAO,KAAK,OAAO,EAAE,QAAQ,YAAU;AAGrC,cAAM,cAAc,OAAO,YAAY;AAEvC,YAAI,eAAe,YAAY,QAAQ;AAGrC,gBAAM,aAAa,YAAY,OAAO,WAAW;AACjD,cAAI,eAAe,KAAK;AACtB,qBAAS,KAAK,iBAAiB,aAAa,QAAQ,MAAM,CAAC,CAAC;AAAA,UAC9D,OAAO;AAEL,gBAAI,UAAU,QAAQ,MAAM,EAAE,QAAQ,GAAG,YAAY,OAAO,WAAW,CAAC,KAAK,EAAE;AAC/E,gBAAI,WAAW,YAAY,MAAM,SAAS;AACxC,wBAAU,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,OAAO;AACzD,wBAAU,QAAQ,MAAM,GAAG;AAAA,YAC7B;AAEA,qBAAS,KAAK,iBAAiB,aAAa,OAAO,CAAC;AAAA,UACtD;AAEA,iBAAO,QAAQ,MAAM;AACrB;AAAA,QACF,WAAW,gBAAgB,gBAAgB;AAIzC,gBAAM,oBAAoB,YAAY,MAAM,QAAQ,MAAM,CAAC;AAC3D,cAAI,CAAC,OAAO,KAAK,kBAAkB,UAAU,EAAE,QAAQ;AACrD,mBAAO,QAAQ,MAAM;AACrB;AAAA,UACF;AAAA,QACF,WAAW,gBAAgB,UAAU;AAGnC,cAAI,gBAAgB,KAAK,QAAQ,MAAM,CAAW,GAAG;AACnD,mBAAO,QAAQ,MAAM;AACrB;AAAA,UACF;AAAA,QACF;AAIA,YAAI,CAAC,UAAU,cAAc,EAAE,SAAS,WAAW,GAAG;AACpD,yBAAe,WAAW,IAAI,QAAQ,MAAM;AAAA,QAC9C,OAAO;AAGL,yBAAe,MAAM,IAAI,QAAQ,MAAM;AAAA,QACzC;AAAA,MACF,CAAC;AAED,UAAI,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC1C,mBAAW,OAAO,OAAO,UAAU,cAAc;AAAA,MACnD;AAAA,IACF;AAGA,QAAI;AACJ,YAAQ,SAAS,UAAU;AAAA,MACzB,KAAK;AACH,eAAO,SAAS;AAChB;AAAA,MAEF,KAAK;AACH,YAAI,SAAS,SAAS;AACpB,iBAAO,SAAS;AAAA,QAClB;AACA;AAAA,MAEF,KAAK;AACH,YAAI,SAAS,QAAQ;AACnB,iBAAO,CAAC;AAMR,cAAI,kBAAkB,YAAY,SAAS,cAAc,EAAE,QAAQ,qBAAqB,MAAM,GAAG;AAC/F,mBAAO,SAAS,cAAc;AAAA,UAChC;AAEA,mBAAS,OAAO,QAAQ,WAAS;AAC/B,gBAAI,MAAM,UAAU;AAClB,mBAAK,MAAM,IAAI,IAAI,MAAM;AAAA,YAC3B,OAAO;AACL,mBAAK,MAAM,IAAI,IAAI,MAAM;AAAA,YAC3B;AAAA,UACF,CAAC;AAAA,QACH;AACA;AAAA,MAEF;AACE,YAAI,SAAS,MAAM;AACjB,iBAAO,SAAS;AAAA,QAClB;AAAA,IACJ;AAEA,UAAM,OAAO,CAAC;AAEd,UAAM,WAAW,UAAU,eAAe,EAAE,WAAW,KAAK,CAAC;AAI7D,UAAM,uBAAuB,OAAO,SAAS,eAAe,OAAO,KAAK,QAAQ,EAAE,SAAS,IAAI,KAAK;AACpG,QAAI,OAAO,SAAS,aAAa;AAC/B,WAAK,KAAK,UAAU,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAAA,IACrD;AAEA,QAAI,OAAO,KAAK,QAAQ,EAAE,SAAS,GAAG;AACpC,WAAK,KAAK,UAAU,UAAU,EAAE,qBAAqB,CAAC,CAAC;AAAA,IACzD;AAEA,QAAI,SAAS,QAAQ;AACnB,WAAK,SAAS,KAAK,IAAI,CAAC;AAAA,IAC1B;AAEA,QAAI,WAAW,QAAQ;AACrB,WAAK,WAAW,KAAK,IAAI,CAAC;AAAA,IAC5B;AAEA,SAAK,GAAG,WAAW,IAAI,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG;AACrD,SAAK,0CAA0C,CAAC;AAChD,SAAK,sCAAsC,CAAC;AAE5C,WAAO,KAAK;AAAA,EACd;AACF;AAEA,IAAO,cAAQ","sourcesContent":["import type { ReducedHelperObject } from '@readme/httpsnippet/helpers/reducer';\nimport type { Client } from '@readme/httpsnippet/targets';\nimport type Operation from 'oas/operation';\nimport type { HttpMethods, OASDocument } from 'oas/rmoas.types';\n\nimport { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';\nimport camelCase from 'camelcase';\nimport contentType from 'content-type';\nimport Oas from 'oas';\nimport { matchesMimeType } from 'oas/utils';\nimport { isReservedOrBuiltinsLC } from 'reserved2';\nimport stringifyObject from 'stringify-object';\n\n/**\n * @note This regex also exists in `api/fetcher`.\n *\n * @example @petstore/v1.0#n6kvf10vakpemvplx\n * @example @petstore#n6kvf10vakpemvplx\n */\nconst registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;\n\n/**\n * @note This function also exists in `api/fetcher`.\n */\nfunction getProjectPrefixFromRegistryUUID(uri: string) {\n const matches = uri.match(registryUUIDRegex);\n if (!matches) {\n return undefined;\n }\n\n return matches.groups?.project;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction stringify(obj: any, opts = {}) {\n return stringifyObject(obj, { indent: ' ', ...opts });\n}\n\nfunction buildAuthSnippet(sdkVariable: string, authKey: string | string[]) {\n // Auth key will be an array for Basic auth cases.\n if (Array.isArray(authKey)) {\n const auth: string[] = [];\n authKey.forEach((token, i) => {\n // If the token part is the last part of the key and it's empty, don't add it to the snippet.\n if (token.length === 0 && authKey.length > 1 && i === authKey.length - 1) {\n return;\n }\n\n auth.push(`'${token.replace(/'/g, \"\\\\'\")}'`);\n });\n\n return `${sdkVariable}.auth(${auth.join(', ')});`;\n }\n\n return `${sdkVariable}.auth('${authKey.replace(/'/g, \"\\\\'\")}');`;\n}\n\nfunction getAuthSources(operation: Operation) {\n const matchers: { cookie: string[]; header: Record<string, string>; query: string[] } = {\n header: {},\n query: [],\n cookie: [],\n };\n\n if (operation.getSecurity().length === 0) {\n return matchers;\n }\n\n Object.entries(operation.prepareSecurity()).forEach(([, schemes]) => {\n schemes.forEach(scheme => {\n if (scheme.type === 'http') {\n if (scheme.scheme === 'basic') {\n matchers.header.authorization = 'Basic';\n } else if (scheme.scheme === 'bearer') {\n matchers.header.authorization = 'Bearer';\n }\n } else if (scheme.type === 'oauth2') {\n matchers.header.authorization = 'Bearer';\n } else if (scheme.type === 'apiKey') {\n if (scheme.in === 'query') {\n matchers.query.push(scheme.name);\n } else if (scheme.in === 'header') {\n // The way that this asterisk header matcher works is that since this `apiKey` goes in a\n // named header (`scheme.name`) because the header is the key, we're matching against the\n // entire header -- counter to the way that the HTTP basic matcher above works where we\n // match and extract the API key from everything after `Basic ` in the `Authorization`\n // header.\n matchers.header[scheme.name.toLowerCase()] = '*';\n } else if (scheme.in === 'cookie') {\n matchers.cookie.push(scheme.name);\n }\n }\n });\n });\n\n return matchers;\n}\n\ninterface APIOptions {\n apiDefinition: OASDocument;\n /**\n * The URI that is used to download this API definition from `npx api install`.\n *\n * @example @developers/v2.0#17273l2glm9fq4l5\n */\n apiDefinitionUri: string;\n escapeBrackets?: boolean;\n /**\n * The string to identify this SDK as. This is used in the `import sdk from '@api/<identifier>'`\n * sample as well as the the variable name we attach the SDK to.\n *\n * @example developers\n */\n identifier?: string;\n indent?: string | false;\n}\n\nconst client: Client<APIOptions> = {\n info: {\n key: 'api',\n title: 'API',\n link: 'https://npm.im/api',\n description: 'Automatic SDK generation from an OpenAPI definition.',\n extname: '.js',\n },\n convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {\n const opts = {\n ...options,\n } as APIOptions;\n\n if (!('apiDefinitionUri' in opts)) {\n throw new Error('This HTTP Snippet client must have an `apiDefinitionUri` option supplied to it.');\n } else if (!('apiDefinition' in opts)) {\n throw new Error('This HTTP Snippet client must have an `apiDefinition` option supplied to it.');\n }\n\n const method = source.method.toLowerCase() as HttpMethods;\n const oas = new Oas(opts.apiDefinition);\n const apiDefinition = oas.getDefinition();\n const foundOperation = oas.findOperation(url, method);\n if (!foundOperation) {\n throw new Error(\n `Unable to locate a matching operation in the supplied \\`apiDefinition\\` for: ${source.method} ${url}`,\n );\n }\n\n let sdkPackageName;\n let sdkVariable: string;\n if (opts.identifier) {\n sdkPackageName = opts.identifier;\n\n sdkVariable = camelCase(opts.identifier);\n if (isReservedOrBuiltinsLC(sdkVariable)) {\n // If this identifier is a reserved JS word then we should prefix it with an underscore so\n // this snippet can be valid code.\n sdkVariable = `_${sdkVariable}`;\n }\n } else {\n sdkPackageName = getProjectPrefixFromRegistryUUID(opts.apiDefinitionUri);\n sdkVariable = 'sdk';\n }\n\n const operationSlugs = foundOperation.url.slugs;\n const operation = oas.operation(foundOperation.url.nonNormalizedPath, method);\n const operationPathParameters = operation.getParameters().filter(param => param.in === 'path');\n const path = operation.path;\n const authData: string[] = [];\n const authSources = getAuthSources(operation);\n\n const { blank, push, join } = new CodeBuilder({ indent: opts.indent || ' ' });\n\n push(`import ${sdkVariable} from '@api/${sdkPackageName}';`);\n blank();\n\n // If we have multiple servers configured and our source URL differs from the stock URL that we\n // receive from our `oas` library then the URL either has server variables contained in it (that\n // don't match the defaults), or the OAS offers alternate server URLs and we should expose that\n // in the generated snippet.\n const configData = [];\n if ((apiDefinition.servers || []).length > 1) {\n const stockUrl = oas.url();\n const baseUrl = url.replace(path, '');\n if (baseUrl !== stockUrl) {\n const serverVars = oas.splitVariables(baseUrl);\n const serverUrl = serverVars ? oas.url(serverVars.selected, serverVars.variables) : baseUrl;\n\n configData.push(`sdk.server('${serverUrl}');`);\n }\n }\n\n let metadata: Record<string, string | string[]> = {};\n Object.keys(queryObj).forEach(param => {\n if (authSources.query.includes(param)) {\n authData.push(buildAuthSnippet(sdkVariable, queryObj[param]));\n\n // If this query param is part of an auth source then we don't want it doubled up in the\n // snippet.\n return;\n }\n\n metadata[param] = queryObj[param];\n });\n\n Object.keys(cookiesObj).forEach(cookie => {\n if (authSources.cookie.includes(cookie)) {\n authData.push(buildAuthSnippet(sdkVariable, cookiesObj[cookie]));\n\n // If this cookie is part of an auth source then we don't want it doubled up.\n return;\n }\n\n // Note that we may have the potential to overlap any cookie that also shares the name as\n // another metadata parameter. This problem is currently inherent to `api` and not this\n // snippet generator.\n metadata[cookie] = cookiesObj[cookie];\n });\n\n // If we have path parameters present we should add them into the metadata object.\n Array.from(Object.entries(operationSlugs)).forEach(([param, value]) => {\n // The keys in `operationSlugs` will always be prefixed with a `:` in the `oas` library so\n // we can safely do this substring here without asserting this context.\n const cleanedParam = param.substring(1);\n\n // If our incoming path slug out of `oas.findOperation()` has been sanitized and is missing\n // a hyphen, but there is a parameter in the OpenAPI definition that matches what our\n // hyphen-less slug is then we should use that for the snippet.\n const unsanitizedParam = operationPathParameters.find(p => {\n return p.name.includes('-') && p.name.replace(/-/g, '') === cleanedParam ? p.name : false;\n });\n\n if (unsanitizedParam) {\n metadata[unsanitizedParam.name] = value;\n } else {\n metadata[cleanedParam] = value;\n }\n });\n\n if (Object.keys(headersObj).length) {\n const headers = headersObj;\n const requestHeaders: ReducedHelperObject = {};\n\n Object.keys(headers).forEach(header => {\n // Headers in HTTPSnippet are case-insensitive so we need to add in some special handling to\n // make sure we're able to match them properly.\n const headerLower = header.toLowerCase();\n\n if (headerLower in authSources.header) {\n // If this header has been set up as an authentication header, let's remove it and add it\n // into our auth data so we can build up an `.auth()` snippet for the SDK.\n const authScheme = authSources.header[headerLower];\n if (authScheme === '*') {\n authData.push(buildAuthSnippet(sdkVariable, headers[header]));\n } else {\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n let authKey = headers[header].replace(`${authSources.header[headerLower]} `, '');\n if (authScheme.toLowerCase() === 'basic') {\n authKey = Buffer.from(authKey, 'base64').toString('ascii');\n authKey = authKey.split(':');\n }\n\n authData.push(buildAuthSnippet(sdkVariable, authKey));\n }\n\n delete headers[header];\n return;\n } else if (headerLower === 'content-type') {\n // `Content-Type` headers are automatically added within the SDK so we can filter them out\n // if they don't have parameters attached to them.\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n const parsedContentType = contentType.parse(headers[header]);\n if (!Object.keys(parsedContentType.parameters).length) {\n delete headers[header];\n return;\n }\n } else if (headerLower === 'accept') {\n // If the `Accept` header here is JSON-like header then we can remove it from the code\n // snippet because `api` natively supports and prioritizes JSON over any other mime type.\n if (matchesMimeType.json(headers[header] as string)) {\n delete headers[header];\n return;\n }\n }\n\n // If we haven't used our header anywhere else, or we've deleted it from the payload\n // because it'll be handled internally by `api` then we should add it into our code snippet.\n if (['accept', 'content-type'].includes(headerLower)) {\n requestHeaders[headerLower] = headers[header];\n } else {\n // Non-reserved headers retain their casing because we want to generate a snippet that\n // matches the TS types that are created during codegeneration.\n requestHeaders[header] = headers[header];\n }\n });\n\n if (Object.keys(requestHeaders).length > 0) {\n metadata = Object.assign(metadata, requestHeaders);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let body: any;\n switch (postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n body = postData.paramsObj;\n break;\n\n case 'application/json':\n if (postData.jsonObj) {\n body = postData.jsonObj;\n }\n break;\n\n case 'multipart/form-data':\n if (postData.params) {\n body = {};\n\n // If there's a `Content-Type` header present in the metadata, but it's for the\n // `multipart/form-data` request then dump it off the snippet. We shouldn't offload that\n // unnecessary bloat of multipart boundaries to the user, instead letting the SDK handle it\n // automatically.\n if ('content-type' in metadata && metadata['content-type'].indexOf('multipart/form-data') === 0) {\n delete metadata['content-type'];\n }\n\n postData.params.forEach(param => {\n if (param.fileName) {\n body[param.name] = param.fileName;\n } else {\n body[param.name] = param.value;\n }\n });\n }\n break;\n\n default:\n if (postData.text) {\n body = postData.text;\n }\n }\n\n const args = [];\n\n const accessor = operation.getOperationId({ camelCase: true });\n\n // If we're going to be rendering out body params and metadata we should cut their character\n // limit in half because we'll be rendering them in their own lines.\n const inlineCharacterLimit = typeof body !== 'undefined' && Object.keys(metadata).length > 0 ? 40 : 80;\n if (typeof body !== 'undefined') {\n args.push(stringify(body, { inlineCharacterLimit }));\n }\n\n if (Object.keys(metadata).length > 0) {\n args.push(stringify(metadata, { inlineCharacterLimit }));\n }\n\n if (authData.length) {\n push(authData.join('\\n'));\n }\n\n if (configData.length) {\n push(configData.join('\\n'));\n }\n\n push(`${sdkVariable}.${accessor}(${args.join(', ')})`);\n push('.then(({ data }) => console.log(data))', 1);\n push('.catch(err => console.error(err));', 1);\n\n return join();\n },\n};\n\nexport default client;\n"]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/camelcase/index.js","../node_modules/is-regexp/index.js","../node_modules/is-obj/index.js","../../../node_modules/get-own-enumerable-keys/index.js","../node_modules/stringify-object/index.js"],"names":["preserveConsecutiveUppercase","stringify","input","options","pad"],"mappings":"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","sourcesContent":["import type { ReducedHelperObject } from '@readme/httpsnippet/helpers/reducer';\nimport type { Client, ClientPlugin } from '@readme/httpsnippet/targets';\nimport type { Operation } from 'oas/operation';\nimport type { HttpMethods, OASDocument } from 'oas/types';\n\nimport { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';\nimport camelCase from 'camelcase'; // eslint-disable-line import/no-extraneous-dependencies\nimport contentType from 'content-type';\nimport Oas from 'oas';\nimport { matchesMimeType } from 'oas/utils';\nimport { isReservedOrBuiltinsLC } from 'reserved2';\nimport stringifyObject from 'stringify-object'; // eslint-disable-line import/no-extraneous-dependencies\n\n/**\n * @note This regex also exists in `api/fetcher`.\n *\n * @example @petstore/v1.0#n6kvf10vakpemvplx\n * @example @petstore#n6kvf10vakpemvplx\n */\nconst registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;\n\n/**\n * @note This function also exists in `api/fetcher`.\n */\nfunction getProjectPrefixFromRegistryUUID(uri: string) {\n const matches = uri.match(registryUUIDRegex);\n if (!matches) {\n return undefined;\n }\n\n return matches.groups?.project;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction stringify(obj: any, opts = {}) {\n return stringifyObject(obj, { indent: ' ', ...opts });\n}\n\nfunction buildAuthSnippet(sdkVariable: string, authKey: string | string[]) {\n // Auth key will be an array for Basic auth cases.\n if (Array.isArray(authKey)) {\n const auth: string[] = [];\n authKey.forEach((token, i) => {\n // If the token part is the last part of the key and it's empty, don't add it to the snippet.\n if (token.length === 0 && authKey.length > 1 && i === authKey.length - 1) {\n return;\n }\n\n auth.push(`'${token.replace(/'/g, \"\\\\'\")}'`);\n });\n\n return `${sdkVariable}.auth(${auth.join(', ')});`;\n }\n\n return `${sdkVariable}.auth('${authKey.replace(/'/g, \"\\\\'\")}');`;\n}\n\nfunction getAuthSources(operation: Operation) {\n const matchers: { cookie: string[]; header: Record<string, string>; query: string[] } = {\n header: {},\n query: [],\n cookie: [],\n };\n\n if (operation.getSecurity().length === 0) {\n return matchers;\n }\n\n Object.entries(operation.prepareSecurity()).forEach(([, schemes]) => {\n schemes.forEach(scheme => {\n if (scheme.type === 'http') {\n if (scheme.scheme === 'basic') {\n matchers.header.authorization = 'Basic';\n } else if (scheme.scheme === 'bearer') {\n matchers.header.authorization = 'Bearer';\n }\n } else if (scheme.type === 'oauth2') {\n matchers.header.authorization = 'Bearer';\n } else if (scheme.type === 'apiKey') {\n if (scheme.in === 'query') {\n matchers.query.push(scheme.name);\n } else if (scheme.in === 'header') {\n // The way that this asterisk header matcher works is that since this `apiKey` goes in a\n // named header (`scheme.name`) because the header is the key, we're matching against the\n // entire header -- counter to the way that the HTTP basic matcher above works where we\n // match and extract the API key from everything after `Basic ` in the `Authorization`\n // header.\n matchers.header[scheme.name.toLowerCase()] = '*';\n } else if (scheme.in === 'cookie') {\n matchers.cookie.push(scheme.name);\n }\n }\n });\n });\n\n return matchers;\n}\n\ninterface APIOptions {\n api: {\n definition: OASDocument;\n\n /**\n * The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`\n * sample as well as the the variable name we attach the SDK to.\n *\n * @example `@api/developers`\n */\n identifier?: string;\n\n /**\n * The URI that is used to download this API definition from `npx api install`.\n *\n * @example `@developers/v2.0#17273l2glm9fq4l5`\n */\n registryURI: string;\n };\n escapeBrackets?: boolean;\n indent?: string | false;\n}\n\nconst client: Client<APIOptions> = {\n info: {\n key: 'api',\n title: 'API',\n link: 'https://npm.im/api',\n description: 'Automatic SDK generation from an OpenAPI definition.',\n extname: '.js',\n installation: 'npx api install {packageName}',\n },\n convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {\n const opts = {\n ...options,\n } as APIOptions;\n\n if (!opts?.api) {\n throw new Error('This HTTPSnippet client must have an `api` config supplied to it.');\n } else if (!opts?.api?.definition) {\n throw new Error('This HTTPSnippet client must have an `api.definition` option supplied to it.');\n } else if (!opts?.api?.registryURI) {\n throw new Error('This HTTPSnippet client must have an `api.registryURI` option supplied to it.');\n }\n\n const method = source.method.toLowerCase() as HttpMethods;\n const oas = new Oas(opts.api.definition);\n const apiDefinition = oas.getDefinition();\n const foundOperation = oas.findOperation(url, method);\n if (!foundOperation) {\n throw new Error(\n `Unable to locate a matching operation in the supplied \\`api.definition\\` for: ${source.method} ${url}`,\n );\n }\n\n let sdkPackageName;\n let sdkVariable: string;\n if (opts.api.identifier) {\n sdkPackageName = opts.api.identifier;\n\n sdkVariable = camelCase(opts.api.identifier);\n if (isReservedOrBuiltinsLC(sdkVariable)) {\n // If this identifier is a reserved JS word then we should prefix it with an underscore so\n // this snippet can be valid code.\n sdkVariable = `_${sdkVariable}`;\n }\n } else {\n sdkPackageName = getProjectPrefixFromRegistryUUID(opts.api.registryURI);\n sdkVariable = 'sdk';\n }\n\n const operationSlugs = foundOperation.url.slugs;\n const operation = oas.operation(foundOperation.url.nonNormalizedPath, method);\n const operationPathParameters = operation.getParameters().filter(param => param.in === 'path');\n const path = operation.path;\n const authData: string[] = [];\n const authSources = getAuthSources(operation);\n\n const { blank, push, join } = new CodeBuilder({ indent: opts.indent || ' ' });\n\n push(`import ${sdkVariable} from '@api/${sdkPackageName}';`);\n blank();\n\n // If we have multiple servers configured and our source URL differs from the stock URL that we\n // receive from our `oas` library then the URL either has server variables contained in it (that\n // don't match the defaults), or the OAS offers alternate server URLs and we should expose that\n // in the generated snippet.\n const configData = [];\n if ((apiDefinition.servers || []).length > 1) {\n const stockUrl = oas.url();\n const baseUrl = url.replace(path, '');\n if (baseUrl !== stockUrl) {\n const serverVars = oas.splitVariables(baseUrl);\n const serverUrl = serverVars ? oas.url(serverVars.selected, serverVars.variables) : baseUrl;\n\n configData.push(`sdk.server('${serverUrl}');`);\n }\n }\n\n let metadata: Record<string, string | string[]> = {};\n Object.keys(queryObj).forEach(param => {\n if (authSources.query.includes(param)) {\n authData.push(buildAuthSnippet(sdkVariable, queryObj[param]));\n\n // If this query param is part of an auth source then we don't want it doubled up in the\n // snippet.\n return;\n }\n\n metadata[param] = queryObj[param];\n });\n\n Object.keys(cookiesObj).forEach(cookie => {\n if (authSources.cookie.includes(cookie)) {\n authData.push(buildAuthSnippet(sdkVariable, cookiesObj[cookie]));\n\n // If this cookie is part of an auth source then we don't want it doubled up.\n return;\n }\n\n // Note that we may have the potential to overlap any cookie that also shares the name as\n // another metadata parameter. This problem is currently inherent to `api` and not this\n // snippet generator.\n metadata[cookie] = cookiesObj[cookie];\n });\n\n // If we have path parameters present we should add them into the metadata object.\n Array.from(Object.entries(operationSlugs)).forEach(([param, value]) => {\n // The keys in `operationSlugs` will always be prefixed with a `:` in the `oas` library so\n // we can safely do this substring here without asserting this context.\n const cleanedParam = param.substring(1);\n\n // If our incoming path slug out of `oas.findOperation()` has been sanitized and is missing\n // a hyphen, but there is a parameter in the OpenAPI definition that matches what our\n // hyphen-less slug is then we should use that for the snippet.\n const unsanitizedParam = operationPathParameters.find(p => {\n return p.name.includes('-') && p.name.replace(/-/g, '') === cleanedParam ? p.name : false;\n });\n\n if (unsanitizedParam) {\n metadata[unsanitizedParam.name] = value;\n } else {\n metadata[cleanedParam] = value;\n }\n });\n\n if (Object.keys(headersObj).length) {\n const headers = headersObj;\n const requestHeaders: ReducedHelperObject = {};\n\n Object.keys(headers).forEach(header => {\n // Headers in HTTPSnippet are case-insensitive so we need to add in some special handling to\n // make sure we're able to match them properly.\n const headerLower = header.toLowerCase();\n\n if (headerLower in authSources.header) {\n // If this header has been set up as an authentication header, let's remove it and add it\n // into our auth data so we can build up an `.auth()` snippet for the SDK.\n const authScheme = authSources.header[headerLower];\n if (authScheme === '*') {\n authData.push(buildAuthSnippet(sdkVariable, headers[header]));\n } else {\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n let authKey = headers[header].replace(`${authSources.header[headerLower]} `, '');\n if (authScheme.toLowerCase() === 'basic') {\n authKey = Buffer.from(authKey, 'base64').toString('ascii');\n authKey = authKey.split(':');\n }\n\n authData.push(buildAuthSnippet(sdkVariable, authKey));\n }\n\n delete headers[header];\n return;\n } else if (headerLower === 'content-type') {\n // `Content-Type` headers are automatically added within the SDK so we can filter them out\n // if they don't have parameters attached to them.\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n const parsedContentType = contentType.parse(headers[header]);\n if (!Object.keys(parsedContentType.parameters).length) {\n delete headers[header];\n return;\n }\n } else if (headerLower === 'accept') {\n // If the `Accept` header here is JSON-like header then we can remove it from the code\n // snippet because `api` natively supports and prioritizes JSON over any other mime type.\n if (matchesMimeType.json(headers[header] as string)) {\n delete headers[header];\n return;\n }\n }\n\n // If we haven't used our header anywhere else, or we've deleted it from the payload\n // because it'll be handled internally by `api` then we should add it into our code snippet.\n if (['accept', 'content-type'].includes(headerLower)) {\n requestHeaders[headerLower] = headers[header];\n } else {\n // Non-reserved headers retain their casing because we want to generate a snippet that\n // matches the TS types that are created during codegeneration.\n requestHeaders[header] = headers[header];\n }\n });\n\n if (Object.keys(requestHeaders).length > 0) {\n metadata = Object.assign(metadata, requestHeaders);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let body: any;\n switch (postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n body = postData.paramsObj;\n break;\n\n case 'application/json':\n if (postData.jsonObj) {\n body = postData.jsonObj;\n }\n break;\n\n case 'multipart/form-data':\n if (postData.params) {\n body = {};\n\n // If there's a `Content-Type` header present in the metadata, but it's for the\n // `multipart/form-data` request then dump it off the snippet. We shouldn't offload that\n // unnecessary bloat of multipart boundaries to the user, instead letting the SDK handle it\n // automatically.\n if ('content-type' in metadata && metadata['content-type'].indexOf('multipart/form-data') === 0) {\n delete metadata['content-type'];\n }\n\n postData.params.forEach(param => {\n if (param.fileName) {\n body[param.name] = param.fileName;\n } else {\n body[param.name] = param.value;\n }\n });\n }\n break;\n\n default:\n if (postData.text) {\n body = postData.text;\n }\n }\n\n const args = [];\n\n const accessor = operation.getOperationId({ camelCase: true });\n\n // If we're going to be rendering out body params and metadata we should cut their character\n // limit in half because we'll be rendering them in their own lines.\n const inlineCharacterLimit = typeof body !== 'undefined' && Object.keys(metadata).length > 0 ? 40 : 80;\n if (typeof body !== 'undefined') {\n args.push(stringify(body, { inlineCharacterLimit }));\n }\n\n if (Object.keys(metadata).length > 0) {\n args.push(stringify(metadata, { inlineCharacterLimit }));\n }\n\n if (authData.length) {\n push(authData.join('\\n'));\n }\n\n if (configData.length) {\n push(configData.join('\\n'));\n }\n\n push(`${sdkVariable}.${accessor}(${args.join(', ')})`);\n push('.then(({ data }) => console.log(data))', 1);\n push('.catch(err => console.error(err));', 1);\n\n return join();\n },\n};\n\nconst plugin: ClientPlugin<APIOptions> = {\n target: 'node',\n client,\n};\n\nexport default plugin;\n","const UPPERCASE = /[\\p{Lu}]/u;\nconst LOWERCASE = /[\\p{Ll}]/u;\nconst LEADING_CAPITAL = /^[\\p{Lu}](?![\\p{Lu}])/gu;\nconst IDENTIFIER = /([\\p{Alpha}\\p{N}_]|$)/u;\nconst SEPARATORS = /[_.\\- ]+/;\n\nconst LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);\nconst SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');\nconst NUMBERS_AND_IDENTIFIER = new RegExp('\\\\d+' + IDENTIFIER.source, 'gu');\n\nconst preserveCamelCase = (string, toLowerCase, toUpperCase, preserveConsecutiveUppercase) => {\n\tlet isLastCharLower = false;\n\tlet isLastCharUpper = false;\n\tlet isLastLastCharUpper = false;\n\tlet isLastLastCharPreserved = false;\n\n\tfor (let index = 0; index < string.length; index++) {\n\t\tconst character = string[index];\n\t\tisLastLastCharPreserved = index > 2 ? string[index - 3] === '-' : true;\n\n\t\tif (isLastCharLower && UPPERCASE.test(character)) {\n\t\t\tstring = string.slice(0, index) + '-' + string.slice(index);\n\t\t\tisLastCharLower = false;\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = true;\n\t\t\tindex++;\n\t\t} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase)) {\n\t\t\tstring = string.slice(0, index - 1) + '-' + string.slice(index - 1);\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = false;\n\t\t\tisLastCharLower = true;\n\t\t} else {\n\t\t\tisLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;\n\t\t}\n\t}\n\n\treturn string;\n};\n\nconst preserveConsecutiveUppercase = (input, toLowerCase) => {\n\tLEADING_CAPITAL.lastIndex = 0;\n\n\treturn input.replaceAll(LEADING_CAPITAL, match => toLowerCase(match));\n};\n\nconst postProcess = (input, toUpperCase) => {\n\tSEPARATORS_AND_IDENTIFIER.lastIndex = 0;\n\tNUMBERS_AND_IDENTIFIER.lastIndex = 0;\n\n\treturn input\n\t\t.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ['_', '-'].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match))\n\t\t.replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));\n};\n\nexport default function camelCase(input, options) {\n\tif (!(typeof input === 'string' || Array.isArray(input))) {\n\t\tthrow new TypeError('Expected the input to be `string | string[]`');\n\t}\n\n\toptions = {\n\t\tpascalCase: false,\n\t\tpreserveConsecutiveUppercase: false,\n\t\t...options,\n\t};\n\n\tif (Array.isArray(input)) {\n\t\tinput = input.map(x => x.trim())\n\t\t\t.filter(x => x.length)\n\t\t\t.join('-');\n\t} else {\n\t\tinput = input.trim();\n\t}\n\n\tif (input.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst toLowerCase = options.locale === false\n\t\t? string => string.toLowerCase()\n\t\t: string => string.toLocaleLowerCase(options.locale);\n\n\tconst toUpperCase = options.locale === false\n\t\t? string => string.toUpperCase()\n\t\t: string => string.toLocaleUpperCase(options.locale);\n\n\tif (input.length === 1) {\n\t\tif (SEPARATORS.test(input)) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn options.pascalCase ? toUpperCase(input) : toLowerCase(input);\n\t}\n\n\tconst hasUpperCase = input !== toLowerCase(input);\n\n\tif (hasUpperCase) {\n\t\tinput = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);\n\t}\n\n\tinput = input.replace(LEADING_SEPARATORS, '');\n\tinput = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);\n\n\tif (options.pascalCase) {\n\t\tinput = toUpperCase(input.charAt(0)) + input.slice(1);\n\t}\n\n\treturn postProcess(input, toUpperCase);\n}\n","const {toString} = Object.prototype;\n\nexport default function isRegexp(value) {\n\treturn toString.call(value) === '[object RegExp]';\n}\n","export default function isObject(value) {\n\tconst type = typeof value;\n\treturn value !== null && (type === 'object' || type === 'function');\n}\n","const {propertyIsEnumerable} = Object.prototype;\n\nexport default function getOwnEnumerableKeys(object) {\n\treturn [\n\t\t...Object.keys(object),\n\t\t...Object.getOwnPropertySymbols(object)\n\t\t\t.filter(key => propertyIsEnumerable.call(object, key)),\n\t];\n}\n","import isRegexp from 'is-regexp';\nimport isObject from 'is-obj';\nimport getOwnEnumerableKeys from 'get-own-enumerable-keys';\n\nexport default function stringifyObject(input, options, pad) {\n\tconst seen = [];\n\n\treturn (function stringify(input, options = {}, pad = '') {\n\t\tconst indent = options.indent || '\\t';\n\n\t\tlet tokens;\n\t\tif (options.inlineCharacterLimit === undefined) {\n\t\t\ttokens = {\n\t\t\t\tnewline: '\\n',\n\t\t\t\tnewlineOrSpace: '\\n',\n\t\t\t\tpad,\n\t\t\t\tindent: pad + indent,\n\t\t\t};\n\t\t} else {\n\t\t\ttokens = {\n\t\t\t\tnewline: '@@__STRINGIFY_OBJECT_NEW_LINE__@@',\n\t\t\t\tnewlineOrSpace: '@@__STRINGIFY_OBJECT_NEW_LINE_OR_SPACE__@@',\n\t\t\t\tpad: '@@__STRINGIFY_OBJECT_PAD__@@',\n\t\t\t\tindent: '@@__STRINGIFY_OBJECT_INDENT__@@',\n\t\t\t};\n\t\t}\n\n\t\tconst expandWhiteSpace = string => {\n\t\t\tif (options.inlineCharacterLimit === undefined) {\n\t\t\t\treturn string;\n\t\t\t}\n\n\t\t\tconst oneLined = string\n\t\t\t\t.replace(new RegExp(tokens.newline, 'g'), '')\n\t\t\t\t.replace(new RegExp(tokens.newlineOrSpace, 'g'), ' ')\n\t\t\t\t.replace(new RegExp(tokens.pad + '|' + tokens.indent, 'g'), '');\n\n\t\t\tif (oneLined.length <= options.inlineCharacterLimit) {\n\t\t\t\treturn oneLined;\n\t\t\t}\n\n\t\t\treturn string\n\t\t\t\t.replace(new RegExp(tokens.newline + '|' + tokens.newlineOrSpace, 'g'), '\\n')\n\t\t\t\t.replace(new RegExp(tokens.pad, 'g'), pad)\n\t\t\t\t.replace(new RegExp(tokens.indent, 'g'), pad + indent);\n\t\t};\n\n\t\tif (seen.includes(input)) {\n\t\t\treturn '\"[Circular]\"';\n\t\t}\n\n\t\tif (\n\t\t\tinput === null\n\t\t\t|| input === undefined\n\t\t\t|| typeof input === 'number'\n\t\t\t|| typeof input === 'boolean'\n\t\t\t|| typeof input === 'function'\n\t\t\t|| typeof input === 'symbol'\n\t\t\t|| isRegexp(input)\n\t\t) {\n\t\t\treturn String(input);\n\t\t}\n\n\t\tif (input instanceof Date) {\n\t\t\treturn `new Date('${input.toISOString()}')`;\n\t\t}\n\n\t\tif (Array.isArray(input)) {\n\t\t\tif (input.length === 0) {\n\t\t\t\treturn '[]';\n\t\t\t}\n\n\t\t\tseen.push(input);\n\n\t\t\tconst returnValue = '[' + tokens.newline + input.map((element, i) => {\n\t\t\t\tconst eol = input.length - 1 === i ? tokens.newline : ',' + tokens.newlineOrSpace;\n\n\t\t\t\tlet value = stringify(element, options, pad + indent);\n\t\t\t\tif (options.transform) {\n\t\t\t\t\tvalue = options.transform(input, i, value);\n\t\t\t\t}\n\n\t\t\t\treturn tokens.indent + value + eol;\n\t\t\t}).join('') + tokens.pad + ']';\n\n\t\t\tseen.pop();\n\n\t\t\treturn expandWhiteSpace(returnValue);\n\t\t}\n\n\t\tif (isObject(input)) {\n\t\t\tlet objectKeys = getOwnEnumerableKeys(input);\n\n\t\t\tif (options.filter) {\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n\t\t\t\tobjectKeys = objectKeys.filter(element => options.filter(input, element));\n\t\t\t}\n\n\t\t\tif (objectKeys.length === 0) {\n\t\t\t\treturn '{}';\n\t\t\t}\n\n\t\t\tseen.push(input);\n\n\t\t\tconst returnValue = '{' + tokens.newline + objectKeys.map((element, index) => {\n\t\t\t\tconst eol = objectKeys.length - 1 === index ? tokens.newline : ',' + tokens.newlineOrSpace;\n\t\t\t\tconst isSymbol = typeof element === 'symbol';\n\t\t\t\tconst isClassic = !isSymbol && /^[a-z$_][$\\w]*$/i.test(element);\n\t\t\t\tconst key = isSymbol || isClassic ? element : stringify(element, options);\n\n\t\t\t\tlet value = stringify(input[element], options, pad + indent);\n\t\t\t\tif (options.transform) {\n\t\t\t\t\tvalue = options.transform(input, element, value);\n\t\t\t\t}\n\n\t\t\t\treturn tokens.indent + String(key) + ': ' + value + eol;\n\t\t\t}).join('') + tokens.pad + '}';\n\n\t\t\tseen.pop();\n\n\t\t\treturn expandWhiteSpace(returnValue);\n\t\t}\n\n\t\tinput = input.replace(/\\\\/g, '\\\\\\\\');\n\t\tinput = String(input).replace(/[\\r\\n]/g, x => x === '\\n' ? '\\\\n' : '\\\\r');\n\n\t\tif (options.singleQuotes === false) {\n\t\t\tinput = input.replace(/\"/g, '\\\\\"');\n\t\t\treturn `\"${input}\"`;\n\t\t}\n\n\t\tinput = input.replace(/'/g, '\\\\\\'');\n\t\treturn `'${input}'`;\n\t})(input, options, pad);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,24 +1,26 @@
1
- import { Client } from '@readme/httpsnippet/targets';
2
- import { OASDocument } from 'oas/rmoas.types';
1
+ import { ClientPlugin } from '@readme/httpsnippet/targets';
2
+ import { OASDocument } from 'oas/types';
3
3
 
4
4
  interface APIOptions {
5
- apiDefinition: OASDocument;
6
- /**
7
- * The URI that is used to download this API definition from `npx api install`.
8
- *
9
- * @example @developers/v2.0#17273l2glm9fq4l5
10
- */
11
- apiDefinitionUri: string;
5
+ api: {
6
+ definition: OASDocument;
7
+ /**
8
+ * The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`
9
+ * sample as well as the the variable name we attach the SDK to.
10
+ *
11
+ * @example `@api/developers`
12
+ */
13
+ identifier?: string;
14
+ /**
15
+ * The URI that is used to download this API definition from `npx api install`.
16
+ *
17
+ * @example `@developers/v2.0#17273l2glm9fq4l5`
18
+ */
19
+ registryURI: string;
20
+ };
12
21
  escapeBrackets?: boolean;
13
- /**
14
- * The string to identify this SDK as. This is used in the `import sdk from '@api/<identifier>'`
15
- * sample as well as the the variable name we attach the SDK to.
16
- *
17
- * @example developers
18
- */
19
- identifier?: string;
20
22
  indent?: string | false;
21
23
  }
22
- declare const client: Client<APIOptions>;
24
+ declare const plugin: ClientPlugin<APIOptions>;
23
25
 
24
- export = client;
26
+ export = plugin;
package/dist/index.d.ts CHANGED
@@ -1,24 +1,26 @@
1
- import { Client } from '@readme/httpsnippet/targets';
2
- import { OASDocument } from 'oas/rmoas.types';
1
+ import { ClientPlugin } from '@readme/httpsnippet/targets';
2
+ import { OASDocument } from 'oas/types';
3
3
 
4
4
  interface APIOptions {
5
- apiDefinition: OASDocument;
6
- /**
7
- * The URI that is used to download this API definition from `npx api install`.
8
- *
9
- * @example @developers/v2.0#17273l2glm9fq4l5
10
- */
11
- apiDefinitionUri: string;
5
+ api: {
6
+ definition: OASDocument;
7
+ /**
8
+ * The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`
9
+ * sample as well as the the variable name we attach the SDK to.
10
+ *
11
+ * @example `@api/developers`
12
+ */
13
+ identifier?: string;
14
+ /**
15
+ * The URI that is used to download this API definition from `npx api install`.
16
+ *
17
+ * @example `@developers/v2.0#17273l2glm9fq4l5`
18
+ */
19
+ registryURI: string;
20
+ };
12
21
  escapeBrackets?: boolean;
13
- /**
14
- * The string to identify this SDK as. This is used in the `import sdk from '@api/<identifier>'`
15
- * sample as well as the the variable name we attach the SDK to.
16
- *
17
- * @example developers
18
- */
19
- identifier?: string;
20
22
  indent?: string | false;
21
23
  }
22
- declare const client: Client<APIOptions>;
24
+ declare const plugin: ClientPlugin<APIOptions>;
23
25
 
24
- export { client as default };
26
+ export { plugin as default };
package/dist/index.js CHANGED
@@ -1,11 +1,206 @@
1
1
  // src/index.ts
2
2
  import { CodeBuilder } from "@readme/httpsnippet/helpers/code-builder";
3
- import camelCase from "camelcase";
3
+
4
+ // node_modules/camelcase/index.js
5
+ var UPPERCASE = /[\p{Lu}]/u;
6
+ var LOWERCASE = /[\p{Ll}]/u;
7
+ var LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
8
+ var IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
9
+ var SEPARATORS = /[_.\- ]+/;
10
+ var LEADING_SEPARATORS = new RegExp("^" + SEPARATORS.source);
11
+ var SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, "gu");
12
+ var NUMBERS_AND_IDENTIFIER = new RegExp("\\d+" + IDENTIFIER.source, "gu");
13
+ var preserveCamelCase = (string, toLowerCase, toUpperCase, preserveConsecutiveUppercase2) => {
14
+ let isLastCharLower = false;
15
+ let isLastCharUpper = false;
16
+ let isLastLastCharUpper = false;
17
+ let isLastLastCharPreserved = false;
18
+ for (let index = 0; index < string.length; index++) {
19
+ const character = string[index];
20
+ isLastLastCharPreserved = index > 2 ? string[index - 3] === "-" : true;
21
+ if (isLastCharLower && UPPERCASE.test(character)) {
22
+ string = string.slice(0, index) + "-" + string.slice(index);
23
+ isLastCharLower = false;
24
+ isLastLastCharUpper = isLastCharUpper;
25
+ isLastCharUpper = true;
26
+ index++;
27
+ } else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase2)) {
28
+ string = string.slice(0, index - 1) + "-" + string.slice(index - 1);
29
+ isLastLastCharUpper = isLastCharUpper;
30
+ isLastCharUpper = false;
31
+ isLastCharLower = true;
32
+ } else {
33
+ isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
34
+ isLastLastCharUpper = isLastCharUpper;
35
+ isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
36
+ }
37
+ }
38
+ return string;
39
+ };
40
+ var preserveConsecutiveUppercase = (input, toLowerCase) => {
41
+ LEADING_CAPITAL.lastIndex = 0;
42
+ return input.replaceAll(LEADING_CAPITAL, (match) => toLowerCase(match));
43
+ };
44
+ var postProcess = (input, toUpperCase) => {
45
+ SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
46
+ NUMBERS_AND_IDENTIFIER.lastIndex = 0;
47
+ return input.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ["_", "-"].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match)).replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));
48
+ };
49
+ function camelCase(input, options) {
50
+ if (!(typeof input === "string" || Array.isArray(input))) {
51
+ throw new TypeError("Expected the input to be `string | string[]`");
52
+ }
53
+ options = {
54
+ pascalCase: false,
55
+ preserveConsecutiveUppercase: false,
56
+ ...options
57
+ };
58
+ if (Array.isArray(input)) {
59
+ input = input.map((x) => x.trim()).filter((x) => x.length).join("-");
60
+ } else {
61
+ input = input.trim();
62
+ }
63
+ if (input.length === 0) {
64
+ return "";
65
+ }
66
+ const toLowerCase = options.locale === false ? (string) => string.toLowerCase() : (string) => string.toLocaleLowerCase(options.locale);
67
+ const toUpperCase = options.locale === false ? (string) => string.toUpperCase() : (string) => string.toLocaleUpperCase(options.locale);
68
+ if (input.length === 1) {
69
+ if (SEPARATORS.test(input)) {
70
+ return "";
71
+ }
72
+ return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
73
+ }
74
+ const hasUpperCase = input !== toLowerCase(input);
75
+ if (hasUpperCase) {
76
+ input = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);
77
+ }
78
+ input = input.replace(LEADING_SEPARATORS, "");
79
+ input = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);
80
+ if (options.pascalCase) {
81
+ input = toUpperCase(input.charAt(0)) + input.slice(1);
82
+ }
83
+ return postProcess(input, toUpperCase);
84
+ }
85
+
86
+ // src/index.ts
4
87
  import contentType from "content-type";
5
88
  import Oas from "oas";
6
89
  import { matchesMimeType } from "oas/utils";
7
90
  import { isReservedOrBuiltinsLC } from "reserved2";
8
- import stringifyObject from "stringify-object";
91
+
92
+ // node_modules/is-regexp/index.js
93
+ var { toString } = Object.prototype;
94
+ function isRegexp(value) {
95
+ return toString.call(value) === "[object RegExp]";
96
+ }
97
+
98
+ // node_modules/is-obj/index.js
99
+ function isObject(value) {
100
+ const type = typeof value;
101
+ return value !== null && (type === "object" || type === "function");
102
+ }
103
+
104
+ // ../../node_modules/get-own-enumerable-keys/index.js
105
+ var { propertyIsEnumerable } = Object.prototype;
106
+ function getOwnEnumerableKeys(object) {
107
+ return [
108
+ ...Object.keys(object),
109
+ ...Object.getOwnPropertySymbols(object).filter((key) => propertyIsEnumerable.call(object, key))
110
+ ];
111
+ }
112
+
113
+ // node_modules/stringify-object/index.js
114
+ function stringifyObject(input, options, pad) {
115
+ const seen = [];
116
+ return function stringify2(input2, options2 = {}, pad2 = "") {
117
+ const indent = options2.indent || " ";
118
+ let tokens;
119
+ if (options2.inlineCharacterLimit === void 0) {
120
+ tokens = {
121
+ newline: "\n",
122
+ newlineOrSpace: "\n",
123
+ pad: pad2,
124
+ indent: pad2 + indent
125
+ };
126
+ } else {
127
+ tokens = {
128
+ newline: "@@__STRINGIFY_OBJECT_NEW_LINE__@@",
129
+ newlineOrSpace: "@@__STRINGIFY_OBJECT_NEW_LINE_OR_SPACE__@@",
130
+ pad: "@@__STRINGIFY_OBJECT_PAD__@@",
131
+ indent: "@@__STRINGIFY_OBJECT_INDENT__@@"
132
+ };
133
+ }
134
+ const expandWhiteSpace = (string) => {
135
+ if (options2.inlineCharacterLimit === void 0) {
136
+ return string;
137
+ }
138
+ const oneLined = string.replace(new RegExp(tokens.newline, "g"), "").replace(new RegExp(tokens.newlineOrSpace, "g"), " ").replace(new RegExp(tokens.pad + "|" + tokens.indent, "g"), "");
139
+ if (oneLined.length <= options2.inlineCharacterLimit) {
140
+ return oneLined;
141
+ }
142
+ return string.replace(new RegExp(tokens.newline + "|" + tokens.newlineOrSpace, "g"), "\n").replace(new RegExp(tokens.pad, "g"), pad2).replace(new RegExp(tokens.indent, "g"), pad2 + indent);
143
+ };
144
+ if (seen.includes(input2)) {
145
+ return '"[Circular]"';
146
+ }
147
+ if (input2 === null || input2 === void 0 || typeof input2 === "number" || typeof input2 === "boolean" || typeof input2 === "function" || typeof input2 === "symbol" || isRegexp(input2)) {
148
+ return String(input2);
149
+ }
150
+ if (input2 instanceof Date) {
151
+ return `new Date('${input2.toISOString()}')`;
152
+ }
153
+ if (Array.isArray(input2)) {
154
+ if (input2.length === 0) {
155
+ return "[]";
156
+ }
157
+ seen.push(input2);
158
+ const returnValue = "[" + tokens.newline + input2.map((element, i) => {
159
+ const eol = input2.length - 1 === i ? tokens.newline : "," + tokens.newlineOrSpace;
160
+ let value = stringify2(element, options2, pad2 + indent);
161
+ if (options2.transform) {
162
+ value = options2.transform(input2, i, value);
163
+ }
164
+ return tokens.indent + value + eol;
165
+ }).join("") + tokens.pad + "]";
166
+ seen.pop();
167
+ return expandWhiteSpace(returnValue);
168
+ }
169
+ if (isObject(input2)) {
170
+ let objectKeys = getOwnEnumerableKeys(input2);
171
+ if (options2.filter) {
172
+ objectKeys = objectKeys.filter((element) => options2.filter(input2, element));
173
+ }
174
+ if (objectKeys.length === 0) {
175
+ return "{}";
176
+ }
177
+ seen.push(input2);
178
+ const returnValue = "{" + tokens.newline + objectKeys.map((element, index) => {
179
+ const eol = objectKeys.length - 1 === index ? tokens.newline : "," + tokens.newlineOrSpace;
180
+ const isSymbol = typeof element === "symbol";
181
+ const isClassic = !isSymbol && /^[a-z$_][$\w]*$/i.test(element);
182
+ const key = isSymbol || isClassic ? element : stringify2(element, options2);
183
+ let value = stringify2(input2[element], options2, pad2 + indent);
184
+ if (options2.transform) {
185
+ value = options2.transform(input2, element, value);
186
+ }
187
+ return tokens.indent + String(key) + ": " + value + eol;
188
+ }).join("") + tokens.pad + "}";
189
+ seen.pop();
190
+ return expandWhiteSpace(returnValue);
191
+ }
192
+ input2 = input2.replace(/\\/g, "\\\\");
193
+ input2 = String(input2).replace(/[\r\n]/g, (x) => x === "\n" ? "\\n" : "\\r");
194
+ if (options2.singleQuotes === false) {
195
+ input2 = input2.replace(/"/g, '\\"');
196
+ return `"${input2}"`;
197
+ }
198
+ input2 = input2.replace(/'/g, "\\'");
199
+ return `'${input2}'`;
200
+ }(input, options, pad);
201
+ }
202
+
203
+ // src/index.ts
9
204
  var registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;
10
205
  function getProjectPrefixFromRegistryUUID(uri) {
11
206
  const matches = uri.match(registryUUIDRegex);
@@ -68,36 +263,39 @@ var client = {
68
263
  title: "API",
69
264
  link: "https://npm.im/api",
70
265
  description: "Automatic SDK generation from an OpenAPI definition.",
71
- extname: ".js"
266
+ extname: ".js",
267
+ installation: "npx api install {packageName}"
72
268
  },
73
269
  convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {
74
270
  const opts = {
75
271
  ...options
76
272
  };
77
- if (!("apiDefinitionUri" in opts)) {
78
- throw new Error("This HTTP Snippet client must have an `apiDefinitionUri` option supplied to it.");
79
- } else if (!("apiDefinition" in opts)) {
80
- throw new Error("This HTTP Snippet client must have an `apiDefinition` option supplied to it.");
273
+ if (!opts?.api) {
274
+ throw new Error("This HTTPSnippet client must have an `api` config supplied to it.");
275
+ } else if (!opts?.api?.definition) {
276
+ throw new Error("This HTTPSnippet client must have an `api.definition` option supplied to it.");
277
+ } else if (!opts?.api?.registryURI) {
278
+ throw new Error("This HTTPSnippet client must have an `api.registryURI` option supplied to it.");
81
279
  }
82
280
  const method = source.method.toLowerCase();
83
- const oas = new Oas(opts.apiDefinition);
281
+ const oas = new Oas(opts.api.definition);
84
282
  const apiDefinition = oas.getDefinition();
85
283
  const foundOperation = oas.findOperation(url, method);
86
284
  if (!foundOperation) {
87
285
  throw new Error(
88
- `Unable to locate a matching operation in the supplied \`apiDefinition\` for: ${source.method} ${url}`
286
+ `Unable to locate a matching operation in the supplied \`api.definition\` for: ${source.method} ${url}`
89
287
  );
90
288
  }
91
289
  let sdkPackageName;
92
290
  let sdkVariable;
93
- if (opts.identifier) {
94
- sdkPackageName = opts.identifier;
95
- sdkVariable = camelCase(opts.identifier);
291
+ if (opts.api.identifier) {
292
+ sdkPackageName = opts.api.identifier;
293
+ sdkVariable = camelCase(opts.api.identifier);
96
294
  if (isReservedOrBuiltinsLC(sdkVariable)) {
97
295
  sdkVariable = `_${sdkVariable}`;
98
296
  }
99
297
  } else {
100
- sdkPackageName = getProjectPrefixFromRegistryUUID(opts.apiDefinitionUri);
298
+ sdkPackageName = getProjectPrefixFromRegistryUUID(opts.api.registryURI);
101
299
  sdkVariable = "sdk";
102
300
  }
103
301
  const operationSlugs = foundOperation.url.slugs;
@@ -237,7 +435,11 @@ var client = {
237
435
  return join();
238
436
  }
239
437
  };
240
- var src_default = client;
438
+ var plugin = {
439
+ target: "node",
440
+ client
441
+ };
442
+ var src_default = plugin;
241
443
  export {
242
444
  src_default as default
243
445
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { ReducedHelperObject } from '@readme/httpsnippet/helpers/reducer';\nimport type { Client } from '@readme/httpsnippet/targets';\nimport type Operation from 'oas/operation';\nimport type { HttpMethods, OASDocument } from 'oas/rmoas.types';\n\nimport { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';\nimport camelCase from 'camelcase';\nimport contentType from 'content-type';\nimport Oas from 'oas';\nimport { matchesMimeType } from 'oas/utils';\nimport { isReservedOrBuiltinsLC } from 'reserved2';\nimport stringifyObject from 'stringify-object';\n\n/**\n * @note This regex also exists in `api/fetcher`.\n *\n * @example @petstore/v1.0#n6kvf10vakpemvplx\n * @example @petstore#n6kvf10vakpemvplx\n */\nconst registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;\n\n/**\n * @note This function also exists in `api/fetcher`.\n */\nfunction getProjectPrefixFromRegistryUUID(uri: string) {\n const matches = uri.match(registryUUIDRegex);\n if (!matches) {\n return undefined;\n }\n\n return matches.groups?.project;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction stringify(obj: any, opts = {}) {\n return stringifyObject(obj, { indent: ' ', ...opts });\n}\n\nfunction buildAuthSnippet(sdkVariable: string, authKey: string | string[]) {\n // Auth key will be an array for Basic auth cases.\n if (Array.isArray(authKey)) {\n const auth: string[] = [];\n authKey.forEach((token, i) => {\n // If the token part is the last part of the key and it's empty, don't add it to the snippet.\n if (token.length === 0 && authKey.length > 1 && i === authKey.length - 1) {\n return;\n }\n\n auth.push(`'${token.replace(/'/g, \"\\\\'\")}'`);\n });\n\n return `${sdkVariable}.auth(${auth.join(', ')});`;\n }\n\n return `${sdkVariable}.auth('${authKey.replace(/'/g, \"\\\\'\")}');`;\n}\n\nfunction getAuthSources(operation: Operation) {\n const matchers: { cookie: string[]; header: Record<string, string>; query: string[] } = {\n header: {},\n query: [],\n cookie: [],\n };\n\n if (operation.getSecurity().length === 0) {\n return matchers;\n }\n\n Object.entries(operation.prepareSecurity()).forEach(([, schemes]) => {\n schemes.forEach(scheme => {\n if (scheme.type === 'http') {\n if (scheme.scheme === 'basic') {\n matchers.header.authorization = 'Basic';\n } else if (scheme.scheme === 'bearer') {\n matchers.header.authorization = 'Bearer';\n }\n } else if (scheme.type === 'oauth2') {\n matchers.header.authorization = 'Bearer';\n } else if (scheme.type === 'apiKey') {\n if (scheme.in === 'query') {\n matchers.query.push(scheme.name);\n } else if (scheme.in === 'header') {\n // The way that this asterisk header matcher works is that since this `apiKey` goes in a\n // named header (`scheme.name`) because the header is the key, we're matching against the\n // entire header -- counter to the way that the HTTP basic matcher above works where we\n // match and extract the API key from everything after `Basic ` in the `Authorization`\n // header.\n matchers.header[scheme.name.toLowerCase()] = '*';\n } else if (scheme.in === 'cookie') {\n matchers.cookie.push(scheme.name);\n }\n }\n });\n });\n\n return matchers;\n}\n\ninterface APIOptions {\n apiDefinition: OASDocument;\n /**\n * The URI that is used to download this API definition from `npx api install`.\n *\n * @example @developers/v2.0#17273l2glm9fq4l5\n */\n apiDefinitionUri: string;\n escapeBrackets?: boolean;\n /**\n * The string to identify this SDK as. This is used in the `import sdk from '@api/<identifier>'`\n * sample as well as the the variable name we attach the SDK to.\n *\n * @example developers\n */\n identifier?: string;\n indent?: string | false;\n}\n\nconst client: Client<APIOptions> = {\n info: {\n key: 'api',\n title: 'API',\n link: 'https://npm.im/api',\n description: 'Automatic SDK generation from an OpenAPI definition.',\n extname: '.js',\n },\n convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {\n const opts = {\n ...options,\n } as APIOptions;\n\n if (!('apiDefinitionUri' in opts)) {\n throw new Error('This HTTP Snippet client must have an `apiDefinitionUri` option supplied to it.');\n } else if (!('apiDefinition' in opts)) {\n throw new Error('This HTTP Snippet client must have an `apiDefinition` option supplied to it.');\n }\n\n const method = source.method.toLowerCase() as HttpMethods;\n const oas = new Oas(opts.apiDefinition);\n const apiDefinition = oas.getDefinition();\n const foundOperation = oas.findOperation(url, method);\n if (!foundOperation) {\n throw new Error(\n `Unable to locate a matching operation in the supplied \\`apiDefinition\\` for: ${source.method} ${url}`,\n );\n }\n\n let sdkPackageName;\n let sdkVariable: string;\n if (opts.identifier) {\n sdkPackageName = opts.identifier;\n\n sdkVariable = camelCase(opts.identifier);\n if (isReservedOrBuiltinsLC(sdkVariable)) {\n // If this identifier is a reserved JS word then we should prefix it with an underscore so\n // this snippet can be valid code.\n sdkVariable = `_${sdkVariable}`;\n }\n } else {\n sdkPackageName = getProjectPrefixFromRegistryUUID(opts.apiDefinitionUri);\n sdkVariable = 'sdk';\n }\n\n const operationSlugs = foundOperation.url.slugs;\n const operation = oas.operation(foundOperation.url.nonNormalizedPath, method);\n const operationPathParameters = operation.getParameters().filter(param => param.in === 'path');\n const path = operation.path;\n const authData: string[] = [];\n const authSources = getAuthSources(operation);\n\n const { blank, push, join } = new CodeBuilder({ indent: opts.indent || ' ' });\n\n push(`import ${sdkVariable} from '@api/${sdkPackageName}';`);\n blank();\n\n // If we have multiple servers configured and our source URL differs from the stock URL that we\n // receive from our `oas` library then the URL either has server variables contained in it (that\n // don't match the defaults), or the OAS offers alternate server URLs and we should expose that\n // in the generated snippet.\n const configData = [];\n if ((apiDefinition.servers || []).length > 1) {\n const stockUrl = oas.url();\n const baseUrl = url.replace(path, '');\n if (baseUrl !== stockUrl) {\n const serverVars = oas.splitVariables(baseUrl);\n const serverUrl = serverVars ? oas.url(serverVars.selected, serverVars.variables) : baseUrl;\n\n configData.push(`sdk.server('${serverUrl}');`);\n }\n }\n\n let metadata: Record<string, string | string[]> = {};\n Object.keys(queryObj).forEach(param => {\n if (authSources.query.includes(param)) {\n authData.push(buildAuthSnippet(sdkVariable, queryObj[param]));\n\n // If this query param is part of an auth source then we don't want it doubled up in the\n // snippet.\n return;\n }\n\n metadata[param] = queryObj[param];\n });\n\n Object.keys(cookiesObj).forEach(cookie => {\n if (authSources.cookie.includes(cookie)) {\n authData.push(buildAuthSnippet(sdkVariable, cookiesObj[cookie]));\n\n // If this cookie is part of an auth source then we don't want it doubled up.\n return;\n }\n\n // Note that we may have the potential to overlap any cookie that also shares the name as\n // another metadata parameter. This problem is currently inherent to `api` and not this\n // snippet generator.\n metadata[cookie] = cookiesObj[cookie];\n });\n\n // If we have path parameters present we should add them into the metadata object.\n Array.from(Object.entries(operationSlugs)).forEach(([param, value]) => {\n // The keys in `operationSlugs` will always be prefixed with a `:` in the `oas` library so\n // we can safely do this substring here without asserting this context.\n const cleanedParam = param.substring(1);\n\n // If our incoming path slug out of `oas.findOperation()` has been sanitized and is missing\n // a hyphen, but there is a parameter in the OpenAPI definition that matches what our\n // hyphen-less slug is then we should use that for the snippet.\n const unsanitizedParam = operationPathParameters.find(p => {\n return p.name.includes('-') && p.name.replace(/-/g, '') === cleanedParam ? p.name : false;\n });\n\n if (unsanitizedParam) {\n metadata[unsanitizedParam.name] = value;\n } else {\n metadata[cleanedParam] = value;\n }\n });\n\n if (Object.keys(headersObj).length) {\n const headers = headersObj;\n const requestHeaders: ReducedHelperObject = {};\n\n Object.keys(headers).forEach(header => {\n // Headers in HTTPSnippet are case-insensitive so we need to add in some special handling to\n // make sure we're able to match them properly.\n const headerLower = header.toLowerCase();\n\n if (headerLower in authSources.header) {\n // If this header has been set up as an authentication header, let's remove it and add it\n // into our auth data so we can build up an `.auth()` snippet for the SDK.\n const authScheme = authSources.header[headerLower];\n if (authScheme === '*') {\n authData.push(buildAuthSnippet(sdkVariable, headers[header]));\n } else {\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n let authKey = headers[header].replace(`${authSources.header[headerLower]} `, '');\n if (authScheme.toLowerCase() === 'basic') {\n authKey = Buffer.from(authKey, 'base64').toString('ascii');\n authKey = authKey.split(':');\n }\n\n authData.push(buildAuthSnippet(sdkVariable, authKey));\n }\n\n delete headers[header];\n return;\n } else if (headerLower === 'content-type') {\n // `Content-Type` headers are automatically added within the SDK so we can filter them out\n // if they don't have parameters attached to them.\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n const parsedContentType = contentType.parse(headers[header]);\n if (!Object.keys(parsedContentType.parameters).length) {\n delete headers[header];\n return;\n }\n } else if (headerLower === 'accept') {\n // If the `Accept` header here is JSON-like header then we can remove it from the code\n // snippet because `api` natively supports and prioritizes JSON over any other mime type.\n if (matchesMimeType.json(headers[header] as string)) {\n delete headers[header];\n return;\n }\n }\n\n // If we haven't used our header anywhere else, or we've deleted it from the payload\n // because it'll be handled internally by `api` then we should add it into our code snippet.\n if (['accept', 'content-type'].includes(headerLower)) {\n requestHeaders[headerLower] = headers[header];\n } else {\n // Non-reserved headers retain their casing because we want to generate a snippet that\n // matches the TS types that are created during codegeneration.\n requestHeaders[header] = headers[header];\n }\n });\n\n if (Object.keys(requestHeaders).length > 0) {\n metadata = Object.assign(metadata, requestHeaders);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let body: any;\n switch (postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n body = postData.paramsObj;\n break;\n\n case 'application/json':\n if (postData.jsonObj) {\n body = postData.jsonObj;\n }\n break;\n\n case 'multipart/form-data':\n if (postData.params) {\n body = {};\n\n // If there's a `Content-Type` header present in the metadata, but it's for the\n // `multipart/form-data` request then dump it off the snippet. We shouldn't offload that\n // unnecessary bloat of multipart boundaries to the user, instead letting the SDK handle it\n // automatically.\n if ('content-type' in metadata && metadata['content-type'].indexOf('multipart/form-data') === 0) {\n delete metadata['content-type'];\n }\n\n postData.params.forEach(param => {\n if (param.fileName) {\n body[param.name] = param.fileName;\n } else {\n body[param.name] = param.value;\n }\n });\n }\n break;\n\n default:\n if (postData.text) {\n body = postData.text;\n }\n }\n\n const args = [];\n\n const accessor = operation.getOperationId({ camelCase: true });\n\n // If we're going to be rendering out body params and metadata we should cut their character\n // limit in half because we'll be rendering them in their own lines.\n const inlineCharacterLimit = typeof body !== 'undefined' && Object.keys(metadata).length > 0 ? 40 : 80;\n if (typeof body !== 'undefined') {\n args.push(stringify(body, { inlineCharacterLimit }));\n }\n\n if (Object.keys(metadata).length > 0) {\n args.push(stringify(metadata, { inlineCharacterLimit }));\n }\n\n if (authData.length) {\n push(authData.join('\\n'));\n }\n\n if (configData.length) {\n push(configData.join('\\n'));\n }\n\n push(`${sdkVariable}.${accessor}(${args.join(', ')})`);\n push('.then(({ data }) => console.log(data))', 1);\n push('.catch(err => console.error(err));', 1);\n\n return join();\n },\n};\n\nexport default client;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/camelcase/index.js","../node_modules/is-regexp/index.js","../node_modules/is-obj/index.js","../../../node_modules/get-own-enumerable-keys/index.js","../node_modules/stringify-object/index.js"],"sourcesContent":["import type { ReducedHelperObject } from '@readme/httpsnippet/helpers/reducer';\nimport type { Client, ClientPlugin } from '@readme/httpsnippet/targets';\nimport type { Operation } from 'oas/operation';\nimport type { HttpMethods, OASDocument } from 'oas/types';\n\nimport { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';\nimport camelCase from 'camelcase'; // eslint-disable-line import/no-extraneous-dependencies\nimport contentType from 'content-type';\nimport Oas from 'oas';\nimport { matchesMimeType } from 'oas/utils';\nimport { isReservedOrBuiltinsLC } from 'reserved2';\nimport stringifyObject from 'stringify-object'; // eslint-disable-line import/no-extraneous-dependencies\n\n/**\n * @note This regex also exists in `api/fetcher`.\n *\n * @example @petstore/v1.0#n6kvf10vakpemvplx\n * @example @petstore#n6kvf10vakpemvplx\n */\nconst registryUUIDRegex = /^@(?<project>[a-zA-Z0-9-_]+)(\\/?(?<version>.+))?#(?<uuid>[a-z0-9]+)$/;\n\n/**\n * @note This function also exists in `api/fetcher`.\n */\nfunction getProjectPrefixFromRegistryUUID(uri: string) {\n const matches = uri.match(registryUUIDRegex);\n if (!matches) {\n return undefined;\n }\n\n return matches.groups?.project;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction stringify(obj: any, opts = {}) {\n return stringifyObject(obj, { indent: ' ', ...opts });\n}\n\nfunction buildAuthSnippet(sdkVariable: string, authKey: string | string[]) {\n // Auth key will be an array for Basic auth cases.\n if (Array.isArray(authKey)) {\n const auth: string[] = [];\n authKey.forEach((token, i) => {\n // If the token part is the last part of the key and it's empty, don't add it to the snippet.\n if (token.length === 0 && authKey.length > 1 && i === authKey.length - 1) {\n return;\n }\n\n auth.push(`'${token.replace(/'/g, \"\\\\'\")}'`);\n });\n\n return `${sdkVariable}.auth(${auth.join(', ')});`;\n }\n\n return `${sdkVariable}.auth('${authKey.replace(/'/g, \"\\\\'\")}');`;\n}\n\nfunction getAuthSources(operation: Operation) {\n const matchers: { cookie: string[]; header: Record<string, string>; query: string[] } = {\n header: {},\n query: [],\n cookie: [],\n };\n\n if (operation.getSecurity().length === 0) {\n return matchers;\n }\n\n Object.entries(operation.prepareSecurity()).forEach(([, schemes]) => {\n schemes.forEach(scheme => {\n if (scheme.type === 'http') {\n if (scheme.scheme === 'basic') {\n matchers.header.authorization = 'Basic';\n } else if (scheme.scheme === 'bearer') {\n matchers.header.authorization = 'Bearer';\n }\n } else if (scheme.type === 'oauth2') {\n matchers.header.authorization = 'Bearer';\n } else if (scheme.type === 'apiKey') {\n if (scheme.in === 'query') {\n matchers.query.push(scheme.name);\n } else if (scheme.in === 'header') {\n // The way that this asterisk header matcher works is that since this `apiKey` goes in a\n // named header (`scheme.name`) because the header is the key, we're matching against the\n // entire header -- counter to the way that the HTTP basic matcher above works where we\n // match and extract the API key from everything after `Basic ` in the `Authorization`\n // header.\n matchers.header[scheme.name.toLowerCase()] = '*';\n } else if (scheme.in === 'cookie') {\n matchers.cookie.push(scheme.name);\n }\n }\n });\n });\n\n return matchers;\n}\n\ninterface APIOptions {\n api: {\n definition: OASDocument;\n\n /**\n * The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`\n * sample as well as the the variable name we attach the SDK to.\n *\n * @example `@api/developers`\n */\n identifier?: string;\n\n /**\n * The URI that is used to download this API definition from `npx api install`.\n *\n * @example `@developers/v2.0#17273l2glm9fq4l5`\n */\n registryURI: string;\n };\n escapeBrackets?: boolean;\n indent?: string | false;\n}\n\nconst client: Client<APIOptions> = {\n info: {\n key: 'api',\n title: 'API',\n link: 'https://npm.im/api',\n description: 'Automatic SDK generation from an OpenAPI definition.',\n extname: '.js',\n installation: 'npx api install {packageName}',\n },\n convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {\n const opts = {\n ...options,\n } as APIOptions;\n\n if (!opts?.api) {\n throw new Error('This HTTPSnippet client must have an `api` config supplied to it.');\n } else if (!opts?.api?.definition) {\n throw new Error('This HTTPSnippet client must have an `api.definition` option supplied to it.');\n } else if (!opts?.api?.registryURI) {\n throw new Error('This HTTPSnippet client must have an `api.registryURI` option supplied to it.');\n }\n\n const method = source.method.toLowerCase() as HttpMethods;\n const oas = new Oas(opts.api.definition);\n const apiDefinition = oas.getDefinition();\n const foundOperation = oas.findOperation(url, method);\n if (!foundOperation) {\n throw new Error(\n `Unable to locate a matching operation in the supplied \\`api.definition\\` for: ${source.method} ${url}`,\n );\n }\n\n let sdkPackageName;\n let sdkVariable: string;\n if (opts.api.identifier) {\n sdkPackageName = opts.api.identifier;\n\n sdkVariable = camelCase(opts.api.identifier);\n if (isReservedOrBuiltinsLC(sdkVariable)) {\n // If this identifier is a reserved JS word then we should prefix it with an underscore so\n // this snippet can be valid code.\n sdkVariable = `_${sdkVariable}`;\n }\n } else {\n sdkPackageName = getProjectPrefixFromRegistryUUID(opts.api.registryURI);\n sdkVariable = 'sdk';\n }\n\n const operationSlugs = foundOperation.url.slugs;\n const operation = oas.operation(foundOperation.url.nonNormalizedPath, method);\n const operationPathParameters = operation.getParameters().filter(param => param.in === 'path');\n const path = operation.path;\n const authData: string[] = [];\n const authSources = getAuthSources(operation);\n\n const { blank, push, join } = new CodeBuilder({ indent: opts.indent || ' ' });\n\n push(`import ${sdkVariable} from '@api/${sdkPackageName}';`);\n blank();\n\n // If we have multiple servers configured and our source URL differs from the stock URL that we\n // receive from our `oas` library then the URL either has server variables contained in it (that\n // don't match the defaults), or the OAS offers alternate server URLs and we should expose that\n // in the generated snippet.\n const configData = [];\n if ((apiDefinition.servers || []).length > 1) {\n const stockUrl = oas.url();\n const baseUrl = url.replace(path, '');\n if (baseUrl !== stockUrl) {\n const serverVars = oas.splitVariables(baseUrl);\n const serverUrl = serverVars ? oas.url(serverVars.selected, serverVars.variables) : baseUrl;\n\n configData.push(`sdk.server('${serverUrl}');`);\n }\n }\n\n let metadata: Record<string, string | string[]> = {};\n Object.keys(queryObj).forEach(param => {\n if (authSources.query.includes(param)) {\n authData.push(buildAuthSnippet(sdkVariable, queryObj[param]));\n\n // If this query param is part of an auth source then we don't want it doubled up in the\n // snippet.\n return;\n }\n\n metadata[param] = queryObj[param];\n });\n\n Object.keys(cookiesObj).forEach(cookie => {\n if (authSources.cookie.includes(cookie)) {\n authData.push(buildAuthSnippet(sdkVariable, cookiesObj[cookie]));\n\n // If this cookie is part of an auth source then we don't want it doubled up.\n return;\n }\n\n // Note that we may have the potential to overlap any cookie that also shares the name as\n // another metadata parameter. This problem is currently inherent to `api` and not this\n // snippet generator.\n metadata[cookie] = cookiesObj[cookie];\n });\n\n // If we have path parameters present we should add them into the metadata object.\n Array.from(Object.entries(operationSlugs)).forEach(([param, value]) => {\n // The keys in `operationSlugs` will always be prefixed with a `:` in the `oas` library so\n // we can safely do this substring here without asserting this context.\n const cleanedParam = param.substring(1);\n\n // If our incoming path slug out of `oas.findOperation()` has been sanitized and is missing\n // a hyphen, but there is a parameter in the OpenAPI definition that matches what our\n // hyphen-less slug is then we should use that for the snippet.\n const unsanitizedParam = operationPathParameters.find(p => {\n return p.name.includes('-') && p.name.replace(/-/g, '') === cleanedParam ? p.name : false;\n });\n\n if (unsanitizedParam) {\n metadata[unsanitizedParam.name] = value;\n } else {\n metadata[cleanedParam] = value;\n }\n });\n\n if (Object.keys(headersObj).length) {\n const headers = headersObj;\n const requestHeaders: ReducedHelperObject = {};\n\n Object.keys(headers).forEach(header => {\n // Headers in HTTPSnippet are case-insensitive so we need to add in some special handling to\n // make sure we're able to match them properly.\n const headerLower = header.toLowerCase();\n\n if (headerLower in authSources.header) {\n // If this header has been set up as an authentication header, let's remove it and add it\n // into our auth data so we can build up an `.auth()` snippet for the SDK.\n const authScheme = authSources.header[headerLower];\n if (authScheme === '*') {\n authData.push(buildAuthSnippet(sdkVariable, headers[header]));\n } else {\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n let authKey = headers[header].replace(`${authSources.header[headerLower]} `, '');\n if (authScheme.toLowerCase() === 'basic') {\n authKey = Buffer.from(authKey, 'base64').toString('ascii');\n authKey = authKey.split(':');\n }\n\n authData.push(buildAuthSnippet(sdkVariable, authKey));\n }\n\n delete headers[header];\n return;\n } else if (headerLower === 'content-type') {\n // `Content-Type` headers are automatically added within the SDK so we can filter them out\n // if they don't have parameters attached to them.\n // @ts-expect-error `headers[header]` is typed improperly in HTTPSnippet.\n const parsedContentType = contentType.parse(headers[header]);\n if (!Object.keys(parsedContentType.parameters).length) {\n delete headers[header];\n return;\n }\n } else if (headerLower === 'accept') {\n // If the `Accept` header here is JSON-like header then we can remove it from the code\n // snippet because `api` natively supports and prioritizes JSON over any other mime type.\n if (matchesMimeType.json(headers[header] as string)) {\n delete headers[header];\n return;\n }\n }\n\n // If we haven't used our header anywhere else, or we've deleted it from the payload\n // because it'll be handled internally by `api` then we should add it into our code snippet.\n if (['accept', 'content-type'].includes(headerLower)) {\n requestHeaders[headerLower] = headers[header];\n } else {\n // Non-reserved headers retain their casing because we want to generate a snippet that\n // matches the TS types that are created during codegeneration.\n requestHeaders[header] = headers[header];\n }\n });\n\n if (Object.keys(requestHeaders).length > 0) {\n metadata = Object.assign(metadata, requestHeaders);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let body: any;\n switch (postData.mimeType) {\n case 'application/x-www-form-urlencoded':\n body = postData.paramsObj;\n break;\n\n case 'application/json':\n if (postData.jsonObj) {\n body = postData.jsonObj;\n }\n break;\n\n case 'multipart/form-data':\n if (postData.params) {\n body = {};\n\n // If there's a `Content-Type` header present in the metadata, but it's for the\n // `multipart/form-data` request then dump it off the snippet. We shouldn't offload that\n // unnecessary bloat of multipart boundaries to the user, instead letting the SDK handle it\n // automatically.\n if ('content-type' in metadata && metadata['content-type'].indexOf('multipart/form-data') === 0) {\n delete metadata['content-type'];\n }\n\n postData.params.forEach(param => {\n if (param.fileName) {\n body[param.name] = param.fileName;\n } else {\n body[param.name] = param.value;\n }\n });\n }\n break;\n\n default:\n if (postData.text) {\n body = postData.text;\n }\n }\n\n const args = [];\n\n const accessor = operation.getOperationId({ camelCase: true });\n\n // If we're going to be rendering out body params and metadata we should cut their character\n // limit in half because we'll be rendering them in their own lines.\n const inlineCharacterLimit = typeof body !== 'undefined' && Object.keys(metadata).length > 0 ? 40 : 80;\n if (typeof body !== 'undefined') {\n args.push(stringify(body, { inlineCharacterLimit }));\n }\n\n if (Object.keys(metadata).length > 0) {\n args.push(stringify(metadata, { inlineCharacterLimit }));\n }\n\n if (authData.length) {\n push(authData.join('\\n'));\n }\n\n if (configData.length) {\n push(configData.join('\\n'));\n }\n\n push(`${sdkVariable}.${accessor}(${args.join(', ')})`);\n push('.then(({ data }) => console.log(data))', 1);\n push('.catch(err => console.error(err));', 1);\n\n return join();\n },\n};\n\nconst plugin: ClientPlugin<APIOptions> = {\n target: 'node',\n client,\n};\n\nexport default plugin;\n","const UPPERCASE = /[\\p{Lu}]/u;\nconst LOWERCASE = /[\\p{Ll}]/u;\nconst LEADING_CAPITAL = /^[\\p{Lu}](?![\\p{Lu}])/gu;\nconst IDENTIFIER = /([\\p{Alpha}\\p{N}_]|$)/u;\nconst SEPARATORS = /[_.\\- ]+/;\n\nconst LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);\nconst SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');\nconst NUMBERS_AND_IDENTIFIER = new RegExp('\\\\d+' + IDENTIFIER.source, 'gu');\n\nconst preserveCamelCase = (string, toLowerCase, toUpperCase, preserveConsecutiveUppercase) => {\n\tlet isLastCharLower = false;\n\tlet isLastCharUpper = false;\n\tlet isLastLastCharUpper = false;\n\tlet isLastLastCharPreserved = false;\n\n\tfor (let index = 0; index < string.length; index++) {\n\t\tconst character = string[index];\n\t\tisLastLastCharPreserved = index > 2 ? string[index - 3] === '-' : true;\n\n\t\tif (isLastCharLower && UPPERCASE.test(character)) {\n\t\t\tstring = string.slice(0, index) + '-' + string.slice(index);\n\t\t\tisLastCharLower = false;\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = true;\n\t\t\tindex++;\n\t\t} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase)) {\n\t\t\tstring = string.slice(0, index - 1) + '-' + string.slice(index - 1);\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = false;\n\t\t\tisLastCharLower = true;\n\t\t} else {\n\t\t\tisLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;\n\t\t\tisLastLastCharUpper = isLastCharUpper;\n\t\t\tisLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;\n\t\t}\n\t}\n\n\treturn string;\n};\n\nconst preserveConsecutiveUppercase = (input, toLowerCase) => {\n\tLEADING_CAPITAL.lastIndex = 0;\n\n\treturn input.replaceAll(LEADING_CAPITAL, match => toLowerCase(match));\n};\n\nconst postProcess = (input, toUpperCase) => {\n\tSEPARATORS_AND_IDENTIFIER.lastIndex = 0;\n\tNUMBERS_AND_IDENTIFIER.lastIndex = 0;\n\n\treturn input\n\t\t.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ['_', '-'].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match))\n\t\t.replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));\n};\n\nexport default function camelCase(input, options) {\n\tif (!(typeof input === 'string' || Array.isArray(input))) {\n\t\tthrow new TypeError('Expected the input to be `string | string[]`');\n\t}\n\n\toptions = {\n\t\tpascalCase: false,\n\t\tpreserveConsecutiveUppercase: false,\n\t\t...options,\n\t};\n\n\tif (Array.isArray(input)) {\n\t\tinput = input.map(x => x.trim())\n\t\t\t.filter(x => x.length)\n\t\t\t.join('-');\n\t} else {\n\t\tinput = input.trim();\n\t}\n\n\tif (input.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst toLowerCase = options.locale === false\n\t\t? string => string.toLowerCase()\n\t\t: string => string.toLocaleLowerCase(options.locale);\n\n\tconst toUpperCase = options.locale === false\n\t\t? string => string.toUpperCase()\n\t\t: string => string.toLocaleUpperCase(options.locale);\n\n\tif (input.length === 1) {\n\t\tif (SEPARATORS.test(input)) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn options.pascalCase ? toUpperCase(input) : toLowerCase(input);\n\t}\n\n\tconst hasUpperCase = input !== toLowerCase(input);\n\n\tif (hasUpperCase) {\n\t\tinput = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);\n\t}\n\n\tinput = input.replace(LEADING_SEPARATORS, '');\n\tinput = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);\n\n\tif (options.pascalCase) {\n\t\tinput = toUpperCase(input.charAt(0)) + input.slice(1);\n\t}\n\n\treturn postProcess(input, toUpperCase);\n}\n","const {toString} = Object.prototype;\n\nexport default function isRegexp(value) {\n\treturn toString.call(value) === '[object RegExp]';\n}\n","export default function isObject(value) {\n\tconst type = typeof value;\n\treturn value !== null && (type === 'object' || type === 'function');\n}\n","const {propertyIsEnumerable} = Object.prototype;\n\nexport default function getOwnEnumerableKeys(object) {\n\treturn [\n\t\t...Object.keys(object),\n\t\t...Object.getOwnPropertySymbols(object)\n\t\t\t.filter(key => propertyIsEnumerable.call(object, key)),\n\t];\n}\n","import isRegexp from 'is-regexp';\nimport isObject from 'is-obj';\nimport getOwnEnumerableKeys from 'get-own-enumerable-keys';\n\nexport default function stringifyObject(input, options, pad) {\n\tconst seen = [];\n\n\treturn (function stringify(input, options = {}, pad = '') {\n\t\tconst indent = options.indent || '\\t';\n\n\t\tlet tokens;\n\t\tif (options.inlineCharacterLimit === undefined) {\n\t\t\ttokens = {\n\t\t\t\tnewline: '\\n',\n\t\t\t\tnewlineOrSpace: '\\n',\n\t\t\t\tpad,\n\t\t\t\tindent: pad + indent,\n\t\t\t};\n\t\t} else {\n\t\t\ttokens = {\n\t\t\t\tnewline: '@@__STRINGIFY_OBJECT_NEW_LINE__@@',\n\t\t\t\tnewlineOrSpace: '@@__STRINGIFY_OBJECT_NEW_LINE_OR_SPACE__@@',\n\t\t\t\tpad: '@@__STRINGIFY_OBJECT_PAD__@@',\n\t\t\t\tindent: '@@__STRINGIFY_OBJECT_INDENT__@@',\n\t\t\t};\n\t\t}\n\n\t\tconst expandWhiteSpace = string => {\n\t\t\tif (options.inlineCharacterLimit === undefined) {\n\t\t\t\treturn string;\n\t\t\t}\n\n\t\t\tconst oneLined = string\n\t\t\t\t.replace(new RegExp(tokens.newline, 'g'), '')\n\t\t\t\t.replace(new RegExp(tokens.newlineOrSpace, 'g'), ' ')\n\t\t\t\t.replace(new RegExp(tokens.pad + '|' + tokens.indent, 'g'), '');\n\n\t\t\tif (oneLined.length <= options.inlineCharacterLimit) {\n\t\t\t\treturn oneLined;\n\t\t\t}\n\n\t\t\treturn string\n\t\t\t\t.replace(new RegExp(tokens.newline + '|' + tokens.newlineOrSpace, 'g'), '\\n')\n\t\t\t\t.replace(new RegExp(tokens.pad, 'g'), pad)\n\t\t\t\t.replace(new RegExp(tokens.indent, 'g'), pad + indent);\n\t\t};\n\n\t\tif (seen.includes(input)) {\n\t\t\treturn '\"[Circular]\"';\n\t\t}\n\n\t\tif (\n\t\t\tinput === null\n\t\t\t|| input === undefined\n\t\t\t|| typeof input === 'number'\n\t\t\t|| typeof input === 'boolean'\n\t\t\t|| typeof input === 'function'\n\t\t\t|| typeof input === 'symbol'\n\t\t\t|| isRegexp(input)\n\t\t) {\n\t\t\treturn String(input);\n\t\t}\n\n\t\tif (input instanceof Date) {\n\t\t\treturn `new Date('${input.toISOString()}')`;\n\t\t}\n\n\t\tif (Array.isArray(input)) {\n\t\t\tif (input.length === 0) {\n\t\t\t\treturn '[]';\n\t\t\t}\n\n\t\t\tseen.push(input);\n\n\t\t\tconst returnValue = '[' + tokens.newline + input.map((element, i) => {\n\t\t\t\tconst eol = input.length - 1 === i ? tokens.newline : ',' + tokens.newlineOrSpace;\n\n\t\t\t\tlet value = stringify(element, options, pad + indent);\n\t\t\t\tif (options.transform) {\n\t\t\t\t\tvalue = options.transform(input, i, value);\n\t\t\t\t}\n\n\t\t\t\treturn tokens.indent + value + eol;\n\t\t\t}).join('') + tokens.pad + ']';\n\n\t\t\tseen.pop();\n\n\t\t\treturn expandWhiteSpace(returnValue);\n\t\t}\n\n\t\tif (isObject(input)) {\n\t\t\tlet objectKeys = getOwnEnumerableKeys(input);\n\n\t\t\tif (options.filter) {\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument\n\t\t\t\tobjectKeys = objectKeys.filter(element => options.filter(input, element));\n\t\t\t}\n\n\t\t\tif (objectKeys.length === 0) {\n\t\t\t\treturn '{}';\n\t\t\t}\n\n\t\t\tseen.push(input);\n\n\t\t\tconst returnValue = '{' + tokens.newline + objectKeys.map((element, index) => {\n\t\t\t\tconst eol = objectKeys.length - 1 === index ? tokens.newline : ',' + tokens.newlineOrSpace;\n\t\t\t\tconst isSymbol = typeof element === 'symbol';\n\t\t\t\tconst isClassic = !isSymbol && /^[a-z$_][$\\w]*$/i.test(element);\n\t\t\t\tconst key = isSymbol || isClassic ? element : stringify(element, options);\n\n\t\t\t\tlet value = stringify(input[element], options, pad + indent);\n\t\t\t\tif (options.transform) {\n\t\t\t\t\tvalue = options.transform(input, element, value);\n\t\t\t\t}\n\n\t\t\t\treturn tokens.indent + String(key) + ': ' + value + eol;\n\t\t\t}).join('') + tokens.pad + '}';\n\n\t\t\tseen.pop();\n\n\t\t\treturn expandWhiteSpace(returnValue);\n\t\t}\n\n\t\tinput = input.replace(/\\\\/g, '\\\\\\\\');\n\t\tinput = String(input).replace(/[\\r\\n]/g, x => x === '\\n' ? '\\\\n' : '\\\\r');\n\n\t\tif (options.singleQuotes === false) {\n\t\t\tinput = input.replace(/\"/g, '\\\\\"');\n\t\t\treturn `\"${input}\"`;\n\t\t}\n\n\t\tinput = input.replace(/'/g, '\\\\\\'');\n\t\treturn `'${input}'`;\n\t})(input, options, pad);\n}\n"],"mappings":"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","names":["preserveConsecutiveUppercase","stringify","input","options","pad"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "httpsnippet-client-api",
3
- "version": "7.0.0-beta.3",
3
+ "version": "7.0.0-beta.4",
4
4
  "description": "An HTTPSnippet client for generating snippets for the `api` module.",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -36,14 +36,12 @@
36
36
  "node": ">=18"
37
37
  },
38
38
  "dependencies": {
39
- "camelcase": "^8.0.0",
40
39
  "content-type": "^1.0.5",
41
- "reserved2": "^0.1.5",
42
- "stringify-object": "^5.0.0"
40
+ "reserved2": "^0.1.5"
43
41
  },
44
42
  "peerDependencies": {
45
- "@readme/httpsnippet": ">=8",
46
- "oas": "^23.0.0"
43
+ "@readme/httpsnippet": ">=8.1.2",
44
+ "oas": "^24.0.0"
47
45
  },
48
46
  "devDependencies": {
49
47
  "@readme/oas-examples": "^5.12.0",
@@ -51,9 +49,11 @@
51
49
  "@types/content-type": "^1.1.6",
52
50
  "@types/stringify-object": "^4.0.3",
53
51
  "@vitest/coverage-v8": "^0.34.4",
52
+ "camelcase": "^8.0.0",
53
+ "stringify-object": "^5.0.0",
54
54
  "typescript": "^5.2.2",
55
55
  "vitest": "^0.34.5"
56
56
  },
57
57
  "prettier": "@readme/eslint-config/prettier",
58
- "gitHead": "9dbc86caab9ae4b49e7d0dac52ab6c25f5f46170"
58
+ "gitHead": "17f994aef85a15a64b1a8010d944c65dba85470e"
59
59
  }
package/src/index.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import type { ReducedHelperObject } from '@readme/httpsnippet/helpers/reducer';
2
- import type { Client } from '@readme/httpsnippet/targets';
3
- import type Operation from 'oas/operation';
4
- import type { HttpMethods, OASDocument } from 'oas/rmoas.types';
2
+ import type { Client, ClientPlugin } from '@readme/httpsnippet/targets';
3
+ import type { Operation } from 'oas/operation';
4
+ import type { HttpMethods, OASDocument } from 'oas/types';
5
5
 
6
6
  import { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';
7
- import camelCase from 'camelcase';
7
+ import camelCase from 'camelcase'; // eslint-disable-line import/no-extraneous-dependencies
8
8
  import contentType from 'content-type';
9
9
  import Oas from 'oas';
10
10
  import { matchesMimeType } from 'oas/utils';
11
11
  import { isReservedOrBuiltinsLC } from 'reserved2';
12
- import stringifyObject from 'stringify-object';
12
+ import stringifyObject from 'stringify-object'; // eslint-disable-line import/no-extraneous-dependencies
13
13
 
14
14
  /**
15
15
  * @note This regex also exists in `api/fetcher`.
@@ -97,21 +97,25 @@ function getAuthSources(operation: Operation) {
97
97
  }
98
98
 
99
99
  interface APIOptions {
100
- apiDefinition: OASDocument;
101
- /**
102
- * The URI that is used to download this API definition from `npx api install`.
103
- *
104
- * @example @developers/v2.0#17273l2glm9fq4l5
105
- */
106
- apiDefinitionUri: string;
100
+ api: {
101
+ definition: OASDocument;
102
+
103
+ /**
104
+ * The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`
105
+ * sample as well as the the variable name we attach the SDK to.
106
+ *
107
+ * @example `@api/developers`
108
+ */
109
+ identifier?: string;
110
+
111
+ /**
112
+ * The URI that is used to download this API definition from `npx api install`.
113
+ *
114
+ * @example `@developers/v2.0#17273l2glm9fq4l5`
115
+ */
116
+ registryURI: string;
117
+ };
107
118
  escapeBrackets?: boolean;
108
- /**
109
- * The string to identify this SDK as. This is used in the `import sdk from '@api/<identifier>'`
110
- * sample as well as the the variable name we attach the SDK to.
111
- *
112
- * @example developers
113
- */
114
- identifier?: string;
115
119
  indent?: string | false;
116
120
  }
117
121
 
@@ -122,41 +126,44 @@ const client: Client<APIOptions> = {
122
126
  link: 'https://npm.im/api',
123
127
  description: 'Automatic SDK generation from an OpenAPI definition.',
124
128
  extname: '.js',
129
+ installation: 'npx api install {packageName}',
125
130
  },
126
131
  convert: ({ cookiesObj, headersObj, postData, queryObj, url, ...source }, options) => {
127
132
  const opts = {
128
133
  ...options,
129
134
  } as APIOptions;
130
135
 
131
- if (!('apiDefinitionUri' in opts)) {
132
- throw new Error('This HTTP Snippet client must have an `apiDefinitionUri` option supplied to it.');
133
- } else if (!('apiDefinition' in opts)) {
134
- throw new Error('This HTTP Snippet client must have an `apiDefinition` option supplied to it.');
136
+ if (!opts?.api) {
137
+ throw new Error('This HTTPSnippet client must have an `api` config supplied to it.');
138
+ } else if (!opts?.api?.definition) {
139
+ throw new Error('This HTTPSnippet client must have an `api.definition` option supplied to it.');
140
+ } else if (!opts?.api?.registryURI) {
141
+ throw new Error('This HTTPSnippet client must have an `api.registryURI` option supplied to it.');
135
142
  }
136
143
 
137
144
  const method = source.method.toLowerCase() as HttpMethods;
138
- const oas = new Oas(opts.apiDefinition);
145
+ const oas = new Oas(opts.api.definition);
139
146
  const apiDefinition = oas.getDefinition();
140
147
  const foundOperation = oas.findOperation(url, method);
141
148
  if (!foundOperation) {
142
149
  throw new Error(
143
- `Unable to locate a matching operation in the supplied \`apiDefinition\` for: ${source.method} ${url}`,
150
+ `Unable to locate a matching operation in the supplied \`api.definition\` for: ${source.method} ${url}`,
144
151
  );
145
152
  }
146
153
 
147
154
  let sdkPackageName;
148
155
  let sdkVariable: string;
149
- if (opts.identifier) {
150
- sdkPackageName = opts.identifier;
156
+ if (opts.api.identifier) {
157
+ sdkPackageName = opts.api.identifier;
151
158
 
152
- sdkVariable = camelCase(opts.identifier);
159
+ sdkVariable = camelCase(opts.api.identifier);
153
160
  if (isReservedOrBuiltinsLC(sdkVariable)) {
154
161
  // If this identifier is a reserved JS word then we should prefix it with an underscore so
155
162
  // this snippet can be valid code.
156
163
  sdkVariable = `_${sdkVariable}`;
157
164
  }
158
165
  } else {
159
- sdkPackageName = getProjectPrefixFromRegistryUUID(opts.apiDefinitionUri);
166
+ sdkPackageName = getProjectPrefixFromRegistryUUID(opts.api.registryURI);
160
167
  sdkVariable = 'sdk';
161
168
  }
162
169
 
@@ -369,4 +376,9 @@ const client: Client<APIOptions> = {
369
376
  },
370
377
  };
371
378
 
372
- export default client;
379
+ const plugin: ClientPlugin<APIOptions> = {
380
+ target: 'node',
381
+ client,
382
+ };
383
+
384
+ export default plugin;
package/tsup.config.ts CHANGED
@@ -11,5 +11,15 @@ export default defineConfig((options: Options) => ({
11
11
  ...config,
12
12
 
13
13
  entry: ['src/index.ts'],
14
+
15
+ noExternal: [
16
+ // These dependencies are ESM-only but because we're building for ESM **and** CJS we can't
17
+ // treat them as external dependencies as CJS libraries can't load ESM code that uses `export`.
18
+ // `noExternal` will instead treeshake these dependencies down and include them in our compiled
19
+ // dists.
20
+ 'camelcase',
21
+ 'stringify-object',
22
+ ],
23
+
14
24
  silent: !options.watch,
15
25
  }));