Skip to content

Commit d8d90f3

Browse files
committed
Move scg config schema validation to lib
1 parent 465ec46 commit d8d90f3

10 files changed

Lines changed: 380 additions & 407 deletions

File tree

packages/extension/client/src/scg.ts

Lines changed: 315 additions & 319 deletions
Large diffs are not rendered by default.

packages/extension/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,9 @@
563563
"test_with_coverage": "pnpm build && nyc mocha --import ts-node/esm --require source-map-support/register --recursive server/src/test/**/*.test.ts "
564564
},
565565
"dependencies": {
566+
"@equinor/septic-config-lib": "workspace:*",
566567
"@vscode/prompt-tsx": "^0.4.0-alpha.5",
567-
"ajv": "^8.12.0",
568-
"js-yaml": "^4.1.1",
569-
"@equinor/septic-config-lib": "workspace:*"
568+
"js-yaml": "^4.1.1"
570569
},
571570
"devDependencies": {
572571
"@types/vscode": "^1.105.0",

packages/extension/server/src/documentProvider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ export class DocumentProvider {
286286
this.cache.set(uri, doc);
287287
return doc;
288288
} catch {
289+
console.log(`Failed to open document from file system: ${uri}`);
289290
return undefined;
290291
}
291292
}

packages/extension/server/src/scgContextManager.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55

66
import { Connection, Emitter, Event } from "vscode-languageserver";
77
import { DocumentProvider } from "./documentProvider";
8-
import * as YAML from "js-yaml";
98
import * as path from "path";
10-
import * as protocol from "./protocol";
11-
import { ScgConfig, ScgContext } from "@equinor/septic-config-lib";
9+
import { scgConfigFromYAML, ScgContext } from "@equinor/septic-config-lib";
1210
import { SepticConfigProvider } from "./configProvider";
1311

1412
export class ScgContextManager {
@@ -83,10 +81,11 @@ export class ScgContextManager {
8381

8482
try {
8583
await this.updateScgContext(uri);
86-
} catch {
84+
} catch (error) {
8785
console.log(
8886
`Error updating context ${context.name}. Removing context from manager!`,
8987
);
88+
console.log(error);
9089
this.contexts.delete(context.name);
9190
}
9291
return;
@@ -115,18 +114,12 @@ export class ScgContextManager {
115114
if (!doc) {
116115
return;
117116
}
118-
const scgConfig = YAML.load(doc.getText()) as ScgConfig;
119-
const filesInTemplatePath = await this.connection.sendRequest(
120-
protocol.globFiles,
121-
{
122-
uri: path.parse(uri).dir + "/" + scgConfig.templatepath,
123-
},
124-
);
117+
const scgConfig = scgConfigFromYAML(doc.getText());
118+
125119
const scgContext = new ScgContext(
126120
uri,
127121
uri,
128122
scgConfig,
129-
filesInTemplatePath,
130123
this.cnfgProvider,
131124
);
132125
this.contexts.set(scgContext.name, scgContext);
File renamed without changes.

packages/septic/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export {
1717
SepticTokenType,
1818
} from "./elements";
1919
export type { SepticReference } from "./reference";
20-
export { ScgContext } from "./scgContext";
21-
export type { ScgConfig } from "./scgContext";
20+
export { ScgContext, validate_scg, scgConfigFromYAML } from "./scg";
21+
export type { ScgConfigSchema } from "./scg";
2222
export { fromCalcIndexToParamIndex } from "./calc";
2323
export { findAlgCycles } from "./cycle";
2424
export type { SepticContext } from "./context";

packages/septic/src/metaInfoProvider.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import * as YAML from "js-yaml";
77
import * as fs from "fs";
88
import * as path from "path";
9+
import { getBasePublicPath } from "./path";
910

1011
export const defaultObjectLevel = 2;
1112
export const defaultObjectSymbolKind = "object";
@@ -236,24 +237,6 @@ export class SepticMetaInfoProvider {
236237
}
237238
}
238239

239-
function getBasePublicPath(): string {
240-
// Use a different base path for tests if NODE_ENV is 'test'
241-
if (process.env.NODE_ENV === "test") {
242-
return path.join(__dirname, `../public`);
243-
}
244-
245-
// Check for assets in the bundled location (e.g. dist/assets)
246-
// This works when the extension is bundled and assets are copied next to the bundle
247-
const bundledPath = path.join(__dirname, "public");
248-
if (fs.existsSync(bundledPath)) {
249-
return bundledPath;
250-
}
251-
252-
// Fallback to development/library structure (e.g. packages/septic/assets)
253-
// This works when running via ts-node or from the compiled lib folder
254-
return path.join(__dirname, "../public");
255-
}
256-
257240
function updateDatatypeParams(params: SepticCalcParameterInfo[] | undefined) {
258241
if (!params) {
259242
return [];
Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,48 @@ import { SepticObject } from "./elements";
1414
import { ISepticConfigProvider } from "./configProvider";
1515
import { SepticCnfg } from "./cnfg";
1616
import { updateParentObjects } from "./hierarchy";
17+
import { readFileSync } from "fs";
18+
import * as yaml from "js-yaml";
1719

18-
export interface ScgConfig {
19-
outputfile?: string;
20-
21-
templatepath: string;
22-
23-
verifycontent: boolean;
20+
import Ajv from "ajv";
21+
import { getBasePublicPath } from "./path";
2422

25-
adjustsspacing: boolean;
23+
const ajv = new Ajv();
24+
const scgSchemaPath = getBasePublicPath() + "/scg_config.schema.json";
25+
const scgSchema = JSON.parse(readFileSync(scgSchemaPath, "utf-8"));
26+
export const validate_scg = ajv.compile<ScgConfigSchema>(scgSchema);
2627

27-
sources: ScgSource[];
28-
layout: ScgTemplate[];
29-
}
30-
31-
export interface ScgSource {
32-
filename: string;
33-
id: string;
34-
sheet: string;
28+
export interface ScgConfigSchema {
29+
outputfile?: string;
30+
templatepath: string;
31+
adjustspacing?: boolean;
32+
verifycontent?: boolean;
33+
counters?: {
34+
name: string;
35+
value: number;
36+
}[];
37+
sources: {
38+
filename: string;
39+
id: string;
40+
sheet?: string;
41+
delimiter?: string;
42+
}[];
43+
layout: {
44+
name: string;
45+
source?: string;
46+
include?: object;
47+
}[];
3548
}
3649

37-
export interface ScgTemplate {
38-
name: string;
39-
source?: string;
40-
include?: string[];
50+
export function scgConfigFromYAML(yamlContent: string): ScgConfigSchema {
51+
const config = yaml.load(yamlContent);
52+
const valid = validate_scg(config);
53+
if (!valid) {
54+
throw new Error(
55+
`Invalid SCG config: ${ajv.errorsText(validate_scg.errors)}`,
56+
);
57+
}
58+
return config;
4159
}
4260

4361
export class ScgContext implements SepticContext {
@@ -51,45 +69,30 @@ export class ScgContext implements SepticContext {
5169
constructor(
5270
name: string,
5371
filePath: string,
54-
config: ScgConfig,
55-
filesInTemplateDir: string[],
72+
config: ScgConfigSchema,
5673
cnfgProvider: ISepticConfigProvider,
5774
) {
5875
this.name = name;
5976
this.filePath = filePath;
6077
this.cnfgProvider = cnfgProvider;
6178

62-
this.files = this.getFiles(config, filesInTemplateDir);
79+
this.files = this.getFiles(config);
6380
}
6481

6582
public fileInContext(file: string): boolean {
6683
return this.files.includes(file);
6784
}
6885

69-
private getFiles(
70-
scgConfig: ScgConfig,
71-
filesInTemplateDir: string[],
72-
): string[] {
73-
const files = [];
74-
for (const template of scgConfig.layout) {
75-
if (path.extname(template.name) !== ".cnfg") {
76-
continue;
77-
}
78-
let found = false;
79-
for (const file of filesInTemplateDir) {
80-
if (template.name === path.basename(file)) {
81-
files.push(file);
82-
found = true;
83-
break;
84-
}
85-
}
86-
if (!found) {
87-
console.log(
88-
`Could not find template: ${template.name} in template dir for context ${this.name}`,
89-
);
90-
}
91-
}
92-
return files;
86+
private getFiles(scgConfig: ScgConfigSchema): string[] {
87+
return scgConfig.layout.map((layout) => {
88+
return (
89+
path.dirname(this.filePath) +
90+
"/" +
91+
scgConfig.templatepath +
92+
"/" +
93+
layout.name
94+
);
95+
});
9396
}
9497

9598
public async load(): Promise<void> {
@@ -137,9 +140,6 @@ export class ScgContext implements SepticContext {
137140
for (const file of this.files) {
138141
const cnfg = this.cnfgCache.get(file);
139142
if (!cnfg) {
140-
console.log(
141-
`Could not get config for ${file} in context ${this.name}`,
142-
);
143143
continue;
144144
}
145145
const localReferences = cnfg.getReferences(name);

packages/septic/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"skipLibCheck": true,
4141
"outDir": "./dist",
4242
"rootDir": "./src",
43-
"composite": true
43+
"composite": true,
44+
"resolveJsonModule": true
4445
},
4546
"include": ["src"],
4647
"exclude": ["node_modules", "src/test", "dist"]

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)