Skip to content

Commit 9d7ae87

Browse files
committed
feat: some small adjustments
1 parent f1c0ff8 commit 9d7ae87

File tree

8 files changed

+246
-127
lines changed

8 files changed

+246
-127
lines changed

package/mapper/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"@code0-tech/tucana": "^0.0.39",
3434
"@protobuf-ts/runtime": "^2.11.1",
3535
"@protobuf-ts/runtime-rpc": "^2.11.1",
36-
"fflate": "^0.8.2",
3736
"vite-plugin-dts": "^4.5.4"
3837
}
3938
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
flowTypes
84+
.map((f) => ({ name: f.feature, type: mapFlowType(f.flow, constructed) }))
85+
.forEach((ft) => ft.type && getFeature(ft.name).flowTypes.push(ft.type));
86+
87+
return features;
88+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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+
};
112+

package/mapper/src/definition/remote.ts

Lines changed: 0 additions & 119 deletions
This file was deleted.

package/mapper/src/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
1-
export { DefinitionMapper } from './definition/remote.js';
2-
export type { Feature } from './definition/remote.js';
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+
});

package/mapper/src/mapper/dataTypeMapper.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,43 @@ import {
55
DataTypeRulesInputTypeConfig,
66
DataTypeRulesInputTypesConfig,
77
DataTypeRulesItemOfCollectionConfig, DataTypeRulesNumberRangeConfig,
8-
DataTypeRulesParentTypeConfig, DataTypeRulesRegexConfig, DataTypeRulesVariant, DataTypeVariant,
9-
GenericCombinationStrategyType,
8+
DataTypeRulesParentTypeConfig, DataTypeRulesRegexConfig,
109
} from "@code0-tech/sagittarius-graphql-types";
1110
import {
1211
DataTypeIdentifier as TucanaDataTypeIdentifier,
1312
DefinitionDataType_Variant, DefinitionDataTypeRule, GenericMapper_GenericCombinationStrategy
1413
} from "@code0-tech/tucana/pb/shared.data_type_pb.js"
1514
import {GenericMapper as TucanaGenericMapper} from "@code0-tech/tucana/pb/shared.data_type_pb.js"
16-
import {ConstructedDataTypes, getID} from "../definition/remote.js";
15+
import {ConstructedDataTypes, getID} from "../definition/mapper.js";
1716
import {getTranslationConnection} from "./translation.js";
1817
import {Value} from "@code0-tech/tucana/pb/shared.struct_pb.js";
1918

19+
enum GenericCombinationStrategyType {
20+
And = 'AND',
21+
Or = 'OR'
22+
}
23+
24+
enum DataTypeRulesVariant {
25+
ContainsKey = 'CONTAINS_KEY',
26+
ContainsType = 'CONTAINS_TYPE',
27+
InputType = 'INPUT_TYPE',
28+
ItemOfCollection = 'ITEM_OF_COLLECTION',
29+
NumberRange = 'NUMBER_RANGE',
30+
ParentType = 'PARENT_TYPE',
31+
Regex = 'REGEX',
32+
ReturnType = 'RETURN_TYPE'
33+
}
34+
35+
enum DataTypeVariant {
36+
Array = 'ARRAY',
37+
DataType = 'DATA_TYPE',
38+
Error = 'ERROR',
39+
Node = 'NODE',
40+
Object = 'OBJECT',
41+
Primitive = 'PRIMITIVE',
42+
Type = 'TYPE'
43+
}
44+
2045
function getDataType(identifier: string, constructedDataTypes: ConstructedDataTypes): DataType | null {
2146
const dataType = constructedDataTypes.constructedDataTypes.find(dt => dt.identifier === identifier)
2247
if (dataType == undefined) {

0 commit comments

Comments
 (0)