@aeriajs/compiler 0.0.16 → 0.0.18
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/dist/ast.d.ts +1 -0
- package/dist/codegen/generateContracts.js +5 -5
- package/dist/codegen/generateContracts.mjs +6 -6
- package/dist/codegen/generateJSCollections.js +1 -1
- package/dist/codegen/generateJSCollections.mjs +2 -2
- package/dist/codegen/generateTSCollections.js +1 -1
- package/dist/codegen/generateTSCollections.mjs +2 -2
- package/dist/codegen/utils.d.ts +2 -2
- package/dist/codegen/utils.js +50 -21
- package/dist/codegen/utils.mjs +42 -18
- package/dist/codegen.js +1 -1
- package/dist/codegen.mjs +1 -1
- package/dist/compile.d.ts +2 -3
- package/dist/compile.js +16 -35
- package/dist/compile.mjs +15 -31
- package/dist/lexer.d.ts +1 -1
- package/dist/lexer.js +1 -0
- package/dist/lexer.mjs +1 -0
- package/dist/parser.js +22 -6
- package/dist/parser.mjs +21 -7
- package/dist/semantic.js +18 -7
- package/dist/semantic.mjs +17 -7
- package/dist/types.d.ts +1 -1
- package/package.json +3 -3
package/dist/ast.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
19
19
|
const getCodeForResponse = (responseProperty) => {
|
|
20
20
|
const { kind, modifier, ...propertyNode } = responseProperty;
|
|
21
21
|
if (!modifier) {
|
|
22
|
-
return (0, utils_js_1.stringify)((0, utils_js_1.
|
|
22
|
+
return (0, utils_js_1.stringify)((0, utils_js_1.unwrapPropertyNode)(propertyNode));
|
|
23
23
|
}
|
|
24
24
|
const modifierSymbol = responseProperty.modifier === 'Result'
|
|
25
25
|
? 'resultSchema'
|
|
@@ -27,7 +27,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
27
27
|
if (!imports.has(modifierSymbol)) {
|
|
28
28
|
imports.add(modifierSymbol);
|
|
29
29
|
}
|
|
30
|
-
return `${modifierSymbol}(${(0, utils_js_1.stringify)((0, utils_js_1.
|
|
30
|
+
return `${modifierSymbol}(${(0, utils_js_1.stringify)((0, utils_js_1.unwrapPropertyNode)(propertyNode))})`;
|
|
31
31
|
};
|
|
32
32
|
const declarations = contractAst.map((contractNode) => {
|
|
33
33
|
const { name, kind, roles, response, ...contractProperty } = contractNode;
|
|
@@ -47,7 +47,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
47
47
|
responseString = (0, utils_js_1.stringify)(getCodeForResponse(response));
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
const contractSchema = (0, utils_js_1.
|
|
50
|
+
const contractSchema = (0, utils_js_1.recursivelyUnwrapPropertyNodes)(contractProperty);
|
|
51
51
|
if (responseString) {
|
|
52
52
|
contractSchema.response = {
|
|
53
53
|
[utils_js_1.UnquotedSymbol]: responseString,
|
|
@@ -61,7 +61,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
61
61
|
return `import { ${Array.from(imports).join(', ')} } from \'aeria\'\n\n` + declarations;
|
|
62
62
|
};
|
|
63
63
|
const getResponseSchema = (response) => {
|
|
64
|
-
const responseSchema = (0, utils_js_1.
|
|
64
|
+
const responseSchema = (0, utils_js_1.unwrapPropertyNode)(response);
|
|
65
65
|
if (!response.modifier) {
|
|
66
66
|
return responseSchema;
|
|
67
67
|
}
|
|
@@ -81,7 +81,7 @@ const makeTSContractsCode = (contractAst) => {
|
|
|
81
81
|
responseSchema = getResponseSchema(contractSchema.response);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
const contractProperties = (0, utils_js_1.
|
|
84
|
+
const contractProperties = (0, utils_js_1.recursivelyUnwrapPropertyNodes)(contractSchema);
|
|
85
85
|
if (responseSchema) {
|
|
86
86
|
contractProperties.response = responseSchema;
|
|
87
87
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { errorSchema, resultSchema } from "@aeriajs/types";
|
|
3
|
-
import {
|
|
3
|
+
import { recursivelyUnwrapPropertyNodes, unwrapPropertyNode, stringify, UnquotedSymbol } from "./utils.mjs";
|
|
4
4
|
export const generateContracts = (ast) => {
|
|
5
5
|
const contractNodes = ast.filter((node) => node.kind === "contract");
|
|
6
6
|
if (contractNodes.length === 0) {
|
|
@@ -16,13 +16,13 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
16
16
|
const getCodeForResponse = (responseProperty) => {
|
|
17
17
|
const { kind, modifier, ...propertyNode } = responseProperty;
|
|
18
18
|
if (!modifier) {
|
|
19
|
-
return stringify(
|
|
19
|
+
return stringify(unwrapPropertyNode(propertyNode));
|
|
20
20
|
}
|
|
21
21
|
const modifierSymbol = responseProperty.modifier === "Result" ? "resultSchema" : "errorSchema";
|
|
22
22
|
if (!imports.has(modifierSymbol)) {
|
|
23
23
|
imports.add(modifierSymbol);
|
|
24
24
|
}
|
|
25
|
-
return `${modifierSymbol}(${stringify(
|
|
25
|
+
return `${modifierSymbol}(${stringify(unwrapPropertyNode(propertyNode))})`;
|
|
26
26
|
};
|
|
27
27
|
const declarations = contractAst.map((contractNode) => {
|
|
28
28
|
const { name, kind, roles, response, ...contractProperty } = contractNode;
|
|
@@ -41,7 +41,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
41
41
|
responseString = stringify(getCodeForResponse(response));
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
const contractSchema =
|
|
44
|
+
const contractSchema = recursivelyUnwrapPropertyNodes(contractProperty);
|
|
45
45
|
if (responseString) {
|
|
46
46
|
contractSchema.response = {
|
|
47
47
|
[UnquotedSymbol]: responseString
|
|
@@ -57,7 +57,7 @@ const makeJSContractsCode = (contractAst) => {
|
|
|
57
57
|
` + declarations;
|
|
58
58
|
};
|
|
59
59
|
const getResponseSchema = (response) => {
|
|
60
|
-
const responseSchema =
|
|
60
|
+
const responseSchema = unwrapPropertyNode(response);
|
|
61
61
|
if (!response.modifier) {
|
|
62
62
|
return responseSchema;
|
|
63
63
|
}
|
|
@@ -74,7 +74,7 @@ const makeTSContractsCode = (contractAst) => {
|
|
|
74
74
|
responseSchema = getResponseSchema(contractSchema.response);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
const contractProperties =
|
|
77
|
+
const contractProperties = recursivelyUnwrapPropertyNodes(contractSchema);
|
|
78
78
|
if (responseSchema) {
|
|
79
79
|
contractProperties.response = responseSchema;
|
|
80
80
|
}
|
|
@@ -47,7 +47,7 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
47
47
|
}
|
|
48
48
|
switch (key) {
|
|
49
49
|
case 'properties':
|
|
50
|
-
collectionSchema.description[key] = (0, utils_js_1.
|
|
50
|
+
collectionSchema.description[key] = (0, utils_js_1.recursivelyUnwrapPropertyNodes)(collectionNode[key]);
|
|
51
51
|
break;
|
|
52
52
|
case 'owned':
|
|
53
53
|
collectionSchema.description[key] = collectionNode[key];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import { makeASTImports,
|
|
2
|
+
import { makeASTImports, recursivelyUnwrapPropertyNodes, stringify, getExtendName, getCollectionId, UnquotedSymbol, getExposedFunctions, PACKAGE_NAME, DEFAULT_FUNCTIONS } from "./utils.mjs";
|
|
3
3
|
const initialImportedFunctions = [
|
|
4
4
|
"extendCollection",
|
|
5
5
|
"defineCollection"
|
|
@@ -40,7 +40,7 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
40
40
|
}
|
|
41
41
|
switch (key) {
|
|
42
42
|
case "properties":
|
|
43
|
-
collectionSchema.description[key] =
|
|
43
|
+
collectionSchema.description[key] = recursivelyUnwrapPropertyNodes(collectionNode[key]);
|
|
44
44
|
break;
|
|
45
45
|
case "owned":
|
|
46
46
|
collectionSchema.description[key] = collectionNode[key];
|
|
@@ -59,7 +59,7 @@ const makeTSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
59
59
|
}
|
|
60
60
|
switch (key) {
|
|
61
61
|
case 'properties':
|
|
62
|
-
collectionSchema.description.properties = (0, utils_js_1.
|
|
62
|
+
collectionSchema.description.properties = (0, utils_js_1.recursivelyUnwrapPropertyNodes)(collectionNode[key]);
|
|
63
63
|
break;
|
|
64
64
|
case 'owned':
|
|
65
65
|
collectionSchema.description.owned = collectionNode[key];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import {
|
|
2
|
+
import { recursivelyUnwrapPropertyNodes, stringify, makeASTImports, resizeFirstChar, getCollectionId, UnquotedSymbol, getExposedFunctions, PACKAGE_NAME, DEFAULT_FUNCTIONS } from "./utils.mjs";
|
|
3
3
|
const initialImportedTypes = [
|
|
4
4
|
"Collection",
|
|
5
5
|
"SchemaWithId",
|
|
@@ -54,7 +54,7 @@ const makeTSCollectionSchema = (collectionNode, collectionId) => {
|
|
|
54
54
|
}
|
|
55
55
|
switch (key) {
|
|
56
56
|
case "properties":
|
|
57
|
-
collectionSchema.description.properties =
|
|
57
|
+
collectionSchema.description.properties = recursivelyUnwrapPropertyNodes(collectionNode[key]);
|
|
58
58
|
break;
|
|
59
59
|
case "owned":
|
|
60
60
|
collectionSchema.description.owned = collectionNode[key];
|
package/dist/codegen/utils.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ export declare const makeASTImports: (ast: AST.Node[], initialImports?: Record<s
|
|
|
13
13
|
code: string[];
|
|
14
14
|
modifiedSymbols: Record<string, string>;
|
|
15
15
|
};
|
|
16
|
-
export declare const
|
|
16
|
+
export declare const unwrapPropertyNode: ({ property, nestedProperties, nestedAdditionalProperties }: Pick<AST.PropertyNode, "property" | "nestedProperties" | "nestedAdditionalProperties">) => Property;
|
|
17
17
|
/** Transforms the AST properties to the format of aeria schema properties */
|
|
18
|
-
export declare const
|
|
18
|
+
export declare const recursivelyUnwrapPropertyNodes: <TProperties extends Record<string, AST.PropertyNode | AST.PropertyNode[]>, TReturnType = TProperties[keyof TProperties] extends Array<unknown> ? Record<string, Property[]> : Record<string, Property>>(properties: TProperties) => TReturnType;
|
|
19
19
|
export declare const UnquotedSymbol: unique symbol;
|
|
20
20
|
/** Serves to know if the value must be unquoted on strinfigy function */
|
|
21
21
|
export type StringifyProperty = unknown | {
|
package/dist/codegen/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getExtendName = exports.getCollectionId = exports.resizeFirstChar = exports.stringify = exports.UnquotedSymbol = exports.
|
|
3
|
+
exports.getExtendName = exports.getCollectionId = exports.resizeFirstChar = exports.stringify = exports.UnquotedSymbol = exports.recursivelyUnwrapPropertyNodes = exports.unwrapPropertyNode = exports.makeASTImports = exports.getExposedFunctions = exports.ArraySymbol = exports.DEFAULT_FUNCTIONS = exports.PACKAGE_NAME = void 0;
|
|
4
4
|
exports.PACKAGE_NAME = 'aeria';
|
|
5
5
|
exports.DEFAULT_FUNCTIONS = [
|
|
6
6
|
'count',
|
|
@@ -55,41 +55,70 @@ const makeASTImports = (ast, initialImports) => {
|
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
57
|
exports.makeASTImports = makeASTImports;
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
const unwrapPropertyNode = ({ property, nestedProperties, nestedAdditionalProperties }) => {
|
|
59
|
+
const propertyOrPropertyItems = 'items' in property
|
|
60
|
+
? property.items
|
|
61
|
+
: property;
|
|
62
|
+
let unwrappedProperty = propertyOrPropertyItems;
|
|
63
|
+
if ('$ref' in propertyOrPropertyItems) {
|
|
64
|
+
unwrappedProperty = {
|
|
65
|
+
...propertyOrPropertyItems,
|
|
66
|
+
$ref: (0, exports.getCollectionId)(propertyOrPropertyItems.$ref),
|
|
67
|
+
};
|
|
62
68
|
}
|
|
63
|
-
else if ('
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
else if ('type' in propertyOrPropertyItems && propertyOrPropertyItems.type === 'object') {
|
|
70
|
+
let properties;
|
|
71
|
+
let additionalProperties;
|
|
72
|
+
if (nestedProperties) {
|
|
73
|
+
properties = (0, exports.recursivelyUnwrapPropertyNodes)(nestedProperties);
|
|
74
|
+
}
|
|
75
|
+
if (nestedAdditionalProperties) {
|
|
76
|
+
additionalProperties = typeof nestedAdditionalProperties === 'boolean'
|
|
77
|
+
? nestedAdditionalProperties
|
|
78
|
+
: (0, exports.unwrapPropertyNode)(nestedAdditionalProperties);
|
|
79
|
+
}
|
|
80
|
+
if (properties && additionalProperties) {
|
|
81
|
+
unwrappedProperty = {
|
|
82
|
+
...propertyOrPropertyItems,
|
|
83
|
+
properties,
|
|
84
|
+
additionalProperties,
|
|
85
|
+
};
|
|
69
86
|
}
|
|
70
|
-
else if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
properties
|
|
87
|
+
else if (properties) {
|
|
88
|
+
unwrappedProperty = {
|
|
89
|
+
...propertyOrPropertyItems,
|
|
90
|
+
properties,
|
|
74
91
|
};
|
|
75
92
|
}
|
|
93
|
+
else if (additionalProperties) {
|
|
94
|
+
unwrappedProperty = {
|
|
95
|
+
...propertyOrPropertyItems,
|
|
96
|
+
additionalProperties,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if ('items' in property) {
|
|
101
|
+
return {
|
|
102
|
+
...property,
|
|
103
|
+
items: unwrappedProperty,
|
|
104
|
+
};
|
|
76
105
|
}
|
|
77
|
-
return
|
|
106
|
+
return unwrappedProperty;
|
|
78
107
|
};
|
|
79
|
-
exports.
|
|
108
|
+
exports.unwrapPropertyNode = unwrapPropertyNode;
|
|
80
109
|
/** Transforms the AST properties to the format of aeria schema properties */
|
|
81
|
-
const
|
|
110
|
+
const recursivelyUnwrapPropertyNodes = (properties) => {
|
|
82
111
|
return Object.entries(properties).reduce((acc, [key, value]) => {
|
|
83
112
|
if (Array.isArray(value)) {
|
|
84
|
-
acc[key] = value.map((propertyNode) => (0, exports.
|
|
113
|
+
acc[key] = value.map((propertyNode) => (0, exports.unwrapPropertyNode)(propertyNode));
|
|
85
114
|
}
|
|
86
115
|
else {
|
|
87
|
-
acc[key] = (0, exports.
|
|
116
|
+
acc[key] = (0, exports.unwrapPropertyNode)(value);
|
|
88
117
|
}
|
|
89
118
|
return acc;
|
|
90
119
|
}, {});
|
|
91
120
|
};
|
|
92
|
-
exports.
|
|
121
|
+
exports.recursivelyUnwrapPropertyNodes = recursivelyUnwrapPropertyNodes;
|
|
93
122
|
exports.UnquotedSymbol = Symbol('unquoted');
|
|
94
123
|
const isRecord = (value) => typeof value === 'object';
|
|
95
124
|
/** Assure if specific fields needs to be between quotes or not */
|
package/dist/codegen/utils.mjs
CHANGED
|
@@ -48,31 +48,55 @@ export const makeASTImports = (ast, initialImports) => {
|
|
|
48
48
|
modifiedSymbols
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
|
-
export const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
51
|
+
export const unwrapPropertyNode = ({ property, nestedProperties, nestedAdditionalProperties }) => {
|
|
52
|
+
const propertyOrPropertyItems = "items" in property ? property.items : property;
|
|
53
|
+
let unwrappedProperty = propertyOrPropertyItems;
|
|
54
|
+
if ("$ref" in propertyOrPropertyItems) {
|
|
55
|
+
unwrappedProperty = {
|
|
56
|
+
...propertyOrPropertyItems,
|
|
57
|
+
$ref: getCollectionId(propertyOrPropertyItems.$ref)
|
|
58
|
+
};
|
|
59
|
+
} else if ("type" in propertyOrPropertyItems && propertyOrPropertyItems.type === "object") {
|
|
60
|
+
let properties;
|
|
61
|
+
let additionalProperties;
|
|
62
|
+
if (nestedProperties) {
|
|
63
|
+
properties = recursivelyUnwrapPropertyNodes(nestedProperties);
|
|
64
|
+
}
|
|
65
|
+
if (nestedAdditionalProperties) {
|
|
66
|
+
additionalProperties = typeof nestedAdditionalProperties === "boolean" ? nestedAdditionalProperties : unwrapPropertyNode(nestedAdditionalProperties);
|
|
67
|
+
}
|
|
68
|
+
if (properties && additionalProperties) {
|
|
69
|
+
unwrappedProperty = {
|
|
70
|
+
...propertyOrPropertyItems,
|
|
71
|
+
properties,
|
|
72
|
+
additionalProperties
|
|
73
|
+
};
|
|
74
|
+
} else if (properties) {
|
|
75
|
+
unwrappedProperty = {
|
|
76
|
+
...propertyOrPropertyItems,
|
|
77
|
+
properties
|
|
78
|
+
};
|
|
79
|
+
} else if (additionalProperties) {
|
|
80
|
+
unwrappedProperty = {
|
|
81
|
+
...propertyOrPropertyItems,
|
|
82
|
+
additionalProperties
|
|
65
83
|
};
|
|
66
84
|
}
|
|
67
85
|
}
|
|
68
|
-
|
|
86
|
+
if ("items" in property) {
|
|
87
|
+
return {
|
|
88
|
+
...property,
|
|
89
|
+
items: unwrappedProperty
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return unwrappedProperty;
|
|
69
93
|
};
|
|
70
|
-
export const
|
|
94
|
+
export const recursivelyUnwrapPropertyNodes = (properties) => {
|
|
71
95
|
return Object.entries(properties).reduce((acc, [key, value]) => {
|
|
72
96
|
if (Array.isArray(value)) {
|
|
73
|
-
acc[key] = value.map((propertyNode) =>
|
|
97
|
+
acc[key] = value.map((propertyNode) => unwrapPropertyNode(propertyNode));
|
|
74
98
|
} else {
|
|
75
|
-
acc[key] =
|
|
99
|
+
acc[key] = unwrapPropertyNode(value);
|
|
76
100
|
}
|
|
77
101
|
return acc;
|
|
78
102
|
}, {});
|
package/dist/codegen.js
CHANGED
|
@@ -51,7 +51,7 @@ const path = __importStar(require("node:path"));
|
|
|
51
51
|
* ['outDir/folderX/folderY/file']: ...
|
|
52
52
|
* }
|
|
53
53
|
*/
|
|
54
|
-
const generateFileMap = async (fileTree, outDir) => {
|
|
54
|
+
const generateFileMap = async (fileTree, outDir = '.') => {
|
|
55
55
|
const mappedPaths = {};
|
|
56
56
|
const mapPathTree = async (tree, previousPath) => {
|
|
57
57
|
for (const treePath in tree) {
|
package/dist/codegen.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { generateContracts, generateExports, generateJSCollections, generateTSCollections } from "./codegen/index.mjs";
|
|
3
3
|
import * as fsPromises from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
const generateFileMap = async (fileTree, outDir) => {
|
|
5
|
+
const generateFileMap = async (fileTree, outDir = ".") => {
|
|
6
6
|
const mappedPaths = {};
|
|
7
7
|
const mapPathTree = async (tree, previousPath) => {
|
|
8
8
|
for (const treePath in tree) {
|
package/dist/compile.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { CompilationOptions, CompilationResult } from './types.js';
|
|
2
2
|
import { Diagnostic } from './diagnostic.js';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const GLOB_PATTERN = "**/*.aeria";
|
|
4
4
|
export declare const parseAndCheck: (sources: Record<string, string>, options?: Pick<CompilationOptions, "languageServer">) => Promise<CompilationResult>;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const compileFromFiles: (globPattern: string, options: CompilationOptions) => Promise<CompilationResult | {
|
|
5
|
+
export declare const compileFromFiles: (options: CompilationOptions) => Promise<CompilationResult | {
|
|
7
6
|
emittedFiles: Record<string, string>;
|
|
8
7
|
success: boolean;
|
|
9
8
|
ast?: import("./ast.js").ProgramNode;
|
package/dist/compile.js
CHANGED
|
@@ -33,18 +33,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.compileFromFiles = exports.
|
|
36
|
+
exports.compileFromFiles = exports.parseAndCheck = exports.GLOB_PATTERN = void 0;
|
|
37
37
|
const diagnostic_js_1 = require("./diagnostic.js");
|
|
38
38
|
const lexer_js_1 = require("./lexer.js");
|
|
39
39
|
const parser_js_1 = require("./parser.js");
|
|
40
40
|
const semantic_js_1 = require("./semantic.js");
|
|
41
41
|
const codegen_js_1 = require("./codegen.js");
|
|
42
|
-
const path = __importStar(require("node:path"));
|
|
43
42
|
const fs = __importStar(require("node:fs"));
|
|
44
|
-
exports.
|
|
43
|
+
exports.GLOB_PATTERN = '**/*.aeria';
|
|
45
44
|
const parseAndCheck = async (sources, options = {}) => {
|
|
46
45
|
const errors = [];
|
|
47
|
-
let ast;
|
|
48
46
|
const allTokens = [];
|
|
49
47
|
for (const fileName in sources) {
|
|
50
48
|
diagnostic_js_1.Diagnostic.currentFile = fileName;
|
|
@@ -54,8 +52,8 @@ const parseAndCheck = async (sources, options = {}) => {
|
|
|
54
52
|
}
|
|
55
53
|
allTokens.push(...tokens);
|
|
56
54
|
}
|
|
57
|
-
const { errors: parserErrors, ast
|
|
58
|
-
const { errors: semanticErrors } = await (0, semantic_js_1.analyze)(
|
|
55
|
+
const { errors: parserErrors, ast } = (0, parser_js_1.parse)(allTokens);
|
|
56
|
+
const { errors: semanticErrors } = await (0, semantic_js_1.analyze)(ast, options);
|
|
59
57
|
errors.push(...parserErrors.concat(semanticErrors));
|
|
60
58
|
return {
|
|
61
59
|
success: errors.length === 0,
|
|
@@ -65,31 +63,11 @@ const parseAndCheck = async (sources, options = {}) => {
|
|
|
65
63
|
};
|
|
66
64
|
};
|
|
67
65
|
exports.parseAndCheck = parseAndCheck;
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
for (const dir of directories) {
|
|
71
|
-
await fs.promises.mkdir(dir, {
|
|
72
|
-
recursive: true,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
return directories;
|
|
76
|
-
};
|
|
77
|
-
exports.generateScaffolding = generateScaffolding;
|
|
78
|
-
const compileFromFiles = async (globPattern, options) => {
|
|
79
|
-
const fileList = await Array.fromAsync(fs.promises.glob(globPattern));
|
|
80
|
-
const sortedFileList = fileList.sort((a, b) => {
|
|
81
|
-
const aIndex = exports.FILE_PRECEDENCE.findIndex((file) => a.split('/').at(-1).startsWith(file));
|
|
82
|
-
const bIndex = exports.FILE_PRECEDENCE.findIndex((file) => b.split('/').at(-1).startsWith(file));
|
|
83
|
-
if (!~aIndex && !~bIndex) {
|
|
84
|
-
return 1;
|
|
85
|
-
}
|
|
86
|
-
return aIndex > bIndex
|
|
87
|
-
? 1
|
|
88
|
-
: -1;
|
|
89
|
-
});
|
|
66
|
+
const compileFromFiles = async (options) => {
|
|
67
|
+
const fileList = await Array.fromAsync(fs.promises.glob(exports.GLOB_PATTERN));
|
|
90
68
|
const sources = {};
|
|
91
|
-
for (const
|
|
92
|
-
sources[
|
|
69
|
+
for (const fileName of fileList) {
|
|
70
|
+
sources[fileName] = await fs.promises.readFile(fileName, {
|
|
93
71
|
encoding: 'utf-8',
|
|
94
72
|
});
|
|
95
73
|
}
|
|
@@ -97,10 +75,13 @@ const compileFromFiles = async (globPattern, options) => {
|
|
|
97
75
|
if (!result.ast || result.errorCount > 0) {
|
|
98
76
|
return result;
|
|
99
77
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
78
|
+
if (options.outDir) {
|
|
79
|
+
const emittedFiles = await (0, codegen_js_1.generateCode)(result.ast, options);
|
|
80
|
+
return {
|
|
81
|
+
...result,
|
|
82
|
+
emittedFiles,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
105
86
|
};
|
|
106
87
|
exports.compileFromFiles = compileFromFiles;
|
package/dist/compile.mjs
CHANGED
|
@@ -4,12 +4,10 @@ import { tokenize } from "./lexer.mjs";
|
|
|
4
4
|
import { parse } from "./parser.mjs";
|
|
5
5
|
import { analyze } from "./semantic.mjs";
|
|
6
6
|
import { generateCode } from "./codegen.mjs";
|
|
7
|
-
import * as path from "node:path";
|
|
8
7
|
import * as fs from "node:fs";
|
|
9
|
-
export const
|
|
8
|
+
export const GLOB_PATTERN = "**/*.aeria";
|
|
10
9
|
export const parseAndCheck = async (sources, options = {}) => {
|
|
11
10
|
const errors = [];
|
|
12
|
-
let ast;
|
|
13
11
|
const allTokens = [];
|
|
14
12
|
for (const fileName in sources) {
|
|
15
13
|
Diagnostic.currentFile = fileName;
|
|
@@ -19,8 +17,8 @@ export const parseAndCheck = async (sources, options = {}) => {
|
|
|
19
17
|
}
|
|
20
18
|
allTokens.push(...tokens);
|
|
21
19
|
}
|
|
22
|
-
const { errors: parserErrors, ast
|
|
23
|
-
const { errors: semanticErrors } = await analyze(
|
|
20
|
+
const { errors: parserErrors, ast } = parse(allTokens);
|
|
21
|
+
const { errors: semanticErrors } = await analyze(ast, options);
|
|
24
22
|
errors.push(...parserErrors.concat(semanticErrors));
|
|
25
23
|
return {
|
|
26
24
|
success: errors.length === 0,
|
|
@@ -29,28 +27,11 @@ export const parseAndCheck = async (sources, options = {}) => {
|
|
|
29
27
|
ast
|
|
30
28
|
};
|
|
31
29
|
};
|
|
32
|
-
export const
|
|
33
|
-
const
|
|
34
|
-
for (const dir of directories) {
|
|
35
|
-
await fs.promises.mkdir(dir, {
|
|
36
|
-
recursive: true
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return directories;
|
|
40
|
-
};
|
|
41
|
-
export const compileFromFiles = async (globPattern, options) => {
|
|
42
|
-
const fileList = await Array.fromAsync(fs.promises.glob(globPattern));
|
|
43
|
-
const sortedFileList = fileList.sort((a, b) => {
|
|
44
|
-
const aIndex = FILE_PRECEDENCE.findIndex((file) => a.split("/").at(-1).startsWith(file));
|
|
45
|
-
const bIndex = FILE_PRECEDENCE.findIndex((file) => b.split("/").at(-1).startsWith(file));
|
|
46
|
-
if (!~aIndex && !~bIndex) {
|
|
47
|
-
return 1;
|
|
48
|
-
}
|
|
49
|
-
return aIndex > bIndex ? 1 : -1;
|
|
50
|
-
});
|
|
30
|
+
export const compileFromFiles = async (options) => {
|
|
31
|
+
const fileList = await Array.fromAsync(fs.promises.glob(GLOB_PATTERN));
|
|
51
32
|
const sources = {};
|
|
52
|
-
for (const
|
|
53
|
-
sources[
|
|
33
|
+
for (const fileName of fileList) {
|
|
34
|
+
sources[fileName] = await fs.promises.readFile(fileName, {
|
|
54
35
|
encoding: "utf-8"
|
|
55
36
|
});
|
|
56
37
|
}
|
|
@@ -58,9 +39,12 @@ export const compileFromFiles = async (globPattern, options) => {
|
|
|
58
39
|
if (!result.ast || result.errorCount > 0) {
|
|
59
40
|
return result;
|
|
60
41
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
42
|
+
if (options.outDir) {
|
|
43
|
+
const emittedFiles = await generateCode(result.ast, options);
|
|
44
|
+
return {
|
|
45
|
+
...result,
|
|
46
|
+
emittedFiles
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
66
50
|
};
|
package/dist/lexer.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Token } from './token.js';
|
|
2
2
|
import { Diagnostic } from './diagnostic.js';
|
|
3
3
|
export type Keyword = typeof COLLECTION_KEYWORDS[number] | typeof COLLECTION_ACTIONS_KEYWORDS[number] | typeof COLLECTION_SEARCH_KEYWORDS[number] | typeof CONTRACT_KEYWORDS[number] | typeof TOPLEVEL_KEYWORDS[number] | typeof MISC_KEYWORDS[number];
|
|
4
|
-
export declare const COLLECTION_KEYWORDS: readonly ["actions", "filters", "form", "functions", "icon", "indexes", "individualActions", "owned", "presets", "properties", "required", "search", "table"];
|
|
4
|
+
export declare const COLLECTION_KEYWORDS: readonly ["actions", "additionalProperties", "filters", "form", "functions", "icon", "indexes", "individualActions", "owned", "presets", "properties", "required", "search", "table"];
|
|
5
5
|
export declare const COLLECTION_ACTIONS_KEYWORDS: readonly ["ask", "button", "clearItem", "effect", "event", "fetchItem", "function", "icon", "label", "params", "query", "requires", "roles", "route", "selection", "setItem", "translate"];
|
|
6
6
|
export declare const COLLECTION_SEARCH_KEYWORDS: readonly ["indexes", "placeholder", "exactMatches"];
|
|
7
7
|
export declare const CONTRACT_KEYWORDS: readonly ["roles", "payload", "query", "response"];
|
package/dist/lexer.js
CHANGED
package/dist/lexer.mjs
CHANGED
package/dist/parser.js
CHANGED
|
@@ -378,9 +378,9 @@ const parse = (tokens) => {
|
|
|
378
378
|
}) => {
|
|
379
379
|
let property;
|
|
380
380
|
let nestedProperties;
|
|
381
|
+
let nestedAdditionalProperties;
|
|
381
382
|
let modifierToken;
|
|
382
383
|
const typeSymbol = Symbol();
|
|
383
|
-
exports.locationMap.set(typeSymbol, next().location);
|
|
384
384
|
if (match(token_js_1.TokenType.LeftSquareBracket)) {
|
|
385
385
|
consume(token_js_1.TokenType.LeftSquareBracket);
|
|
386
386
|
const arrayProperty = {
|
|
@@ -428,6 +428,7 @@ const parse = (tokens) => {
|
|
|
428
428
|
...arrayProperty,
|
|
429
429
|
items,
|
|
430
430
|
};
|
|
431
|
+
exports.locationMap.set(typeSymbol, current().location);
|
|
431
432
|
return {
|
|
432
433
|
kind: 'property',
|
|
433
434
|
property,
|
|
@@ -441,6 +442,7 @@ const parse = (tokens) => {
|
|
|
441
442
|
modifierToken = consume(token_js_1.TokenType.Identifier);
|
|
442
443
|
}
|
|
443
444
|
}
|
|
445
|
+
exports.locationMap.set(typeSymbol, current().location);
|
|
444
446
|
if (match(token_js_1.TokenType.LeftBracket)) {
|
|
445
447
|
consume(token_js_1.TokenType.LeftBracket);
|
|
446
448
|
property = {
|
|
@@ -468,6 +470,16 @@ const parse = (tokens) => {
|
|
|
468
470
|
nestedProperties = parsePropertiesBlock(options);
|
|
469
471
|
break;
|
|
470
472
|
}
|
|
473
|
+
case 'additionalProperties': {
|
|
474
|
+
consume(token_js_1.TokenType.Keyword);
|
|
475
|
+
if (match(token_js_1.TokenType.Boolean)) {
|
|
476
|
+
nestedAdditionalProperties = consume(token_js_1.TokenType.Boolean).value;
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
nestedAdditionalProperties = parsePropertyType();
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
471
483
|
default:
|
|
472
484
|
throw new diagnostic_js_1.Diagnostic(`invalid keyword "${keyword}"`, location);
|
|
473
485
|
}
|
|
@@ -544,6 +556,7 @@ const parse = (tokens) => {
|
|
|
544
556
|
kind: 'property',
|
|
545
557
|
property,
|
|
546
558
|
nestedProperties,
|
|
559
|
+
nestedAdditionalProperties,
|
|
547
560
|
};
|
|
548
561
|
if (modifierToken) {
|
|
549
562
|
node.modifier = modifierToken.value;
|
|
@@ -662,11 +675,14 @@ const parse = (tokens) => {
|
|
|
662
675
|
try {
|
|
663
676
|
switch (keyword) {
|
|
664
677
|
case 'owned': {
|
|
665
|
-
if (match(token_js_1.TokenType.
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
node.owned = consume(token_js_1.TokenType.QuotedString
|
|
678
|
+
if (match(token_js_1.TokenType.Boolean)) {
|
|
679
|
+
node.owned = consume(token_js_1.TokenType.Boolean).value;
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
node.owned = consume(token_js_1.TokenType.QuotedString, [
|
|
683
|
+
'always',
|
|
684
|
+
'on-write',
|
|
685
|
+
]).value;
|
|
670
686
|
}
|
|
671
687
|
break;
|
|
672
688
|
}
|
package/dist/parser.mjs
CHANGED
|
@@ -336,9 +336,9 @@ export const parse = (tokens) => {
|
|
|
336
336
|
}) => {
|
|
337
337
|
let property;
|
|
338
338
|
let nestedProperties;
|
|
339
|
+
let nestedAdditionalProperties;
|
|
339
340
|
let modifierToken;
|
|
340
341
|
const typeSymbol = Symbol();
|
|
341
|
-
locationMap.set(typeSymbol, next().location);
|
|
342
342
|
if (match(TokenType.LeftSquareBracket)) {
|
|
343
343
|
consume(TokenType.LeftSquareBracket);
|
|
344
344
|
const arrayProperty = {
|
|
@@ -384,6 +384,7 @@ export const parse = (tokens) => {
|
|
|
384
384
|
...arrayProperty,
|
|
385
385
|
items
|
|
386
386
|
};
|
|
387
|
+
locationMap.set(typeSymbol, current().location);
|
|
387
388
|
return {
|
|
388
389
|
kind: "property",
|
|
389
390
|
property,
|
|
@@ -397,6 +398,7 @@ export const parse = (tokens) => {
|
|
|
397
398
|
modifierToken = consume(TokenType.Identifier);
|
|
398
399
|
}
|
|
399
400
|
}
|
|
401
|
+
locationMap.set(typeSymbol, current().location);
|
|
400
402
|
if (match(TokenType.LeftBracket)) {
|
|
401
403
|
consume(TokenType.LeftBracket);
|
|
402
404
|
property = {
|
|
@@ -424,6 +426,15 @@ export const parse = (tokens) => {
|
|
|
424
426
|
nestedProperties = parsePropertiesBlock(options);
|
|
425
427
|
break;
|
|
426
428
|
}
|
|
429
|
+
case "additionalProperties": {
|
|
430
|
+
consume(TokenType.Keyword);
|
|
431
|
+
if (match(TokenType.Boolean)) {
|
|
432
|
+
nestedAdditionalProperties = consume(TokenType.Boolean).value;
|
|
433
|
+
} else {
|
|
434
|
+
nestedAdditionalProperties = parsePropertyType();
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
427
438
|
default:
|
|
428
439
|
throw new Diagnostic(`invalid keyword "${keyword}"`, location);
|
|
429
440
|
}
|
|
@@ -496,7 +507,8 @@ export const parse = (tokens) => {
|
|
|
496
507
|
const node = {
|
|
497
508
|
kind: "property",
|
|
498
509
|
property,
|
|
499
|
-
nestedProperties
|
|
510
|
+
nestedProperties,
|
|
511
|
+
nestedAdditionalProperties
|
|
500
512
|
};
|
|
501
513
|
if (modifierToken) {
|
|
502
514
|
node.modifier = modifierToken.value;
|
|
@@ -609,11 +621,13 @@ export const parse = (tokens) => {
|
|
|
609
621
|
try {
|
|
610
622
|
switch (keyword) {
|
|
611
623
|
case "owned": {
|
|
612
|
-
if (match(TokenType.
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
624
|
+
if (match(TokenType.Boolean)) {
|
|
625
|
+
node.owned = consume(TokenType.Boolean).value;
|
|
626
|
+
} else {
|
|
627
|
+
node.owned = consume(TokenType.QuotedString, [
|
|
628
|
+
"always",
|
|
629
|
+
"on-write"
|
|
630
|
+
]).value;
|
|
617
631
|
}
|
|
618
632
|
break;
|
|
619
633
|
}
|
package/dist/semantic.js
CHANGED
|
@@ -97,13 +97,18 @@ const analyze = async (ast, options, errors = []) => {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
const recurseProperty = async (node) => {
|
|
100
|
-
if (node.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
await
|
|
100
|
+
if ('type' in node.property && node.property.type === 'object') {
|
|
101
|
+
if (typeof node.nestedAdditionalProperties === 'object') {
|
|
102
|
+
await recurseProperty(node.nestedAdditionalProperties);
|
|
103
|
+
}
|
|
104
|
+
if (node.nestedProperties) {
|
|
105
|
+
await checkObjectLocalProperties(node, 'required');
|
|
106
|
+
await checkObjectLocalProperties(node, 'writable');
|
|
107
|
+
await checkObjectLocalProperties(node, 'form');
|
|
108
|
+
for (const propName in node.nestedProperties) {
|
|
109
|
+
const subProperty = node.nestedProperties[propName];
|
|
110
|
+
await recurseProperty(subProperty);
|
|
111
|
+
}
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
else if ('$ref' in node.property) {
|
|
@@ -118,6 +123,12 @@ const analyze = async (ast, options, errors = []) => {
|
|
|
118
123
|
await checkCollectionForeignProperties(foreignCollection, node.property, 'populate');
|
|
119
124
|
await checkCollectionForeignProperties(foreignCollection, node.property, 'form');
|
|
120
125
|
}
|
|
126
|
+
else if ('items' in node.property) {
|
|
127
|
+
await recurseProperty({
|
|
128
|
+
kind: 'property',
|
|
129
|
+
property: node.property.items,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
121
132
|
};
|
|
122
133
|
for (const node of ast.collections) {
|
|
123
134
|
await checkCollectionLocalProperties(node, 'indexes');
|
package/dist/semantic.mjs
CHANGED
|
@@ -62,13 +62,18 @@ export const analyze = async (ast, options, errors = []) => {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
const recurseProperty = async (node) => {
|
|
65
|
-
if (node.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
await
|
|
65
|
+
if ("type" in node.property && node.property.type === "object") {
|
|
66
|
+
if (typeof node.nestedAdditionalProperties === "object") {
|
|
67
|
+
await recurseProperty(node.nestedAdditionalProperties);
|
|
68
|
+
}
|
|
69
|
+
if (node.nestedProperties) {
|
|
70
|
+
await checkObjectLocalProperties(node, "required");
|
|
71
|
+
await checkObjectLocalProperties(node, "writable");
|
|
72
|
+
await checkObjectLocalProperties(node, "form");
|
|
73
|
+
for (const propName in node.nestedProperties) {
|
|
74
|
+
const subProperty = node.nestedProperties[propName];
|
|
75
|
+
await recurseProperty(subProperty);
|
|
76
|
+
}
|
|
72
77
|
}
|
|
73
78
|
} else if ("$ref" in node.property) {
|
|
74
79
|
const refName = node.property.$ref;
|
|
@@ -81,6 +86,11 @@ export const analyze = async (ast, options, errors = []) => {
|
|
|
81
86
|
await checkCollectionForeignProperties(foreignCollection, node.property, "indexes");
|
|
82
87
|
await checkCollectionForeignProperties(foreignCollection, node.property, "populate");
|
|
83
88
|
await checkCollectionForeignProperties(foreignCollection, node.property, "form");
|
|
89
|
+
} else if ("items" in node.property) {
|
|
90
|
+
await recurseProperty({
|
|
91
|
+
kind: "property",
|
|
92
|
+
property: node.property.items
|
|
93
|
+
});
|
|
84
94
|
}
|
|
85
95
|
};
|
|
86
96
|
for (const node of ast.collections) {
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriajs/compiler",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"keywords": [],
|