Skip to content
This repository was archived by the owner on Feb 14, 2025. It is now read-only.

Commit c717888

Browse files
authored
Merge pull request #38 from publicodes/compilation-better-errors
feat(compilation): better error message
2 parents 3b48325 + 6a6b214 commit c717888

25 files changed

+383
-225
lines changed

package.json

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"version": "1.1.2",
44
"description": "A set of utility functions to build tools around Publicodes models",
55
"type": "module",
6+
"main": "dist/index.cjs",
7+
"module": "dist/index.js",
8+
"types": "dist/index.d.ts",
69
"scripts": {
710
"build": "tsup",
811
"watch": "tsup --watch",
@@ -65,28 +68,28 @@
6568
"prettier": "^3.0.0",
6669
"ts-jest": "^29.0.4",
6770
"ts-node": "^10.9.2",
68-
"tsup": "^6.5.0",
71+
"tsup": "^8.0.2",
6972
"typedoc": "^0.24.8",
7073
"typedoc-plugin-export-functions": "^1.0.0",
7174
"typescript": "^4.9.4",
7275
"yaml": "^2.3.1"
7376
},
7477
"tsup": {
78+
"verbose": true,
7579
"entry": [
76-
"source/index.ts",
77-
"source/optims/index.ts",
78-
"source/compilation/index.ts",
79-
"source/migration/index.ts"
80+
"src/index.ts",
81+
"src/optims/index.ts",
82+
"src/compilation/index.ts",
83+
"src/migration/index.ts"
8084
],
85+
"cjsInterop": true,
8186
"format": [
8287
"cjs",
8388
"esm"
8489
],
85-
"allowJs": true,
8690
"sourceMap": true,
8791
"dts": true,
8892
"clean": true,
89-
"target": "es2020",
9093
"skipNodeModulesBundle": true
9194
},
9295
"publishConfig": {

source/commons.ts src/commons.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import yaml from 'yaml'
1313
*/
1414

1515
/**
16-
* Represents a rule name, i.e. 'rule . A. B'
16+
* Represents a rule name, i.e. 'rule . A . B'
1717
*/
1818
export type RuleName = string
1919

source/compilation/getModelFromSource.ts src/compilation/getModelFromSource.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { readFileSync, statSync } from 'fs'
12
import glob from 'glob'
23
import yaml from 'yaml'
3-
import { readFileSync, statSync } from 'fs'
44
import { getDoubleDefError, RawRules } from '../commons'
55
import { resolveImports } from './resolveImports'
66

source/compilation/index.ts src/compilation/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ To import rules from a _packaged_ Publicodes model, you need to specify the foll
3131
```yaml
3232
importer!:
3333
depuis:
34-
nom: <npm_package_name>
35-
source: <path_to_the_model_file> (optional)
36-
url: <url_to_the_package_documentation> (optional)
34+
nom: <npm_package_name>
35+
source: <path_to_the_model_file> (optional)
36+
url: <url_to_the_package_documentation> (optional)
3737
dans: <namespace> (optional)
3838
les règles:
3939
- <rule_name_from_the_npm_package>

source/compilation/resolveImports.ts src/compilation/resolveImports.ts

+51-15
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
getDoubleDefError,
1010
} from '../commons'
1111
import { readFileSync } from 'fs'
12-
import { dirname, join } from 'path'
12+
import { dirname, join, basename } from 'path'
1313

1414
/**
1515
* @param {string} packageName - The package name.
@@ -33,28 +33,44 @@ const enginesCache = {}
3333
* @param filePath - The path to the file containing the rules in a JSON format.
3434
* @param opts - Options.
3535
*
36+
* @throws {Error} If the package is not found.
3637
* @throws {Error} If the package name is missing in the macro.
3738
*/
3839
function getEngine(
3940
filePath: string,
4041
{ depuis }: ImportMacro,
4142
verbose: boolean,
4243
): Engine {
43-
const packageName = depuis.nom
44+
const packageName = depuis?.nom
4445
const fileDirPath = dirname(filePath)
4546

4647
if (packageName === undefined) {
4748
throw new Error(
48-
`Le nom du package est manquant dans la macro 'importer!' dans le fichier: ${filePath}`,
49+
`[ Erreur dans la macro 'importer!' ]
50+
Le nom du package est manquant dans la macro 'importer!' dans le fichier: ${basename(filePath)}.
51+
52+
[ Solution ]
53+
Ajoutez le nom du package dans la macro 'importer!'.
54+
55+
[ Exemple ]
56+
importer!:
57+
depuis:
58+
nom: package-name
59+
les règles:
60+
- ruleA
61+
- ruleB
62+
...
63+
`,
4964
)
5065
}
5166

52-
if (!enginesCache[packageName]) {
67+
const modelPath =
68+
depuis.source !== undefined
69+
? join(fileDirPath, depuis.source)
70+
: packageModelPath(packageName)
71+
72+
if (!enginesCache[modelPath]) {
5373
try {
54-
const modelPath =
55-
depuis.source !== undefined
56-
? join(fileDirPath, depuis.source)
57-
: packageModelPath(packageName)
5874
const model = JSON.parse(readFileSync(modelPath, 'utf-8'))
5975
const engine = new Engine(model, {
6076
logger: {
@@ -67,13 +83,26 @@ function getEngine(
6783
if (verbose) {
6884
console.debug(`📦 ${packageName} loaded`)
6985
}
70-
enginesCache[packageName] = engine
86+
enginesCache[modelPath] = engine
7187
} catch (e) {
72-
console.error(`Error when loading '${packageName}': ${e}`)
88+
throw new Error(`[ Erreur dans la macro 'importer!' ]
89+
Le package '${packageName}' n'a pas pu être trouvé. (Le fichier '${modelPath}' est introuvable).
90+
91+
[ Solution ]
92+
- Assurez-vous que le package existe et qu'il est correctement installé dans vos 'node_modules'.
93+
- Assurez-vous que le fichier '${packageName}.model.json' existe à la racine du package. Sinon,
94+
précisez le chemin du fichier dans la macro 'importer!' grâce à l'attribut 'source'.
95+
96+
[ Exemple ]
97+
importer!:
98+
depuis:
99+
nom: package-name
100+
source: ../custom-package/path/package-name.model.json
101+
`)
73102
}
74103
}
75104

76-
return enginesCache[packageName]
105+
return enginesCache[modelPath]
77106
}
78107

79108
function getDependencies(engine: Engine, rule: RuleNode, acc = []) {
@@ -213,7 +242,11 @@ export function resolveImports(
213242
rulesToImport?.forEach(({ ruleName, attrs }) => {
214243
if (appearsMoreThanOnce(rulesToImport, ruleName)) {
215244
throw new Error(
216-
`La règle '${ruleName}' est définie deux fois dans ${importMacro.depuis.nom}`,
245+
`[ Erreur dans la macro 'importer!' ]
246+
La règle '${ruleName}' est définie deux fois dans ${importMacro.depuis.nom}
247+
248+
[ Solution ]
249+
Supprimez une des deux définitions de la règle '${ruleName}' dans la macro 'importer!'`,
217250
)
218251
}
219252
if (accFind(acc, ruleName)) {
@@ -224,9 +257,12 @@ export function resolveImports(
224257
try {
225258
rule = engine.getRule(ruleName)
226259
} catch (e) {
227-
throw new Error(
228-
`La règle '${ruleName}' n'existe pas dans ${importMacro.depuis.nom}`,
229-
)
260+
throw new Error(`[ Erreur dans la macro 'importer!' ]
261+
La règle '${ruleName}' n'existe pas dans '${importMacro.depuis.nom}'.
262+
263+
[ Solution ]
264+
- Vérifiez que le nom de la règle est correct.
265+
- Assurez-vous que la règle '${ruleName}' existe dans '${importMacro.depuis.nom}'.`)
230266
}
231267

232268
const getUpdatedRule = (ruleName: RuleName, rule: Rule) => {

source/index.ts src/index.ts

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

source/serializeParsedRules.ts src/serializeParsedRules.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { RawRule, RuleName } from './commons'
44
type SerializedRule = RawRule | number | string | null
55

66
function serializedRuleToRawRule(serializedRule: SerializedRule): RawRule {
7-
if (typeof serializedRule === 'object') {
7+
if (serializedRule !== null && typeof serializedRule === 'object') {
88
return serializedRule
99
}
1010
return {

test/compilation/getModelFromSource.test.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getModelFromSource } from '../../source/compilation/getModelFromSource'
1+
import { getModelFromSource } from '../../src/compilation/getModelFromSource'
22
import { join, resolve } from 'path'
33

44
const testDataDir = resolve('./test/compilation/data/')
@@ -158,7 +158,12 @@ Ajout d'une description`,
158158
expect(() => {
159159
getModelFromSource(join(testDataDir, 'unknown-import.publicodes'))
160160
}).toThrow(
161-
"La règle 'root . unknown' n'existe pas dans my-external-package",
161+
`[ Erreur dans la macro 'importer!' ]
162+
La règle 'root . unknown' n'existe pas dans 'my-external-package'.
163+
164+
[ Solution ]
165+
- Vérifiez que le nom de la règle est correct.
166+
- Assurez-vous que la règle 'root . unknown' existe dans 'my-external-package'.`,
162167
)
163168
})
164169

@@ -167,7 +172,20 @@ Ajout d'une description`,
167172
expect(() => {
168173
getModelFromSource(path)
169174
}).toThrow(
170-
`Le nom du package est manquant dans la macro 'importer!' dans le fichier: ${path}`,
175+
`[ Erreur dans la macro 'importer!' ]
176+
Le nom du package est manquant dans la macro 'importer!' dans le fichier: no-name-import.publicodes.
177+
178+
[ Solution ]
179+
Ajoutez le nom du package dans la macro 'importer!'.
180+
181+
[ Exemple ]
182+
importer!:
183+
depuis:
184+
nom: package-name
185+
les règles:
186+
- ruleA
187+
- ruleB
188+
...`,
171189
)
172190
})
173191

test/migration/migrateSituation.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { migrateSituation } from '../../source/migration/migrateSituation'
1+
import { migrateSituation } from '../../src/migration/migrateSituation'
22

33
const migrationInstructions = {
44
keysToMigrate: { age: 'âge', 'année de naissance': '' },

test/optims/constantFolding.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Engine, { RuleNode } from 'publicodes'
2-
import { serializeParsedRules } from '../../source'
3-
import { RuleName, RawRules, disabledLogger } from '../../source/commons'
4-
import { constantFolding } from '../../source/optims/'
2+
import { serializeParsedRules } from '../../src'
3+
import { RuleName, RawRules, disabledLogger } from '../../src/commons'
4+
import { constantFolding } from '../../src/optims/'
55
import { callWithEngine } from '../utils.test'
66

77
function constantFoldingWith(rawRules: any, targets?: RuleName[]): RawRules {

test/parseExpression.test.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import {
2-
serializeParsedExprAST,
3-
substituteInParsedExpr,
4-
} from '../source/commons'
1+
import { serializeParsedExprAST, substituteInParsedExpr } from '../src/commons'
52

63
describe('substituteInParsedExpr', () => {
74
it('should return the same parsed expression if no occurence of the variable is found', () => {

test/serializeParsedRules.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Engine from 'publicodes'
2-
import { serializeParsedRules } from '../source/index'
2+
import { serializeParsedRules } from '../src/index'
33

44
describe('API > mecanisms list', () => {
55
it('should serialize empty rules', () => {

test/utils.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RuleName, disabledLogger } from '../source/commons'
1+
import { RuleName, disabledLogger } from '../src/commons'
22
import Engine from 'publicodes'
33
import type { ParsedRules } from 'publicodes'
44

tsconfig.json

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
11
{
22
"compilerOptions": {
33
"target": "esnext",
4-
"moduleResolution": "node",
5-
"allowSyntheticDefaultImports": true,
6-
"forceConsistentCasingInFileNames": true,
7-
"resolveJsonModule": true,
4+
"rootDir": "src",
85
"outDir": "dist",
9-
"rootDir": "source",
10-
"types": ["node", "jest"],
116
"esModuleInterop": true,
12-
"allowJs": true,
13-
"lib": ["es2021"],
7+
"module": "esnext",
8+
"moduleResolution": "node",
9+
"resolveJsonModule": true,
1410
"sourceMap": true,
11+
"types": ["jest", "node"],
1512
"declaration": true,
13+
"forceConsistentCasingInFileNames": true,
14+
"allowSyntheticDefaultImports": true,
1615
},
17-
"ts-node": {
18-
"transpileOnly": true,
19-
"files": true,
20-
},
21-
"include": ["source/**/*.ts"],
16+
"include": ["src"],
2217
"exclude": ["./node_modules/", "./dist/", "./jest.config.js", "./test/"],
2318
}

typedoc.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
{
22
"$schema": "https://typedoc.org/schema.json",
33
"name": "@publicodes/tools API",
4-
"entryPoints": [
5-
"./source",
6-
"./source/optims/",
7-
"./source/compilation/",
8-
"./source/migration"
9-
],
4+
"entryPoints": ["./src", "./src/optims/", "./src/compilation/"],
105
"navigationLinks": {
116
"GitHub": "https://github.com/publicodes/tools"
127
},

0 commit comments

Comments
 (0)