Comparing version 0.18.1 to 0.19.0
@@ -6,4 +6,4 @@ import { BaseConfig } from './getConfig'; | ||
}; | ||
declare const _default: ({ input, baseURL, trailingSlash }: BaseConfig) => Template; | ||
declare const _default: ({ input, baseURL, trailingSlash, outputEachDir }: BaseConfig) => Template[]; | ||
export default _default; | ||
//# sourceMappingURL=buildTemplate.d.ts.map |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -8,12 +28,53 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var createTemplateValues_1 = __importDefault(require("./createTemplateValues")); | ||
exports.default = (function (_a) { | ||
var input = _a.input, baseURL = _a.baseURL, trailingSlash = _a.trailingSlash; | ||
var _b = createTemplateValues_1.default(input, trailingSlash), api = _b.api, imports = _b.imports; | ||
var text = ("/* eslint-disable */\nimport { AspidaClient" + (api.includes('BasicHeaders') ? ', BasicHeaders' : '') + " } from 'aspida'\n<% types %><% imports %>\n\nconst api = <T>(client: AspidaClient<T>) => {\n const prefix = (client.baseURL === undefined ? '<% baseURL %>' : client.baseURL).replace(/\\/$/, '')\n\n return <% api %>\n}\n\nexport type ApiInstance = ReturnType<typeof api>\nexport default api\n") | ||
.replace('<% types %>', api.includes(': ApiTypes.') ? "import * as ApiTypes from './@types'\n" : '') | ||
var getDirentTree_1 = require("./getDirentTree"); | ||
var listNotIndexFiles = function (tree) { | ||
return __spread(tree.children | ||
.filter(function (c) { return !c.name.startsWith('_') && !c.isDir && c.name !== 'index.ts'; }) | ||
.map(function (c) { | ||
return path_1.default.posix.join(tree.path, c.name) + " -> " + path_1.default.posix.join(tree.path, c.name.replace('.ts', ''), 'index.ts'); | ||
}), tree.children | ||
.map(function (c) { return (!c.name.startsWith('_') && c.isDir ? listNotIndexFiles(c.tree) : []); }) | ||
.reduce(function (p, c) { return __spread(p, c); }, [])); | ||
}; | ||
var createTemplate = function (tree, baseURL, trailingSlash, appendPrefix) { | ||
var _a = createTemplateValues_1.default(tree, trailingSlash), api = _a.api, imports = _a.imports, pathes = _a.pathes; | ||
var text = ("/* eslint-disable */\nimport { AspidaClient" + (api.includes('BasicHeaders') ? ', BasicHeaders' : '') + " } from 'aspida'\n<% types %><% imports %>\n" + ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS'] | ||
.filter(function (m) { return api.includes(", " + m + ", option"); }) | ||
.map(function (m) { return "\nconst " + m + " = '" + m + "'"; }) | ||
.join('') + pathes.map(function (p, i) { return "\nconst PATH" + i + " = " + p; }).join('') + "\nconst api = <T>({ baseURL, fetch }: AspidaClient<T>) => {\n const prefix = " + (appendPrefix ? '`${' : '') + "(baseURL === undefined ? '<% baseURL %>' : baseURL).replace(/\\/$/, '')" + (appendPrefix ? "}/" + appendPrefix + "`" : '') + "\n\n return <% api %>\n}\n\nexport type ApiInstance = ReturnType<typeof api>\nexport default api\n") | ||
.replace('<% types %>', api.includes(': ApiTypes.') | ||
? "import * as ApiTypes from '" + (appendPrefix | ||
? appendPrefix | ||
.split('/') | ||
.map(function () { return '../'; }) | ||
.join('') | ||
: './') + "@types'\n" | ||
: '') | ||
.replace('<% imports %>', imports.join('\n')) | ||
.replace('<% api %>', api) | ||
.replace('<% baseURL %>', baseURL); | ||
return { text: text, filePath: path_1.default.posix.join(input, '$api.ts') }; | ||
return { text: text, filePath: path_1.default.posix.join(tree.path, '$api.ts') }; | ||
}; | ||
exports.default = (function (_a) { | ||
var input = _a.input, baseURL = _a.baseURL, trailingSlash = _a.trailingSlash, outputEachDir = _a.outputEachDir; | ||
var direntTree = getDirentTree_1.getDirentTree(input); | ||
var templates = [createTemplate(direntTree, baseURL, trailingSlash)]; | ||
if (outputEachDir) { | ||
var notIndexFiles = listNotIndexFiles(direntTree); | ||
if (notIndexFiles.length) { | ||
console.error("Error on aspida: Since true is specified in outputEachDir at aspida.config.js, you need to rename the following files\n" + notIndexFiles.join('\n') + "\n"); | ||
return []; | ||
} | ||
var appendTemplate_1 = function (tree) { | ||
tree.children.forEach(function (c) { | ||
if (!c.isDir || c.name.startsWith('_')) | ||
return; | ||
templates.push(createTemplate(c.tree, baseURL, trailingSlash, c.tree.path.replace(input, '').replace(/^\//, ''))); | ||
appendTemplate_1(c.tree); | ||
}); | ||
}; | ||
appendTemplate_1(direntTree); | ||
} | ||
return templates; | ||
}); | ||
//# sourceMappingURL=buildTemplate.js.map |
@@ -35,3 +35,3 @@ "use strict"; | ||
Build.prototype.run = function (config, io) { | ||
io.write(buildTemplate_1.default(config)); | ||
buildTemplate_1.default(config).forEach(io.write); | ||
}; | ||
@@ -38,0 +38,0 @@ return Build; |
import { Method } from './parseInterface'; | ||
declare const _default: (methods: Method[], indent: string, importName: string, newUrl: string, trailingSlash: boolean) => string; | ||
declare const _default: (methods: Method[], indent: string, importName: string, newPrefix: string, path: string) => string; | ||
export default _default; | ||
//# sourceMappingURL=createMethodsString.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = (function (methods, indent, importName, newUrl, trailingSlash) { | ||
exports.default = (function (methods, indent, importName, newPrefix, path) { | ||
return methods | ||
@@ -55,8 +55,7 @@ .map(function (_a) { | ||
}; | ||
var quotation = newUrl.includes('${') ? '`' : "'"; | ||
var tmpChanks = [ | ||
"(" + option(name) + ") =>", | ||
"client.fetch<" + resBody(name) + resHeaders(name) + status(name) + ">(prefix, " + quotation + newUrl + (trailingSlash ? '/' : '') + quotation + ", '" + name.toUpperCase() + "'" + request() + ")." + resMethodName() + "()" | ||
"fetch<" + resBody(name) + resHeaders(name) + status(name) + ">(" + newPrefix + ", " + path + ", " + name.toUpperCase() + request() + ")." + resMethodName() + "()" | ||
]; | ||
return indent + " " + name + ": " + tmpChanks[0] + "\n" + indent + " " + tmpChanks[1] + ",\n" + indent + " $" + name + ": async " + tmpChanks[0] + "\n" + indent + " (await " + tmpChanks[1] + ").body"; | ||
return indent + " " + name + ": " + tmpChanks[0] + "\n" + indent + " " + tmpChanks[1] + ",\n" + indent + " $" + name + ": " + tmpChanks[0] + "\n" + indent + " " + tmpChanks[1] + ".then(r => r.body)"; | ||
}) | ||
@@ -63,0 +62,0 @@ .join(',\n'); |
@@ -1,6 +0,8 @@ | ||
declare const _default: (input: string, trailingSlash: boolean) => { | ||
import { DirentTree } from './getDirentTree'; | ||
declare const _default: (direntTree: DirentTree, trailingSlash: boolean) => { | ||
api: string; | ||
imports: string[]; | ||
pathes: string[]; | ||
}; | ||
export default _default; | ||
//# sourceMappingURL=createTemplateValues.d.ts.map |
@@ -22,59 +22,51 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fs_1 = __importDefault(require("fs")); | ||
var path_1 = __importDefault(require("path")); | ||
var createMethodsString_1 = __importDefault(require("./createMethodsString")); | ||
var parseInterface_1 = __importDefault(require("./parseInterface")); | ||
exports.default = (function (input, trailingSlash) { | ||
exports.default = (function (direntTree, trailingSlash) { | ||
var imports = []; | ||
var getMethodsString = function (file, target, indent, newUrl) { | ||
var methodsInterface = parseInterface_1.default(fs_1.default.readFileSync(target, 'utf8'), 'Methods'); | ||
if (!methodsInterface) | ||
return ''; | ||
var importName = ''; | ||
if (methodsInterface.some(function (_a) { | ||
var props = _a.props; | ||
return Object.keys(props).length; | ||
})) { | ||
importName = "Methods" + imports.length; | ||
imports.push("import { Methods as " + importName + " } from '" + file.replace(/'/g, "\\'") + "'"); | ||
var pathes = []; | ||
var getMethodsString = function (file, methods, indent, newPrefix, newUrl) { | ||
var importName = "Methods" + imports.length; | ||
imports.push("import { Methods as " + importName + " } from '" + file.replace(/'/g, "\\'") + "'"); | ||
var newPath = "'" + newUrl + (trailingSlash ? '/' : '') + "'"; | ||
if (newPath.length > 2) { | ||
if (!pathes.includes(newPath)) | ||
pathes.push(newPath); | ||
newPath = "PATH" + pathes.indexOf(newPath); | ||
} | ||
return createMethodsString_1.default(methodsInterface, indent, importName, newUrl, trailingSlash); | ||
return createMethodsString_1.default(methods, indent, importName, newPrefix, newPath); | ||
}; | ||
var valCount = 0; | ||
var createApiString = function (targetDir, importBasePath, indent, url, text, methodsOfIndexTsFile) { | ||
indent += ' '; | ||
var props = fs_1.default | ||
.readdirSync(targetDir) | ||
.sort() | ||
.map(function (file, _, dirList) { | ||
if (file.startsWith('$') || file.startsWith('@')) | ||
return; | ||
var createApiString = function (tree, importBasePath, indent, prefix, url, text, methodsOfIndexTsFile) { | ||
var props = tree.children | ||
.map(function (dirent) { | ||
var _a; | ||
var file = dirent.name; | ||
var basename = path_1.default.basename(file, '.ts'); | ||
var hasVal = file.startsWith('_'); | ||
var valFn = "" + indent + basename | ||
.replace(/[^a-zA-Z0-9$_]/g, '_') | ||
.replace(/^(\d)/, '$$$1') + ": {\n<% next %>\n" + indent + "}"; | ||
var newPrefix = prefix; | ||
var newUrl = url + "/" + basename; | ||
if (file.startsWith('_')) { | ||
var _a = __read(basename.split('@'), 2), valName_1 = _a[0], _b = _a[1], valType = _b === void 0 ? 'number | string' : _b; | ||
if (hasVal) { | ||
var _b = __read(basename.split('@'), 2), valName_1 = _b[0], _c = _b[1], valType = _c === void 0 ? 'number | string' : _c; | ||
if (/^[A-Z]/.test(valType)) { | ||
valType = "ApiTypes." + valType; | ||
} | ||
var duplicatedNames = dirList.filter(function (d) { return d.startsWith(valName_1); }); | ||
valFn = "" + indent + valName_1.replace(/\./g, '_') + (duplicatedNames.length > 1 ? "_" + duplicatedNames.indexOf(file) : '') + ": (val" + valCount + ": " + valType + ") => ({\n<% next %>\n" + indent + "})"; | ||
newUrl = url + "/${val" + valCount + "}" + valName_1.replace(/^[^.]+/, ''); | ||
var duplicatedNames = tree.children.filter(function (d) { return d.name.startsWith(valName_1); }); | ||
var prefixVal = "`${" + prefix + "}/${val" + valCount + "}" + valName_1.replace(/^[^.]+/, '') + "`"; | ||
newPrefix = "prefix" + valCount; | ||
newUrl = ''; | ||
valFn = "" + indent + valName_1.replace(/\./g, '_') + (duplicatedNames.length > 1 ? "_" + duplicatedNames.indexOf(dirent) : '') + ": (val" + valCount + ": " + valType + ") => {\n" + indent + " const " + newPrefix + " = " + prefixVal + "\n\n" + indent + " return {\n<% next %>\n" + indent + " }\n" + indent + "}"; | ||
valCount += 1; | ||
} | ||
var target = path_1.default.posix.join(targetDir, file); | ||
if (fs_1.default.statSync(target).isDirectory()) { | ||
var indexPath = path_1.default.posix.join(target, 'index.ts'); | ||
return createApiString(target, importBasePath + "/" + file, indent, newUrl, valFn.replace('<% next %>', '<% props %>'), dirList.includes(file + ".ts") | ||
? getMethodsString(importBasePath + "/" + file, target + ".ts", indent, newUrl) | ||
: fs_1.default.existsSync(indexPath) | ||
? getMethodsString(importBasePath + "/" + file + "/index", indexPath, indent, newUrl) | ||
: undefined); | ||
if (dirent.isDir) { | ||
var methodsOfIndexTsFile_1 = (_a = tree.children.find(function (c) { return c.name === file + ".ts"; })) !== null && _a !== void 0 ? _a : dirent.tree.children.find(function (c) { return c.name === 'index.ts'; }); | ||
return createApiString(dirent.tree, importBasePath + "/" + file, "" + indent + (hasVal ? ' ' : '') + " ", newPrefix, newUrl, valFn.replace('<% next %>', '<% props %>'), (methodsOfIndexTsFile_1 === null || methodsOfIndexTsFile_1 === void 0 ? void 0 : methodsOfIndexTsFile_1.isDir) === false | ||
? getMethodsString(importBasePath + "/" + file, methodsOfIndexTsFile_1.methods, "" + indent + (hasVal ? ' ' : ''), newPrefix, newUrl) | ||
: undefined); | ||
} | ||
else if (path_1.default.extname(file) === '.ts' && | ||
file !== 'index.ts' && | ||
!dirList.includes(basename)) { | ||
return valFn.replace('<% next %>', getMethodsString(importBasePath + "/" + basename, target, indent, newUrl)); | ||
else if (file !== 'index.ts' && tree.children.every(function (d) { return d.name !== basename; })) { | ||
return valFn.replace('<% next %>', getMethodsString(importBasePath + "/" + basename, dirent.methods, "" + indent + (hasVal ? ' ' : ''), newPrefix, newUrl)); | ||
} | ||
@@ -85,7 +77,7 @@ }) | ||
}; | ||
var rootIndexPath = path_1.default.posix.join(input, 'index.ts'); | ||
var rootIndent = ' '; | ||
var emptyMethodsRegExp = /.+{\n\n? +},?\n/; | ||
var api = createApiString(input, '.', rootIndent, '', "{\n<% props %>\n }", fs_1.default.existsSync(rootIndexPath) | ||
? getMethodsString('./index', rootIndexPath, rootIndent, '') | ||
var rootIndexData = direntTree.children.find(function (c) { return c.name === 'index.ts'; }); | ||
/* eslint-disable no-template-curly-in-string */ | ||
var api = createApiString(direntTree, '.', ' ', 'prefix', '', "{\n<% props %>\n }", rootIndexData && !rootIndexData.isDir | ||
? getMethodsString('./index', rootIndexData.methods, ' ', 'prefix', '') | ||
: undefined); | ||
@@ -95,4 +87,4 @@ while (emptyMethodsRegExp.test(api)) { | ||
} | ||
return { api: api, imports: imports }; | ||
return { api: api, imports: imports, pathes: pathes }; | ||
}); | ||
//# sourceMappingURL=createTemplateValues.js.map |
@@ -5,2 +5,3 @@ export declare type BaseConfig = { | ||
trailingSlash: boolean; | ||
outputEachDir: boolean; | ||
}; | ||
@@ -7,0 +8,0 @@ declare const _default: (configPath?: string) => BaseConfig[]; |
@@ -23,3 +23,4 @@ "use strict"; | ||
baseURL: '', | ||
trailingSlash: false | ||
trailingSlash: false, | ||
outputEachDir: false | ||
}; | ||
@@ -26,0 +27,0 @@ exports.default = (function (configPath) { |
{ | ||
"name": "aspida", | ||
"version": "0.18.1", | ||
"version": "0.19.0", | ||
"description": "TypeScript friendly HTTP client wrapper for the browser and node.js", | ||
@@ -21,6 +21,6 @@ "author": "Solufa <solufa2020@gmail.com>", | ||
"keywords": [ | ||
"typescript", | ||
"xhr", | ||
"http", | ||
"ajax", | ||
"promise" | ||
"ajax" | ||
], | ||
@@ -27,0 +27,0 @@ "dependencies": { |
@@ -265,2 +265,11 @@ | aspida | [aspida-mock] | [@aspida/axios] | [@aspida/ky] | [@aspida/fetch] | [@aspida/node-fetch] | | ||
## Options of aspida.config.js | ||
| Option | Type | Default | Description | | ||
| ------------- | ------- | --------------------------- | ----------------------------------------------------- | | ||
| input | string | "apis", "server/api", "api" | Specifies the endpoint type definition root directory | | ||
| baseURL | string | "" | Specify baseURL of the request | | ||
| trailingSlash | boolean | false | Append `/` to the request URL | | ||
| outputEachDir | boolean | false | Generate `$api.ts` in each endpoint directory | | ||
## Tips | ||
@@ -328,3 +337,3 @@ | ||
name: string | ||
icon: ArrayBuffer | ||
icon: Blob | ||
} | ||
@@ -351,3 +360,3 @@ | ||
name: "taro", | ||
icon: imageBuffer | ||
icon: imageBlob | ||
} | ||
@@ -448,6 +457,72 @@ }) | ||
### Define endpoints that contain special characters | ||
Special characters are encoded as percent-encoding in the file name | ||
Example `":"` -> `"%3A"` | ||
`apis/foo%3Abar.ts` | ||
```ts | ||
export type Methods = { | ||
get: { | ||
resBody: string | ||
} | ||
} | ||
``` | ||
With clients, `"%3A"` -> `"_3A"` | ||
`src/index.ts` | ||
```typescript | ||
import aspida from "@aspida/axios" | ||
import api from "../apis/$api" | ||
;(async () => { | ||
const client = api(aspida()) | ||
const message = await client.foo_3Abar.$get() | ||
console.log(message) | ||
// req -> GET: /foo%3Abar (= /foo:bar) | ||
})() | ||
``` | ||
### Import only some endpoints | ||
If you don't need to use all of `apis/$api.ts` , you can split them up and import only part of them | ||
`outputEachDir` option generates `$api.ts` in each endpoint directory | ||
`$api.ts` will not be generated under the directory containing the path variable | ||
`aspida.config.js` | ||
```js | ||
module.exports = { | ||
input: "apis", | ||
outputEachDir: true | ||
} | ||
``` | ||
Import only `$api.ts` of the endpoint you want to use and put it into Object | ||
`src/index.ts` | ||
```typescript | ||
import aspida from "@aspida/axios" | ||
import api0 from "../apis/v1/foo/$api" | ||
import api1 from "../apis/v2/bar/$api" | ||
;(async () => { | ||
const aspidaClient = aspida() | ||
const client = { | ||
foo: api0(aspidaClient), | ||
bar: api1(aspidaClient) | ||
} | ||
const message = await client.bar._id(1).$get() | ||
// req -> GET: /foo | ||
})() | ||
``` | ||
## Support | ||
<a href="https://twitter.com/solufa2020"> | ||
<img src="https://aspidajs.github.io/aspida/assets/images/twitter.svg" width="65" alt="Twitter" /> | ||
<img src="https://aspidajs.github.io/aspida/assets/images/twitter.svg" width="50" alt="Twitter" /> | ||
</a> | ||
@@ -454,0 +529,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83285
56
896
535