@pyrpc/types 0.3.3 → 0.6.1
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 +10 -17
- package/package.json +3 -5
- package/src/index.ts +2 -2
- package/postinstall.js +0 -154
package/README.md
CHANGED
|
@@ -1,34 +1,27 @@
|
|
|
1
1
|
# @pyrpc/types
|
|
2
2
|
|
|
3
|
-
TypeScript type definitions for [pyRPC](https://pyrpc.
|
|
3
|
+
TypeScript type definitions for [pyRPC](https://pyrpc.com). Generated by `pyrpc dev` or `pyrpc codegen` - reflects your actual Python backend procedures at compile time.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Distribution modes
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
When you `npm install @pyrpc/types`, the `postinstall` script prompts you to choose a distribution mode:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```
|
|
9
|
+
### Workspace mode
|
|
10
|
+
Types are written directly by the server-side `pyrpc dev` / `pyrpc codegen` commands into `node_modules/@pyrpc/types/src/index.ts`. The postinstall creates `pyrpc-client.json` with `distribution: "workspace"` and types are generated during development.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
### Server mode
|
|
13
|
+
Types are fetched from a running pyRPC server. The postinstall prompts for a `server_url`, fetches the schema from `{server_url}/rpc`, generates types immediately, and creates `pyrpc-client.json`.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
PYRPC_URL=https://api.example.com npm install @pyrpc/client
|
|
17
|
-
```
|
|
15
|
+
By default, types are written to `{client_root}/node_modules/@pyrpc/types/src/index.ts`, where `client_root` is configured in `pyrpc.json`.
|
|
18
16
|
|
|
19
|
-
Before codegen runs, `Types` resolves to
|
|
17
|
+
Before codegen runs, `Types` resolves to an empty interface. After codegen, it resolves to your actual procedure signatures - full autocompletion, no boilerplate.
|
|
20
18
|
|
|
21
19
|
## Manual generation
|
|
22
20
|
|
|
23
|
-
If the postinstall prompt is skipped:
|
|
24
|
-
|
|
25
21
|
```bash
|
|
26
|
-
|
|
27
|
-
pyrpc codegen https://your-server.com
|
|
22
|
+
pyrpc codegen http://localhost:8000
|
|
28
23
|
```
|
|
29
24
|
|
|
30
|
-
By default, types are written to `node_modules/@pyrpc/types/src/index.ts`. Use `--output` to override.
|
|
31
|
-
|
|
32
25
|
## License
|
|
33
26
|
|
|
34
27
|
MIT
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyrpc/types",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "pyRPC TypeScript type definitions
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "pyRPC TypeScript type definitions - generated by pyrpc codegen",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./src/index.ts",
|
|
@@ -9,11 +9,9 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
|
-
"src"
|
|
13
|
-
"postinstall.js"
|
|
12
|
+
"src"
|
|
14
13
|
],
|
|
15
14
|
"scripts": {
|
|
16
|
-
"postinstall": "node postinstall.js",
|
|
17
15
|
"lint": "echo 'no lint'",
|
|
18
16
|
"test": "echo 'no test'"
|
|
19
17
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @pyrpc/types - types not generated yet.
|
|
2
2
|
// Install @pyrpc/client and the postinstall script will prompt for setup:
|
|
3
3
|
// npm install @pyrpc/client
|
|
4
|
-
// Or
|
|
5
|
-
// pyrpc
|
|
4
|
+
// Or sync manually from a running server:
|
|
5
|
+
// npx pyrpc sync
|
|
6
6
|
//
|
|
7
7
|
// This file is replaced when codegen runs.
|
|
8
8
|
|
package/postinstall.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
var fs = require('fs');
|
|
2
|
-
var path = require('path');
|
|
3
|
-
var readline = require('readline');
|
|
4
|
-
|
|
5
|
-
var TYPES_FILE = path.join(__dirname, 'src', 'index.ts');
|
|
6
|
-
var PLACEHOLDER_MARKER = 'types not generated yet';
|
|
7
|
-
|
|
8
|
-
// Skip if real types already exist
|
|
9
|
-
if (fs.existsSync(TYPES_FILE)) {
|
|
10
|
-
var content = fs.readFileSync(TYPES_FILE, 'utf-8');
|
|
11
|
-
if (!content.includes(PLACEHOLDER_MARKER)) {
|
|
12
|
-
process.exit(0);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
var TYPE_MAP = {
|
|
17
|
-
int: 'number',
|
|
18
|
-
float: 'number',
|
|
19
|
-
str: 'string',
|
|
20
|
-
bool: 'boolean',
|
|
21
|
-
None: 'null',
|
|
22
|
-
NoneType: 'null',
|
|
23
|
-
Any: 'any',
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
function toTs(t) {
|
|
27
|
-
if (!t || t === 'None') return 'void';
|
|
28
|
-
var m = t.match(/^<class\s+'([^'>]+)'>$/);
|
|
29
|
-
if (m) {
|
|
30
|
-
var n = m[1];
|
|
31
|
-
if (TYPE_MAP[n]) return TYPE_MAP[n];
|
|
32
|
-
if (n[0] >= 'A' && n[0] <= 'Z') return n;
|
|
33
|
-
return 'any';
|
|
34
|
-
}
|
|
35
|
-
var s = t.replace(/^typing\./, '');
|
|
36
|
-
var o = s.match(/^Optional\[(.+)\]$/);
|
|
37
|
-
if (o) return toTs(o[1]) + ' | null';
|
|
38
|
-
var l = s.match(/^(?:List|list)\[(.+)\]$/);
|
|
39
|
-
if (l) return toTs(l[1]) + '[]';
|
|
40
|
-
var d = s.match(/^(?:Dict|dict)\[([^,]+),\s*(.+)\]$/);
|
|
41
|
-
if (d) return 'Record<' + toTs(d[1]) + ', ' + toTs(d[2]) + '>';
|
|
42
|
-
var u = s.match(/^Union\[(.+)\]$/);
|
|
43
|
-
if (u) return u[1].split(',').map(function(p) { return toTs(p.trim()); }).join(' | ');
|
|
44
|
-
var tup = s.match(/^(?:Tuple|tuple)\[([^\]]+)\]$/);
|
|
45
|
-
if (tup) return '[' + tup[1].split(',').map(function(p) { return toTs(p.trim()); }).join(', ') + ']';
|
|
46
|
-
return 'any';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function generate(schemas) {
|
|
50
|
-
var lines = [];
|
|
51
|
-
lines.push('// Auto-generated by @pyrpc/types');
|
|
52
|
-
lines.push('// Schema fetched from: ' + (process.env.PYRPC_URL || 'http://localhost:8000'));
|
|
53
|
-
lines.push('');
|
|
54
|
-
var names = Object.keys(schemas);
|
|
55
|
-
for (var i = 0; i < names.length; i++) {
|
|
56
|
-
var name = names[i];
|
|
57
|
-
var schema = schemas[name];
|
|
58
|
-
lines.push('export interface ' + name + 'Params {');
|
|
59
|
-
var params = schema.parameters || [];
|
|
60
|
-
for (var j = 0; j < params.length; j++) {
|
|
61
|
-
var p = params[j];
|
|
62
|
-
lines.push(' ' + p.name + ': ' + toTs(p.type) + ';');
|
|
63
|
-
}
|
|
64
|
-
lines.push('}');
|
|
65
|
-
lines.push('');
|
|
66
|
-
lines.push('export interface ' + name + 'Result {');
|
|
67
|
-
lines.push(' data: ' + toTs(schema.return_type) + ';');
|
|
68
|
-
lines.push('}');
|
|
69
|
-
lines.push('');
|
|
70
|
-
}
|
|
71
|
-
lines.push('export interface Types {');
|
|
72
|
-
for (var k = 0; k < names.length; k++) {
|
|
73
|
-
lines.push(' ' + names[k] + ': { params: ' + names[k] + 'Params; result: ' + names[k] + 'Result };');
|
|
74
|
-
}
|
|
75
|
-
lines.push('}');
|
|
76
|
-
lines.push('');
|
|
77
|
-
return lines.join('\n');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function fetchSchema(url) {
|
|
81
|
-
var endpoint = url.replace(/\/+$/, '');
|
|
82
|
-
if (endpoint.indexOf('/rpc') !== endpoint.length - 4) {
|
|
83
|
-
endpoint += '/rpc';
|
|
84
|
-
}
|
|
85
|
-
if (typeof fetch !== 'undefined') {
|
|
86
|
-
return fetch(endpoint).then(function(res) {
|
|
87
|
-
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
88
|
-
return res.json();
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
var mod = url.indexOf('https') === 0 ? require('https') : require('http');
|
|
92
|
-
return new Promise(function(resolve, reject) {
|
|
93
|
-
mod.get(endpoint, function(res) {
|
|
94
|
-
var data = '';
|
|
95
|
-
res.on('data', function(c) { data += c; });
|
|
96
|
-
res.on('end', function() {
|
|
97
|
-
if (res.statusCode !== 200) return reject(new Error('HTTP ' + res.statusCode));
|
|
98
|
-
try { resolve(JSON.parse(data)); }
|
|
99
|
-
catch (e) { reject(e); }
|
|
100
|
-
});
|
|
101
|
-
}).on('error', reject);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function main() {
|
|
106
|
-
var isInteractive = process.stdin.isTTY;
|
|
107
|
-
var envUrl = process.env.PYRPC_URL;
|
|
108
|
-
var url = null;
|
|
109
|
-
|
|
110
|
-
if (isInteractive) {
|
|
111
|
-
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
112
|
-
return new Promise(function(resolve) {
|
|
113
|
-
rl.question(' pyRPC backend URL (default: http://localhost:8000): ', function(answer) {
|
|
114
|
-
rl.close();
|
|
115
|
-
url = answer.trim() || 'http://localhost:8000';
|
|
116
|
-
resolve(url);
|
|
117
|
-
});
|
|
118
|
-
}).then(function(url) {
|
|
119
|
-
return fetchSchema(url).then(function(schemas) {
|
|
120
|
-
var code = generate(schemas);
|
|
121
|
-
fs.mkdirSync(path.dirname(TYPES_FILE), { recursive: true });
|
|
122
|
-
fs.writeFileSync(TYPES_FILE, code, 'utf-8');
|
|
123
|
-
console.log(' \u2713 @pyrpc/types: generated for ' + Object.keys(schemas).length + ' procedures');
|
|
124
|
-
console.log(' Import: import type { Types } from "@pyrpc/types"');
|
|
125
|
-
}).catch(function(err) {
|
|
126
|
-
console.log(' \u2717 @pyrpc/types: could not connect (' + err.message + ')');
|
|
127
|
-
console.log(' Run manually: pyrpc codegen ' + url);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (envUrl) {
|
|
133
|
-
return fetchSchema(envUrl).then(function(schemas) {
|
|
134
|
-
var code = generate(schemas);
|
|
135
|
-
fs.mkdirSync(path.dirname(TYPES_FILE), { recursive: true });
|
|
136
|
-
fs.writeFileSync(TYPES_FILE, code, 'utf-8');
|
|
137
|
-
console.log(' \u2713 @pyrpc/types: generated for ' + Object.keys(schemas).length + ' procedures');
|
|
138
|
-
}).catch(function(err) {
|
|
139
|
-
console.log(' \u2717 @pyrpc/types: could not connect (' + err.message + ')');
|
|
140
|
-
console.log(' Run manually: pyrpc codegen ' + envUrl);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log('');
|
|
145
|
-
console.log(' \u26A1 @pyrpc/types: no types generated yet.');
|
|
146
|
-
console.log(' To connect to your pyRPC backend:');
|
|
147
|
-
console.log(' pyrpc codegen http://localhost:8000');
|
|
148
|
-
console.log(' Or install interactively in a terminal:');
|
|
149
|
-
console.log(' npm install @pyrpc/client');
|
|
150
|
-
console.log('');
|
|
151
|
-
return Promise.resolve();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
main().catch(function(e) {});
|