Skip to content

Commit 3c1711f

Browse files
committed
feat: temp added mapper back
1 parent 40e7dda commit 3c1711f

File tree

14 files changed

+2062
-0
lines changed

14 files changed

+2062
-0
lines changed

package/mapper/package-lock.json

Lines changed: 1367 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package/mapper/package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "@code0-tech/definition-mapper",
3+
"version": "0.0.0",
4+
"description": "Will map Code0-Definitions to its correspondent Sagittarius-Types",
5+
"main": "./dist/index.js",
6+
"types": "./dist/index.d.ts",
7+
"type": "module",
8+
"scripts": {
9+
"build": "vite build",
10+
"start": "node ./dist/index.js",
11+
"build:and:run": "vite build && node ./dist/index.js"
12+
},
13+
"author": "",
14+
"license": "",
15+
"devDependencies": {
16+
"@types/node": "^24.1.0",
17+
"typescript": "^5.8.3",
18+
"vite": "^7.1.11"
19+
},
20+
"repository": {
21+
"type": "git",
22+
"url": "https://github.com/code0-tech/code0-definition"
23+
},
24+
"files": [
25+
"dist",
26+
"src"
27+
],
28+
"publishConfig": {
29+
"access": "public"
30+
},
31+
"dependencies": {
32+
"@code0-tech/sagittarius-graphql-types": "0.0.0-a395eea54741fc1bb9649341ff6f082cc1c3e67e",
33+
"@code0-tech/tucana": "0.0.50",
34+
"@protobuf-ts/runtime": "^2.11.1",
35+
"@protobuf-ts/runtime-rpc": "^2.11.1",
36+
"vite-plugin-dts": "^4.5.4"
37+
}
38+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { FlowType as TucanaFlowType } from "@code0-tech/tucana/pb/shared.flow_definition_pb.js";
2+
import { RuntimeFunctionDefinition as TucanaFunction } from "@code0-tech/tucana/pb/shared.runtime_function_pb.js";
3+
import { DefinitionDataType as TucanaDataType } from "@code0-tech/tucana/pb/shared.data_type_pb.js";
4+
5+
import type { DataType, FlowType, FunctionDefinition } from "@code0-tech/sagittarius-graphql-types";
6+
import { getDataType } from "../mapper/dataTypeMapper.js";
7+
import { mapFlowType } from "../mapper/flowTypeMapper.js";
8+
import { mapFunction } from "../mapper/functionMapper.js";
9+
import {Reader} from "./reader";
10+
11+
export interface ConstructedDataTypes {
12+
scannedTucanaTypes: TucanaDataType[];
13+
constructedDataTypes: DataType[];
14+
id: number;
15+
}
16+
17+
export interface Feature {
18+
name: string;
19+
dataTypes: DataType[];
20+
flowTypes: FlowType[];
21+
runtimeFunctions: FunctionDefinition[];
22+
}
23+
export function getID(constructedDataTypes: ConstructedDataTypes) {
24+
const last = constructedDataTypes.id;
25+
constructedDataTypes.id += 1;
26+
return last;
27+
}
28+
29+
export async function DefinitionMapper(path: string): Promise<Feature[]> {
30+
const dataTypes: { feature: string; type: TucanaDataType }[] = [];
31+
const flowTypes: { feature: string; flow: TucanaFlowType }[] = [];
32+
const runtimeFunctions: { feature: string; func: TucanaFunction }[] = [];
33+
34+
const tucanaFeature = await Reader.fromPath(path)
35+
36+
tucanaFeature.forEach(feature => {
37+
feature.data_types.forEach(dataType => {
38+
dataTypes.push({
39+
feature: feature.name,
40+
type: dataType
41+
})
42+
})
43+
44+
feature.flow_types.forEach(flowType => {
45+
flowTypes.push({
46+
feature: feature.name,
47+
flow: flowType
48+
})
49+
})
50+
51+
feature.runtime_functions.forEach(runtimeFunction => {
52+
runtimeFunctions.push({
53+
feature: feature.name,
54+
func: runtimeFunction
55+
})
56+
})
57+
})
58+
59+
const constructed: ConstructedDataTypes = {
60+
scannedTucanaTypes: dataTypes.map((d) => d.type),
61+
constructedDataTypes: [],
62+
id: 0,
63+
};
64+
65+
const features: Feature[] = [];
66+
const getFeature = (name: string): Feature => {
67+
let f = features.find((x) => x.name === name);
68+
if (!f) {
69+
f = { name, dataTypes: [], flowTypes: [], runtimeFunctions: [] };
70+
features.push(f);
71+
}
72+
return f;
73+
};
74+
75+
dataTypes
76+
.map((f) => ({ name: f.feature, type: getDataType(f.type.identifier, constructed) }))
77+
.forEach((dt) => dt.type && getFeature(dt.name).dataTypes.push(dt.type));
78+
79+
runtimeFunctions
80+
.map((f) => ({ name: f.feature, type: mapFunction(f.func, constructed) }))
81+
.forEach((rf) => rf.type && getFeature(rf.name).runtimeFunctions.push(rf.type));
82+
83+
console.dir(flowTypes, {depth: null})
84+
85+
flowTypes
86+
.map((f) => ({ name: f.feature, type: mapFlowType(f.flow, constructed) }))
87+
.forEach((ft) => ft.type && getFeature(ft.name).flowTypes.push(ft.type));
88+
89+
return features;
90+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import {readdir, readFile} from "node:fs/promises";
2+
import {join, extname} from "node:path";
3+
4+
import {FlowType} from "@code0-tech/tucana/pb/shared.flow_definition_pb.js";
5+
import {RuntimeFunctionDefinition} from "@code0-tech/tucana/pb/shared.runtime_function_pb.js";
6+
import {DefinitionDataType} from "@code0-tech/tucana/pb/shared.data_type_pb.js";
7+
8+
export const enum MetaType {
9+
FlowType = "FlowType",
10+
DataType = "DataType",
11+
RuntimeFunction = "RuntimeFunction",
12+
}
13+
14+
export interface DefinitionError {
15+
definition: string;
16+
definition_type: MetaType;
17+
error: string;
18+
}
19+
20+
export interface TucanaFeature {
21+
name: string;
22+
data_types: DefinitionDataType[];
23+
flow_types: FlowType[];
24+
runtime_functions: RuntimeFunctionDefinition[];
25+
errors: DefinitionError[];
26+
}
27+
28+
export class Reader {
29+
static async fromPath(root: string): Promise<TucanaFeature[]> {
30+
const features = new Map<string, TucanaFeature>();
31+
32+
for (const featureDir of await safeReadDir(root)) {
33+
if (!featureDir.isDirectory()) continue;
34+
const featureName = featureDir.name;
35+
const featurePath = join(root, featureName);
36+
37+
for (const typeDir of await safeReadDir(featurePath)) {
38+
const type = toMetaType(typeDir.name);
39+
if (!type) continue;
40+
41+
const typePath = join(featurePath, typeDir.name);
42+
const jsonPaths = await collectJsonFiles(typePath);
43+
44+
for (const file of jsonPaths) {
45+
const def = await readFile(file, "utf8");
46+
const f = features.get(featureName) ?? emptyFeature(featureName);
47+
addDefinition(f, def, type);
48+
features.set(featureName, f);
49+
}
50+
}
51+
}
52+
53+
return Array.from(features.values());
54+
}
55+
}
56+
57+
const toMetaType = (folder: string): MetaType | null =>
58+
({
59+
flow_type: MetaType.FlowType,
60+
data_type: MetaType.DataType,
61+
runtime_definition: MetaType.RuntimeFunction
62+
} as const)[folder] ?? null;
63+
64+
const emptyFeature = (name: string): TucanaFeature => ({
65+
name,
66+
data_types: [],
67+
flow_types: [],
68+
runtime_functions: [],
69+
errors: [],
70+
});
71+
72+
const safeReadDir = async (p: string) => {
73+
try {
74+
return await readdir(p, {withFileTypes: true});
75+
} catch {
76+
return [];
77+
}
78+
};
79+
80+
const collectJsonFiles = async (dir: string): Promise<string[]> => {
81+
const entries = await safeReadDir(dir);
82+
const files = entries.filter(e => e.isFile() && extname(e.name) === ".json").map(e => join(dir, e.name));
83+
84+
// include one nested level
85+
for (const e of entries.filter(e => e.isDirectory())) {
86+
const sub = (await safeReadDir(join(dir, e.name)))
87+
.filter(s => s.isFile() && extname(s.name) === ".json")
88+
.map(s => join(dir, e.name, s.name));
89+
files.push(...sub);
90+
}
91+
return files;
92+
};
93+
94+
const addDefinition = (feature: TucanaFeature, def: string, type: MetaType) => {
95+
try {
96+
if (type === MetaType.DataType) feature.data_types.push(DefinitionDataType.fromJsonString(def));
97+
else if (type === MetaType.FlowType) feature.flow_types.push(FlowType.fromJsonString(def));
98+
else feature.runtime_functions.push(RuntimeFunctionDefinition.fromJsonString(def));
99+
} catch (err) {
100+
feature.errors.push({
101+
definition: extractIdentifier(def, type),
102+
definition_type: type,
103+
error: err instanceof Error ? err.message : String(err),
104+
});
105+
}
106+
};
107+
108+
const extractIdentifier = (def: string, type: MetaType): string => {
109+
const key = type === MetaType.RuntimeFunction ? "runtime_name" : "identifier";
110+
return def.match(new RegExp(`"${key}"\\s*:\\s*"([^"]+)"`))?.[1] ?? def;
111+
};

package/mapper/src/export/dataTypes.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"__typename":"FlowType","id":"gid://sagittarius/FlowType/868","identifier":"REST","inputType":{"__typename":"DataType","id":"gid://sagittarius/DataType/1","genericKeys":[],"identifier":"REST_ADAPTER_INPUT","aliases":[{"__typename":"Translation","code":"en-US","content":"http;rest;adapter;input"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Rest Adapter Input"}],"name":[{"__typename":"Translation","code":"en-US","content":"Rest Adapter Input"}],"rules":{"count":3,"nodes":[{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/2","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/3","genericKeys":[],"identifier":"OBJECT","aliases":[{"__typename":"Translation","code":"en-US","content":"object;struct;data"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Object"}],"name":[{"__typename":"Translation","code":"en-US","content":"Object"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}},"key":"body"}},{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/4","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/0","genericKeys":[],"identifier":"REST_HEADER_INPUT","aliases":[{"__typename":"Translation","code":"en-US","content":"http;rest;header;entry;input"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Headers"}],"name":[{"__typename":"Translation","code":"en-US","content":"Headers"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}},"key":"headers"}},{"variant":"PARENT_TYPE","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/5","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/3","genericKeys":[],"identifier":"OBJECT","aliases":[{"__typename":"Translation","code":"en-US","content":"object;struct;data"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Object"}],"name":[{"__typename":"Translation","code":"en-US","content":"Object"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}}}}]},"variant":"OBJECT"},"returnType":{"__typename":"DataType","id":"gid://sagittarius/DataType/41","genericKeys":[],"identifier":"HTTP_RESPONSE","aliases":[{"__typename":"Translation","code":"en-US","content":"http;response;object"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"HTTP Response"}],"name":[{"__typename":"Translation","code":"en-US","content":"HTTP Response"}],"rules":{"count":3,"nodes":[{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/42","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/6","genericKeys":[],"identifier":"HTTP_HEADER_MAP","aliases":[{"__typename":"Translation","code":"en-US","content":"http;headers"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"HTTP Headers"}],"name":[{"__typename":"Translation","code":"en-US","content":"HTTP Headers"}],"rules":{"count":1,"nodes":[{"variant":"PARENT_TYPE","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/7","genericType":{"id":"gid://sagittarius/GenericType/8","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/9","genericKeys":["T"],"identifier":"LIST","aliases":[{"__typename":"Translation","code":"en-US","content":"list;array;collection"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"List of ${T}"}],"name":[{"__typename":"Translation","code":"en-US","content":"Generic List"}],"rules":{"count":1,"nodes":[{"variant":"CONTAINS_TYPE","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/10","genericKey":"T"}}}]},"variant":"ARRAY"},"genericMappers":[{"genericCombinationStrategies":[],"sourceDataTypeIdentifiers":[{"id":"gid://sagittarius/DataTypeIdentifier/11","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/12","genericKeys":[],"identifier":"HTTP_HEADER_ENTRY","aliases":[{"__typename":"Translation","code":"en-US","content":"http;header;entry"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"HTTP Header Entry"}],"name":[{"__typename":"Translation","code":"en-US","content":"HTTP Header Entry"}],"rules":{"count":3,"nodes":[{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/13","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/14","genericKeys":[],"identifier":"TEXT","aliases":[{"__typename":"Translation","code":"en-US","content":"text;char;literal;string"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Text"}],"name":[{"__typename":"Translation","code":"en-US","content":"Text"}],"rules":{"count":1,"nodes":[{"variant":"REGEX","config":{"pattern":"[\\s\\S]*"}}]},"variant":"PRIMITIVE"}},"key":"key"}},{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/15","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/14","genericKeys":[],"identifier":"TEXT","aliases":[{"__typename":"Translation","code":"en-US","content":"text;char;literal;string"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Text"}],"name":[{"__typename":"Translation","code":"en-US","content":"Text"}],"rules":{"count":1,"nodes":[{"variant":"REGEX","config":{"pattern":"[\\s\\S]*"}}]},"variant":"PRIMITIVE"}},"key":"value"}},{"variant":"PARENT_TYPE","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/16","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/3","genericKeys":[],"identifier":"OBJECT","aliases":[{"__typename":"Translation","code":"en-US","content":"object;struct;data"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Object"}],"name":[{"__typename":"Translation","code":"en-US","content":"Object"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}}}}]},"variant":"OBJECT"}}],"target":"T","id":"gid://sagittarius/GenericMapper/17"}]}}}}]},"variant":"ARRAY"}},"key":"headers"}},{"variant":"CONTAINS_KEY","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/43","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/3","genericKeys":[],"identifier":"OBJECT","aliases":[{"__typename":"Translation","code":"en-US","content":"object;struct;data"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Object"}],"name":[{"__typename":"Translation","code":"en-US","content":"Object"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}},"key":"body"}},{"variant":"PARENT_TYPE","config":{"dataTypeIdentifier":{"id":"gid://sagittarius/DataTypeIdentifier/44","dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/3","genericKeys":[],"identifier":"OBJECT","aliases":[{"__typename":"Translation","code":"en-US","content":"object;struct;data"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"Object"}],"name":[{"__typename":"Translation","code":"en-US","content":"Object"}],"rules":{"count":0,"nodes":[]},"variant":"OBJECT"}}}}]},"variant":"OBJECT"},"flowTypeSettings":[{"__typename":"FlowTypeSetting","id":"gid://sagittarius/FlowTypeSetting/869","names":[{"__typename":"Translation","code":"en-US","content":"URL"}],"descriptions":[{"__typename":"Translation","code":"en-US","content":"Specifies the HTTP URL endpoint."}],"dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/37","genericKeys":[],"identifier":"HTTP_URL","aliases":[{"__typename":"Translation","code":"en-US","content":"http;route;url"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"HTTP Route"}],"name":[{"__typename":"Translation","code":"en-US","content":"HTTP Route"}],"rules":{"count":1,"nodes":[{"variant":"REGEX","config":{"pattern":"^/\\w+(?:[.:~-]\\w+)*(?:/\\w+(?:[.:~-]\\w+)*)*$"}}]},"variant":"TYPE"},"identifier":"HTTP_URL","unique":2},{"__typename":"FlowTypeSetting","id":"gid://sagittarius/FlowTypeSetting/870","names":[{"__typename":"Translation","code":"en-US","content":"Method"}],"descriptions":[{"__typename":"Translation","code":"en-US","content":"Specifies the HTTP request method (e.g., GET, POST, PUT, DELETE)."}],"dataType":{"__typename":"DataType","id":"gid://sagittarius/DataType/35","genericKeys":[],"identifier":"HTTP_METHOD","aliases":[{"__typename":"Translation","code":"en-US","content":"http;method;get;post;put;delete;path;head"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"HTTP Method"}],"name":[{"__typename":"Translation","code":"en-US","content":"HTTP Method"}],"rules":{"count":1,"nodes":[{"variant":"ITEM_OF_COLLECTION","config":{"items":["GET","POST","PUT","DELETE","PATCH","HEAD"]}}]},"variant":"TYPE"},"identifier":"HTTP_METHOD","unique":1}],"names":[{"__typename":"Translation","code":"en-US","content":"Rest Endpoint"}],"descriptions":[{"__typename":"Translation","code":"en-US","content":"A REST API is a web service that lets clients interact with data on a server using standard HTTP methods like GET, POST, PUT, and DELETE usually returning results in JSON format."}],"aliases":[{"__typename":"Translation","code":"en-US","content":"http;rest;route;web;webhook"}],"displayMessages":[{"__typename":"Translation","code":"en-US","content":"On ${method} request to ${route}"}],"editable":false}]

package/mapper/src/export/functions.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

package/mapper/src/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {DefinitionMapper, Feature} from "./definition/mapper.js";
2+
import * as fs from "node:fs";
3+
import * as path from "node:path";
4+
5+
DefinitionMapper("../../../definitions").then((value: Feature[]) => {
6+
const functions = value.flatMap(v => v.runtimeFunctions);
7+
const types = value.flatMap(v => v.dataTypes);
8+
const flows = value.flatMap(v => v.flowTypes);
9+
10+
const outDir = path.resolve("./export");
11+
fs.mkdirSync(outDir, {recursive: true});
12+
13+
fs.writeFileSync(path.join(outDir, "functions.json"), JSON.stringify(functions));
14+
fs.writeFileSync(path.join(outDir, "dataTypes.json"), JSON.stringify(types));
15+
fs.writeFileSync(path.join(outDir, "flowTypes.json"), JSON.stringify(flows));
16+
});

0 commit comments

Comments
 (0)