@contractkit/plugin-python 0.9.4 → 0.10.0
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/.turbo/turbo-build$colon$ci.log +7 -7
- package/.turbo/turbo-test$colon$ci.log +5 -5
- package/CHANGELOG.md +11 -0
- package/coverage/clover.xml +2 -2
- package/coverage/index.html +1 -1
- package/coverage/src/codegen-client.ts.html +1 -1
- package/coverage/src/codegen-models.ts.html +1 -1
- package/coverage/src/index.html +1 -1
- package/coverage/tests/helpers.ts.html +1 -1
- package/coverage/tests/index.html +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +265 -80
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +300 -92
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @contractkit/plugin-python@0.
|
|
2
|
+
> @contractkit/plugin-python@0.10.0 build:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-python
|
|
3
3
|
> eslint --max-warnings=0 && pnpm run build
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @contractkit/plugin-python@0.
|
|
6
|
+
> @contractkit/plugin-python@0.10.0 build /home/runner/work/ContractKit/ContractKit/packages/plugin-python
|
|
7
7
|
> tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration
|
|
8
8
|
|
|
9
9
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
[34mCLI[39m tsup v8.5.1
|
|
12
12
|
[34mCLI[39m Target: esnext
|
|
13
13
|
[34mESM[39m Build start
|
|
14
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
15
|
-
[32mESM[39m [1mdist/index.js.map [22m[
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
14
|
+
[32mESM[39m [1mdist/index.js [22m[32m42.33 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m89.19 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 231ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 4449ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.10 KB[39m
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
> @contractkit/plugin-python@0.
|
|
2
|
+
> @contractkit/plugin-python@0.10.0 test:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-python
|
|
3
3
|
> vitest run --coverage
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/ContractKit/ContractKit/packages/plugin-python[39m
|
|
7
7
|
[2mCoverage enabled with [22m[33mv8[39m
|
|
8
8
|
|
|
9
|
-
[32m✓[39m tests/codegen-models.test.ts [2m([22m[2m32 tests[22m[2m)[22m[32m
|
|
10
|
-
[32m✓[39m tests/codegen-client.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m
|
|
9
|
+
[32m✓[39m tests/codegen-models.test.ts [2m([22m[2m32 tests[22m[2m)[22m[32m 126[2mms[22m[39m
|
|
10
|
+
[32m✓[39m tests/codegen-client.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m 98[2mms[22m[39m
|
|
11
11
|
|
|
12
12
|
[2m Test Files [22m [1m[32m2 passed[39m[22m[90m (2)[39m
|
|
13
13
|
[2m Tests [22m [1m[32m59 passed[39m[22m[90m (59)[39m
|
|
14
|
-
[2m Start at [22m
|
|
15
|
-
[2m Duration [22m
|
|
14
|
+
[2m Start at [22m 11:09:08
|
|
15
|
+
[2m Duration [22m 5.60s[2m (transform 1.93s, setup 0ms, import 7.42s, tests 224ms, environment 0ms)[22m
|
|
16
16
|
|
|
17
17
|
[34m % [39m[2mCoverage report from [22m[33mv8[39m
|
|
18
18
|
-------------------|---------|----------|---------|---------|-------------------
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @contractkit/contractkit-plugin-python
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 10ca07b: Add per-output incremental caching to the Bruno, Python, and TypeScript plugins. Editing a single contract or operation no longer regenerates every output file — only the units whose transitive inputs actually changed are re-rendered, with the rest reused from a per-plugin manifest. `@contractkit/core` exposes the shared utility (`runIncrementalCodegen`, `parseIncrementalManifest`, `hashFingerprint`, `collectTransitiveModelRefs`, manifest types) for plugin authors. `PluginContext` gains a `cacheEnabled` flag so plugins can honor `--force` / `cache: false`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [10ca07b]
|
|
12
|
+
- @contractkit/core@0.15.0
|
|
13
|
+
|
|
3
14
|
## 0.9.4
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/coverage/clover.xml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<coverage generated="
|
|
3
|
-
<project timestamp="
|
|
2
|
+
<coverage generated="1778152153915" clover="3.2.0">
|
|
3
|
+
<project timestamp="1778152153915" name="All files">
|
|
4
4
|
<metrics statements="538" coveredstatements="456" conditionals="416" coveredconditionals="320" methods="91" coveredmethods="78" elements="1045" coveredelements="854" complexity="0" loc="538" ncloc="538" packages="2" files="3" classes="3"/>
|
|
5
5
|
<package name="src">
|
|
6
6
|
<metrics statements="500" coveredstatements="421" conditionals="385" coveredconditionals="297" methods="66" coveredmethods="55"/>
|
package/coverage/index.html
CHANGED
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
117
117
|
Code coverage generated by
|
|
118
118
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
119
|
-
at 2026-05-
|
|
119
|
+
at 2026-05-07T11:09:13.871Z
|
|
120
120
|
</div>
|
|
121
121
|
<script src="prettify.js"></script>
|
|
122
122
|
<script>
|
|
@@ -2056,7 +2056,7 @@ class BaseClient:
|
|
|
2056
2056
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
2057
2057
|
Code coverage generated by
|
|
2058
2058
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2059
|
-
at 2026-05-
|
|
2059
|
+
at 2026-05-07T11:09:13.871Z
|
|
2060
2060
|
</div>
|
|
2061
2061
|
<script src="../prettify.js"></script>
|
|
2062
2062
|
<script>
|
|
@@ -1345,7 +1345,7 @@ export function deriveModelsModuleName(file: string): string {
|
|
|
1345
1345
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1346
1346
|
Code coverage generated by
|
|
1347
1347
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1348
|
-
at 2026-05-
|
|
1348
|
+
at 2026-05-07T11:09:13.871Z
|
|
1349
1349
|
</div>
|
|
1350
1350
|
<script src="../prettify.js"></script>
|
|
1351
1351
|
<script>
|
package/coverage/src/index.html
CHANGED
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
117
117
|
Code coverage generated by
|
|
118
118
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
119
|
-
at 2026-05-
|
|
119
|
+
at 2026-05-07T11:09:13.871Z
|
|
120
120
|
</div>
|
|
121
121
|
<script src="../prettify.js"></script>
|
|
122
122
|
<script>
|
|
@@ -652,7 +652,7 @@ export function opRoot(routes: OpRouteNode[], file = 'payments.op.ck', meta: Rec
|
|
|
652
652
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
653
653
|
Code coverage generated by
|
|
654
654
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
655
|
-
at 2026-05-
|
|
655
|
+
at 2026-05-07T11:09:13.871Z
|
|
656
656
|
</div>
|
|
657
657
|
<script src="../prettify.js"></script>
|
|
658
658
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-05-
|
|
104
|
+
at 2026-05-07T11:09:13.871Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../prettify.js"></script>
|
|
107
107
|
<script>
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export interface PythonSdkPluginConfig {
|
|
|
11
11
|
*/
|
|
12
12
|
includeInternal?: boolean;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Bumped when the Python codegen output shape changes in a way that should
|
|
16
|
+
* invalidate every per-file fingerprint. Mixed into the manifest's
|
|
17
|
+
* `codegenVersion`, so a plugin upgrade forces full regeneration even when no
|
|
18
|
+
* `.ck` files have changed.
|
|
19
|
+
*/
|
|
20
|
+
export declare const PYTHON_CODEGEN_VERSION = "1";
|
|
14
21
|
declare const plugin: ContractKitPlugin;
|
|
15
22
|
export default plugin;
|
|
16
23
|
export declare function createPythonSdkPlugin(config: PythonSdkPluginConfig, rootDir: string): ContractKitPlugin;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,iBAAiB,EAOpB,MAAM,mBAAmB,CAAC;AAmB3B,MAAM,WAAW,qBAAqB;IAClC,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAI1C,QAAA,MAAM,MAAM,EAAE,iBAMb,CAAC;AAEF,eAAe,MAAM,CAAC;AAEtB,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAOvG"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,9 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
5
|
-
import { resolve, join } from "path";
|
|
5
|
+
import { resolve, join, relative } from "path";
|
|
6
|
+
import { existsSync, readFileSync, rmSync, readdirSync, rmdirSync } from "fs";
|
|
7
|
+
import { runIncrementalCodegen, parseIncrementalManifest, emptyIncrementalManifest, hashFingerprint, collectTransitiveModelRefs, collectTypeRefs as collectTypeRefs2 } from "@contractkit/core";
|
|
6
8
|
|
|
7
9
|
// src/codegen-models.ts
|
|
8
10
|
import { computeModelsWithInput, topoSortModels, collectExternalRefs, collectExternalInputRefs } from "@contractkit/core";
|
|
@@ -943,103 +945,286 @@ class BaseClient:
|
|
|
943
945
|
`;
|
|
944
946
|
|
|
945
947
|
// src/index.ts
|
|
948
|
+
var PYTHON_CODEGEN_VERSION = "1";
|
|
949
|
+
var MANIFEST_FILENAME = ".contractkit-python-manifest.json";
|
|
946
950
|
var plugin = {
|
|
947
951
|
name: "python-sdk",
|
|
948
|
-
cacheKey: "python-sdk",
|
|
949
952
|
async generateTargets(inputs, ctx) {
|
|
950
953
|
const config = ctx.options;
|
|
951
|
-
|
|
954
|
+
await runPythonCodegen(inputs, ctx, config, ctx.rootDir);
|
|
952
955
|
}
|
|
953
956
|
};
|
|
954
957
|
var index_default = plugin;
|
|
955
958
|
function createPythonSdkPlugin(config, rootDir) {
|
|
956
959
|
return {
|
|
957
960
|
name: "python-sdk",
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
modelsWithInput
|
|
984
|
-
});
|
|
985
|
-
ctx.emitFile(outPath, content);
|
|
961
|
+
async generateTargets(inputs, ctx) {
|
|
962
|
+
await runPythonCodegen(inputs, ctx, config, rootDir);
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
__name(createPythonSdkPlugin, "createPythonSdkPlugin");
|
|
967
|
+
async function runPythonCodegen(inputs, ctx, config, rootDir) {
|
|
968
|
+
const { contractRoots, opRoots } = inputs;
|
|
969
|
+
const modelsWithInput = inputs.modelsWithInput;
|
|
970
|
+
const outDir = resolve(rootDir, config.baseDir ?? "python-sdk");
|
|
971
|
+
const modelModulePaths = /* @__PURE__ */ new Map();
|
|
972
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
973
|
+
const contractEntries = [];
|
|
974
|
+
for (const root of contractRoots) {
|
|
975
|
+
const moduleName = deriveModelsModuleName(root.file);
|
|
976
|
+
contractEntries.push({
|
|
977
|
+
moduleName,
|
|
978
|
+
relPath: `${moduleName}.py`,
|
|
979
|
+
root
|
|
980
|
+
});
|
|
981
|
+
for (const model of root.models) {
|
|
982
|
+
modelMap.set(model.name, model);
|
|
983
|
+
modelModulePaths.set(model.name, `.${moduleName}`);
|
|
984
|
+
if (modelsWithInput.has(model.name)) {
|
|
985
|
+
modelModulePaths.set(`${model.name}Input`, `.${moduleName}`);
|
|
986
986
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
const modelsWithInputArray = [
|
|
990
|
+
...modelsWithInput
|
|
991
|
+
].sort();
|
|
992
|
+
const prevManifest = ctx.cacheEnabled ? readManifest(outDir) : emptyIncrementalManifest(PYTHON_CODEGEN_VERSION);
|
|
993
|
+
const units = [];
|
|
994
|
+
for (const { moduleName, relPath, root } of contractEntries) {
|
|
995
|
+
const ownNames = new Set(root.models.map((m) => m.name));
|
|
996
|
+
const externalRefs = collectExternalRefsFromContract(root, ownNames);
|
|
997
|
+
const referencedModulePaths = {};
|
|
998
|
+
for (const ref of [
|
|
999
|
+
...externalRefs
|
|
1000
|
+
].sort()) {
|
|
1001
|
+
const path = modelModulePaths.get(ref);
|
|
1002
|
+
if (path) referencedModulePaths[ref] = path;
|
|
1003
|
+
const inputPath = modelModulePaths.get(`${ref}Input`);
|
|
1004
|
+
if (inputPath) referencedModulePaths[`${ref}Input`] = inputPath;
|
|
1005
|
+
}
|
|
1006
|
+
const relevantInputModels = modelsWithInputArray.filter((name) => ownNames.has(name) || externalRefs.has(name));
|
|
1007
|
+
const fingerprint = hashFingerprint({
|
|
1008
|
+
kind: "models",
|
|
1009
|
+
v: PYTHON_CODEGEN_VERSION,
|
|
1010
|
+
relPath,
|
|
1011
|
+
currentModule: `.${moduleName}`,
|
|
1012
|
+
root,
|
|
1013
|
+
referencedModulePaths,
|
|
1014
|
+
modelsWithInput: relevantInputModels
|
|
1015
|
+
});
|
|
1016
|
+
units.push({
|
|
1017
|
+
key: `models::${relPath}`,
|
|
1018
|
+
fingerprint,
|
|
1019
|
+
render: /* @__PURE__ */ __name(() => [
|
|
1020
|
+
{
|
|
1021
|
+
relativePath: relPath,
|
|
1022
|
+
content: generatePydanticModels(root, {
|
|
1023
|
+
modelModulePaths,
|
|
1024
|
+
currentModule: `.${moduleName}`,
|
|
1025
|
+
modelsWithInput
|
|
1026
|
+
})
|
|
1027
|
+
}
|
|
1028
|
+
], "render")
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
const clientInfos = [];
|
|
1032
|
+
for (const root of opRoots) {
|
|
1033
|
+
if (!hasPublicOperations(root, config.includeInternal)) continue;
|
|
1034
|
+
const moduleName = deriveClientModuleName(root.file);
|
|
1035
|
+
const relPath = `${moduleName}.py`;
|
|
1036
|
+
clientInfos.push({
|
|
1037
|
+
moduleName,
|
|
1038
|
+
className: deriveClientClassName(root.file),
|
|
1039
|
+
propertyName: deriveClientPropertyName(root.file)
|
|
1040
|
+
});
|
|
1041
|
+
const referencedModels = collectOpRootModelRefs(root, modelMap);
|
|
1042
|
+
const referencedModulePaths = {};
|
|
1043
|
+
for (const ref of [
|
|
1044
|
+
...referencedModels
|
|
1045
|
+
].sort()) {
|
|
1046
|
+
const path = modelModulePaths.get(ref);
|
|
1047
|
+
if (path) referencedModulePaths[ref] = path;
|
|
1048
|
+
const inputPath = modelModulePaths.get(`${ref}Input`);
|
|
1049
|
+
if (inputPath) referencedModulePaths[`${ref}Input`] = inputPath;
|
|
1050
|
+
}
|
|
1051
|
+
const relevantInputModels = modelsWithInputArray.filter((name) => referencedModels.has(name));
|
|
1052
|
+
const fingerprint = hashFingerprint({
|
|
1053
|
+
kind: "client",
|
|
1054
|
+
v: PYTHON_CODEGEN_VERSION,
|
|
1055
|
+
relPath,
|
|
1056
|
+
currentModule: `.${moduleName}`,
|
|
1057
|
+
root,
|
|
1058
|
+
referencedModulePaths,
|
|
1059
|
+
modelsWithInput: relevantInputModels,
|
|
1060
|
+
includeInternal: config.includeInternal ?? false
|
|
1061
|
+
});
|
|
1062
|
+
units.push({
|
|
1063
|
+
key: `client::${relPath}`,
|
|
1064
|
+
fingerprint,
|
|
1065
|
+
render: /* @__PURE__ */ __name(() => [
|
|
1066
|
+
{
|
|
1067
|
+
relativePath: relPath,
|
|
1068
|
+
content: generatePythonClient(root, {
|
|
1069
|
+
modelModulePaths,
|
|
1070
|
+
currentModule: `.${moduleName}`,
|
|
1071
|
+
modelsWithInput,
|
|
1072
|
+
includeInternal: config.includeInternal
|
|
1073
|
+
})
|
|
1074
|
+
}
|
|
1075
|
+
], "render")
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
const sdkClassName = config.packageName ? config.packageName.split(/[-._\s]+/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Sdk" : "Sdk";
|
|
1079
|
+
const initLines = [
|
|
1080
|
+
"# Auto-generated by contractkit-plugin-python-sdk. Do not edit manually.",
|
|
1081
|
+
"from ._base_client import BaseClient, SdkError"
|
|
1082
|
+
];
|
|
1083
|
+
for (const c of clientInfos) {
|
|
1084
|
+
initLines.push(`from .${c.moduleName} import ${c.className}`);
|
|
1085
|
+
}
|
|
1086
|
+
initLines.push("");
|
|
1087
|
+
initLines.push("");
|
|
1088
|
+
if (clientInfos.length > 0) {
|
|
1089
|
+
initLines.push(`class ${sdkClassName}(BaseClient):`);
|
|
1090
|
+
initLines.push(` def __init__(self, base_url: str, headers: dict[str, str] | None = None):`);
|
|
1091
|
+
initLines.push(` super().__init__(base_url, headers)`);
|
|
1092
|
+
for (const c of clientInfos) {
|
|
1093
|
+
initLines.push(` self.${c.propertyName} = ${c.className}(base_url, headers)`);
|
|
1094
|
+
}
|
|
1095
|
+
initLines.push("");
|
|
1096
|
+
} else {
|
|
1097
|
+
initLines.push(`class ${sdkClassName}(BaseClient):`);
|
|
1098
|
+
initLines.push(` pass`);
|
|
1099
|
+
initLines.push("");
|
|
1100
|
+
}
|
|
1101
|
+
const allNames = [
|
|
1102
|
+
"BaseClient",
|
|
1103
|
+
"SdkError",
|
|
1104
|
+
sdkClassName,
|
|
1105
|
+
...clientInfos.map((c) => c.className)
|
|
1106
|
+
];
|
|
1107
|
+
initLines.push(`__all__ = [${allNames.map((n) => JSON.stringify(n)).join(", ")}]`);
|
|
1108
|
+
initLines.push("");
|
|
1109
|
+
const globalFiles = [
|
|
1110
|
+
{
|
|
1111
|
+
relativePath: "_base_client.py",
|
|
1112
|
+
content: BASE_CLIENT_PY
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
relativePath: "requirements.txt",
|
|
1116
|
+
content: "httpx\npydantic>=2.0\n"
|
|
1117
|
+
},
|
|
1118
|
+
{
|
|
1119
|
+
relativePath: "__init__.py",
|
|
1120
|
+
content: initLines.join("\n")
|
|
1121
|
+
}
|
|
1122
|
+
];
|
|
1123
|
+
const result = runIncrementalCodegen({
|
|
1124
|
+
codegenVersion: PYTHON_CODEGEN_VERSION,
|
|
1125
|
+
manifestFilename: MANIFEST_FILENAME,
|
|
1126
|
+
prevManifest,
|
|
1127
|
+
globalFiles,
|
|
1128
|
+
units,
|
|
1129
|
+
fileExists: /* @__PURE__ */ __name((relPath) => existsSync(resolve(outDir, relPath)), "fileExists")
|
|
1130
|
+
});
|
|
1131
|
+
deleteStalePaths(outDir, result.deletedPaths);
|
|
1132
|
+
for (const { relativePath, content } of result.filesToWrite) {
|
|
1133
|
+
ctx.emitFile(resolve(outDir, relativePath), content);
|
|
1134
|
+
}
|
|
1135
|
+
void relative;
|
|
1136
|
+
}
|
|
1137
|
+
__name(runPythonCodegen, "runPythonCodegen");
|
|
1138
|
+
function collectExternalRefsFromContract(root, ownNames) {
|
|
1139
|
+
const refs = /* @__PURE__ */ new Set();
|
|
1140
|
+
for (const m of root.models) {
|
|
1141
|
+
if (m.type) collectTypeRefs2(m.type, refs);
|
|
1142
|
+
for (const f of m.fields) collectTypeRefs2(f.type, refs);
|
|
1143
|
+
if (m.bases) {
|
|
1144
|
+
for (const b of m.bases) refs.add(b);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
for (const own of ownNames) refs.delete(own);
|
|
1148
|
+
return refs;
|
|
1149
|
+
}
|
|
1150
|
+
__name(collectExternalRefsFromContract, "collectExternalRefsFromContract");
|
|
1151
|
+
function collectOpRootModelRefs(root, modelMap) {
|
|
1152
|
+
const seeds = [];
|
|
1153
|
+
for (const route of root.routes) {
|
|
1154
|
+
if (route.params) seeds.push(...paramSourceTypes(route.params));
|
|
1155
|
+
for (const op of route.operations) {
|
|
1156
|
+
if (op.query) seeds.push(...paramSourceTypes(op.query));
|
|
1157
|
+
if (op.headers) seeds.push(...paramSourceTypes(op.headers));
|
|
1158
|
+
if (op.request) {
|
|
1159
|
+
for (const body of op.request.bodies) seeds.push(body.bodyType);
|
|
1003
1160
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
"from ._base_client import BaseClient, SdkError"
|
|
1010
|
-
];
|
|
1011
|
-
for (const c of clientInfos) {
|
|
1012
|
-
initLines.push(`from .${c.moduleName} import ${c.className}`);
|
|
1161
|
+
for (const resp of op.responses) {
|
|
1162
|
+
if (resp.bodyType) seeds.push(resp.bodyType);
|
|
1163
|
+
if (resp.headers) {
|
|
1164
|
+
for (const h of resp.headers) seeds.push(h.type);
|
|
1165
|
+
}
|
|
1013
1166
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
return collectTransitiveModelRefs(seeds, modelMap);
|
|
1170
|
+
}
|
|
1171
|
+
__name(collectOpRootModelRefs, "collectOpRootModelRefs");
|
|
1172
|
+
function paramSourceTypes(src) {
|
|
1173
|
+
const out = [];
|
|
1174
|
+
if (src.kind === "params") {
|
|
1175
|
+
for (const n of src.nodes) out.push(n.type);
|
|
1176
|
+
} else if (src.kind === "ref") {
|
|
1177
|
+
out.push({
|
|
1178
|
+
kind: "ref",
|
|
1179
|
+
name: src.name
|
|
1180
|
+
});
|
|
1181
|
+
} else if (src.kind === "type") {
|
|
1182
|
+
out.push(src.node);
|
|
1183
|
+
}
|
|
1184
|
+
return out;
|
|
1185
|
+
}
|
|
1186
|
+
__name(paramSourceTypes, "paramSourceTypes");
|
|
1187
|
+
function readManifest(outDir) {
|
|
1188
|
+
const manifestPath = resolve(outDir, MANIFEST_FILENAME);
|
|
1189
|
+
if (!existsSync(manifestPath)) return emptyIncrementalManifest(PYTHON_CODEGEN_VERSION);
|
|
1190
|
+
try {
|
|
1191
|
+
return parseIncrementalManifest(readFileSync(manifestPath, "utf-8"));
|
|
1192
|
+
} catch {
|
|
1193
|
+
return emptyIncrementalManifest(PYTHON_CODEGEN_VERSION);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
__name(readManifest, "readManifest");
|
|
1197
|
+
function deleteStalePaths(outDir, relPaths) {
|
|
1198
|
+
if (relPaths.length === 0) return;
|
|
1199
|
+
const removedDirs = /* @__PURE__ */ new Set();
|
|
1200
|
+
for (const rel of relPaths) {
|
|
1201
|
+
const abs = resolve(outDir, rel);
|
|
1202
|
+
if (existsSync(abs)) {
|
|
1203
|
+
rmSync(abs, {
|
|
1204
|
+
force: true
|
|
1205
|
+
});
|
|
1206
|
+
removedDirs.add(join(abs, ".."));
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
for (const dir of removedDirs) {
|
|
1210
|
+
let current = dir;
|
|
1211
|
+
while (current.startsWith(outDir) && current !== outDir) {
|
|
1212
|
+
try {
|
|
1213
|
+
if (readdirSync(current).length === 0) {
|
|
1214
|
+
rmdirSync(current);
|
|
1215
|
+
current = join(current, "..");
|
|
1216
|
+
} else {
|
|
1217
|
+
break;
|
|
1022
1218
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
initLines.push(`class ${sdkClassName}(BaseClient):`);
|
|
1026
|
-
initLines.push(` pass`);
|
|
1027
|
-
initLines.push("");
|
|
1219
|
+
} catch {
|
|
1220
|
+
break;
|
|
1028
1221
|
}
|
|
1029
|
-
const allNames = [
|
|
1030
|
-
"BaseClient",
|
|
1031
|
-
"SdkError",
|
|
1032
|
-
sdkClassName,
|
|
1033
|
-
...clientInfos.map((c) => c.className)
|
|
1034
|
-
];
|
|
1035
|
-
initLines.push(`__all__ = [${allNames.map((n) => JSON.stringify(n)).join(", ")}]`);
|
|
1036
|
-
initLines.push("");
|
|
1037
|
-
ctx.emitFile(join(outDir, "__init__.py"), initLines.join("\n"));
|
|
1038
1222
|
}
|
|
1039
|
-
}
|
|
1223
|
+
}
|
|
1040
1224
|
}
|
|
1041
|
-
__name(
|
|
1225
|
+
__name(deleteStalePaths, "deleteStalePaths");
|
|
1042
1226
|
export {
|
|
1227
|
+
PYTHON_CODEGEN_VERSION,
|
|
1043
1228
|
createPythonSdkPlugin,
|
|
1044
1229
|
index_default as default
|
|
1045
1230
|
};
|