@aeriajs/compiler 0.0.31 → 0.0.32

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 CHANGED
@@ -1,4 +1,4 @@
1
- import type { Property, AccessCondition, CollectionActions, SearchOptions, DescriptionPreset, Icon, OwnershipMode, Layout, LayoutOptions, FormLayout, Description, FormLayoutField } from '@aeriajs/types';
1
+ import type { Property, AccessCondition, CollectionActions, SearchOptions, DescriptionPreset, Icon, OwnershipMode, Layout, LayoutOptions, FormLayout, Description, FormLayoutField, RequiredProperties } from '@aeriajs/types';
2
2
  import type { ArrayProperties } from './utils.js';
3
3
  export declare const LOCATION_SYMBOL: unique symbol;
4
4
  export declare const PropertyType: {
@@ -34,7 +34,7 @@ export type FormLayoutNode = NodeBase<'formLayout'> & FormLayout<Description> &
34
34
  field: FormLayoutField<Description>;
35
35
  };
36
36
  };
37
- terms?: [string, symbol][];
37
+ terms?: readonly [string, symbol][];
38
38
  };
39
39
  };
40
40
  export type PropertyNode = NodeBase<'property'> & {
@@ -56,6 +56,7 @@ export type PropertyNode = NodeBase<'property'> & {
56
56
  export type CollectionNode = NodeBase<'collection'> & {
57
57
  name: string;
58
58
  extends?: ExportSymbol;
59
+ middlewares?: readonly string[];
59
60
  owned?: OwnershipMode;
60
61
  icon?: Icon;
61
62
  actions?: CollectionActions;
@@ -64,13 +65,13 @@ export type CollectionNode = NodeBase<'collection'> & {
64
65
  functions?: Record<string, {
65
66
  accessCondition: AccessCondition;
66
67
  }>;
67
- required?: Record<string, unknown> | string[];
68
- indexes?: string[];
68
+ required?: RequiredProperties;
69
+ indexes?: readonly string[];
69
70
  presets?: DescriptionPreset[];
70
- form?: string[];
71
- table?: string[];
72
- tableMeta?: string[];
73
- filters?: string[];
71
+ form?: readonly string[];
72
+ table?: readonly string[];
73
+ tableMeta?: readonly string[];
74
+ filters?: readonly string[];
74
75
  search?: SearchOptions<any>;
75
76
  layout?: LayoutNode;
76
77
  formLayout?: FormLayoutNode;
@@ -78,6 +79,7 @@ export type CollectionNode = NodeBase<'collection'> & {
78
79
  arrays: {
79
80
  [P in ArrayProperties<CollectionNode>]?: symbol[];
80
81
  };
82
+ requiredTerms?: readonly [string, symbol][];
81
83
  };
82
84
  };
83
85
  export type ContractNode = NodeBase<'contract'> & {
@@ -11,7 +11,7 @@ const generateJSCollections = (ast) => {
11
11
  const importsResult = (0, utils_js_1.makeASTImports)(ast, {
12
12
  [utils_js_1.PACKAGE_NAME]: new Set(initialImportedFunctions),
13
13
  });
14
- javascriptCode += importsResult.code + '\n\n';
14
+ javascriptCode += importsResult.code.join('\n') + '\n\n';
15
15
  javascriptCode += makeJSCollections(ast, importsResult.modifiedSymbols) + '\n\n';
16
16
  return javascriptCode;
17
17
  };
@@ -37,8 +37,10 @@ const makeJSCollections = (ast, modifiedSymbols) => {
37
37
  };
38
38
  const makeJSCollectionSchema = (collectionNode, collectionId) => {
39
39
  const collectionSchema = {
40
+ item: {},
40
41
  description: {
41
42
  $id: collectionId,
43
+ properties: {},
42
44
  },
43
45
  };
44
46
  for (const key of Object.keys(collectionNode)) {
@@ -52,6 +54,11 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
52
54
  case 'owned':
53
55
  collectionSchema.description[key] = collectionNode[key];
54
56
  break;
57
+ case 'middlewares':
58
+ collectionSchema.middlewares = {
59
+ [utils_js_1.UnquotedSymbol]: `[ ${collectionNode[key].join(', ')} ]`,
60
+ };
61
+ break;
55
62
  case 'functions':
56
63
  collectionSchema.functions = {
57
64
  [utils_js_1.UnquotedSymbol]: `{ ${makeJSFunctions(collectionNode[key])} }`,
@@ -9,7 +9,7 @@ export const generateJSCollections = (ast) => {
9
9
  const importsResult = makeASTImports(ast, {
10
10
  [PACKAGE_NAME]: new Set(initialImportedFunctions)
11
11
  });
12
- javascriptCode += importsResult.code + "\n\n";
12
+ javascriptCode += importsResult.code.join("\n") + "\n\n";
13
13
  javascriptCode += makeJSCollections(ast, importsResult.modifiedSymbols) + "\n\n";
14
14
  return javascriptCode;
15
15
  };
@@ -30,8 +30,10 @@ const makeJSCollections = (ast, modifiedSymbols) => {
30
30
  };
31
31
  const makeJSCollectionSchema = (collectionNode, collectionId) => {
32
32
  const collectionSchema = {
33
+ item: {},
33
34
  description: {
34
- $id: collectionId
35
+ $id: collectionId,
36
+ properties: {}
35
37
  }
36
38
  };
37
39
  for (const key of Object.keys(collectionNode)) {
@@ -45,6 +47,11 @@ const makeJSCollectionSchema = (collectionNode, collectionId) => {
45
47
  case "owned":
46
48
  collectionSchema.description[key] = collectionNode[key];
47
49
  break;
50
+ case "middlewares":
51
+ collectionSchema.middlewares = {
52
+ [UnquotedSymbol]: `[ ${collectionNode[key].join(", ")} ]`
53
+ };
54
+ break;
48
55
  case "functions":
49
56
  collectionSchema.functions = {
50
57
  [UnquotedSymbol]: `{ ${makeJSFunctions(collectionNode[key])} }`
@@ -12,7 +12,7 @@ const generateTSCollections = (ast) => {
12
12
  let code = '';
13
13
  code += `import type { ${initialImportedTypes.join(', ')} } from '${utils_js_1.PACKAGE_NAME}'\n`; //Used types
14
14
  const importsResult = (0, utils_js_1.makeASTImports)(ast);
15
- code += importsResult.code + '\n\n';
15
+ code += importsResult.code.join('\n') + '\n\n';
16
16
  code += makeTSCollections(ast, importsResult.modifiedSymbols) + '\n';
17
17
  return code;
18
18
  };
@@ -49,8 +49,10 @@ const makeTSCollections = (ast, modifiedSymbols) => {
49
49
  };
50
50
  const makeTSCollectionSchema = (collectionNode, collectionId) => {
51
51
  const collectionSchema = {
52
+ item: {},
52
53
  description: {
53
54
  $id: collectionId,
55
+ properties: {},
54
56
  },
55
57
  };
56
58
  for (const key of Object.keys(collectionNode)) {
@@ -11,7 +11,7 @@ export const generateTSCollections = (ast) => {
11
11
  code += `import type { ${initialImportedTypes.join(", ")} } from '${PACKAGE_NAME}'
12
12
  `;
13
13
  const importsResult = makeASTImports(ast);
14
- code += importsResult.code + "\n\n";
14
+ code += importsResult.code.join("\n") + "\n\n";
15
15
  code += makeTSCollections(ast, importsResult.modifiedSymbols) + "\n";
16
16
  return code;
17
17
  };
@@ -44,8 +44,10 @@ const makeTSCollections = (ast, modifiedSymbols) => {
44
44
  };
45
45
  const makeTSCollectionSchema = (collectionNode, collectionId) => {
46
46
  const collectionSchema = {
47
+ item: {},
47
48
  description: {
48
- $id: collectionId
49
+ $id: collectionId,
50
+ properties: {}
49
51
  }
50
52
  };
51
53
  for (const key of Object.keys(collectionNode)) {
@@ -1,6 +1,7 @@
1
1
  import type * as AST from '../ast.js';
2
2
  import type { Property } from '@aeriajs/types';
3
3
  export declare const PACKAGE_NAME = "aeria";
4
+ export declare const MIDDLEWARES_RUNTIME_PATH = "../../../dist/middlewares/index.js";
4
5
  export declare const DEFAULT_FUNCTIONS: string[];
5
6
  export declare const ArraySymbol: unique symbol;
6
7
  export declare const getExposedFunctions: (astFunctions: NonNullable<AST.CollectionNode["functions"]>) => {
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getExtendName = exports.getCollectionId = exports.resizeFirstChar = exports.stringify = exports.UnquotedSymbol = exports.recursivelyUnwrapPropertyNodes = exports.unwrapPropertyNode = exports.unwrapNode = exports.makeASTImports = exports.getExposedFunctions = exports.ArraySymbol = exports.DEFAULT_FUNCTIONS = exports.PACKAGE_NAME = void 0;
3
+ exports.getExtendName = exports.getCollectionId = exports.resizeFirstChar = exports.stringify = exports.UnquotedSymbol = exports.recursivelyUnwrapPropertyNodes = exports.unwrapPropertyNode = exports.unwrapNode = exports.makeASTImports = exports.getExposedFunctions = exports.ArraySymbol = exports.DEFAULT_FUNCTIONS = exports.MIDDLEWARES_RUNTIME_PATH = exports.PACKAGE_NAME = void 0;
4
4
  exports.PACKAGE_NAME = 'aeria';
5
+ exports.MIDDLEWARES_RUNTIME_PATH = '../../../dist/middlewares/index.js';
5
6
  exports.DEFAULT_FUNCTIONS = [
6
7
  'count',
7
8
  'get',
@@ -39,14 +40,18 @@ const makeASTImports = (ast, initialImports) => {
39
40
  if (node.functions) {
40
41
  const functionsToImport = Object.keys(node.functions).filter((key) => exports.DEFAULT_FUNCTIONS.includes(key));
41
42
  if (functionsToImport.length > 0) {
42
- if (!(exports.PACKAGE_NAME in imports)) {
43
- imports[exports.PACKAGE_NAME] = new Set();
44
- }
43
+ imports[exports.PACKAGE_NAME] ??= new Set();
45
44
  for (const key of functionsToImport) {
46
45
  imports[exports.PACKAGE_NAME].add(key);
47
46
  }
48
47
  }
49
48
  }
49
+ if (node.middlewares) {
50
+ imports[exports.MIDDLEWARES_RUNTIME_PATH] ??= new Set();
51
+ for (const middleware of node.middlewares) {
52
+ imports[exports.MIDDLEWARES_RUNTIME_PATH].add(middleware);
53
+ }
54
+ }
50
55
  }
51
56
  return imports;
52
57
  }, initialImports ?? {});
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  export const PACKAGE_NAME = "aeria";
3
+ export const MIDDLEWARES_RUNTIME_PATH = "../../../dist/middlewares/index.mjs";
3
4
  export const DEFAULT_FUNCTIONS = [
4
5
  "count",
5
6
  "get",
@@ -33,14 +34,18 @@ export const makeASTImports = (ast, initialImports) => {
33
34
  if (node.functions) {
34
35
  const functionsToImport = Object.keys(node.functions).filter((key) => DEFAULT_FUNCTIONS.includes(key));
35
36
  if (functionsToImport.length > 0) {
36
- if (!(PACKAGE_NAME in imports)) {
37
- imports[PACKAGE_NAME] = /* @__PURE__ */ new Set();
38
- }
37
+ imports[PACKAGE_NAME] ??= /* @__PURE__ */ new Set();
39
38
  for (const key of functionsToImport) {
40
39
  imports[PACKAGE_NAME].add(key);
41
40
  }
42
41
  }
43
42
  }
43
+ if (node.middlewares) {
44
+ imports[MIDDLEWARES_RUNTIME_PATH] ??= /* @__PURE__ */ new Set();
45
+ for (const middleware of node.middlewares) {
46
+ imports[MIDDLEWARES_RUNTIME_PATH].add(middleware);
47
+ }
48
+ }
44
49
  }
45
50
  return imports;
46
51
  }, initialImports ?? {});
package/dist/lexer.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type Token } from './token.js';
2
2
  import { Diagnostic } from './diagnostic.js';
3
- export declare const COLLECTION_KEYWORDS: readonly ["actions", "additionalProperties", "filters", "form", "formLayout", "functions", "icon", "indexes", "individualActions", "layout", "owned", "presets", "properties", "required", "search", "table", "tableMeta"];
3
+ export declare const COLLECTION_KEYWORDS: readonly ["actions", "additionalProperties", "filters", "form", "formLayout", "functions", "icon", "indexes", "individualActions", "layout", "middlewares", "owned", "presets", "properties", "required", "search", "table", "tableMeta"];
4
4
  export declare const COLLECTION_ACTIONS_KEYWORDS: readonly ["ask", "button", "clearItem", "effect", "event", "fetchItem", "function", "icon", "label", "params", "query", "requires", "roles", "route", "selection", "setItem", "translate"];
5
5
  export declare const COLLECTION_SEARCH_KEYWORDS: readonly ["indexes", "placeholder", "exactMatches"];
6
6
  export declare const COLLECTION_LAYOUT_KEYWORDS: readonly ["name", "options"];
package/dist/lexer.js CHANGED
@@ -14,6 +14,7 @@ exports.COLLECTION_KEYWORDS = [
14
14
  'indexes',
15
15
  'individualActions',
16
16
  'layout',
17
+ 'middlewares',
17
18
  'owned',
18
19
  'presets',
19
20
  'properties',
@@ -338,7 +339,7 @@ const tokenize = function (rawInput) {
338
339
  break;
339
340
  }
340
341
  case token_js_1.TokenType.RightParens: {
341
- if (state.variableScopeStack.length > 0) {
342
+ if (state.variableExpressionStack.length > 0) {
342
343
  state.variableExpressionStack.pop();
343
344
  }
344
345
  break;
package/dist/lexer.mjs CHANGED
@@ -12,6 +12,7 @@ export const COLLECTION_KEYWORDS = [
12
12
  "indexes",
13
13
  "individualActions",
14
14
  "layout",
15
+ "middlewares",
15
16
  "owned",
16
17
  "presets",
17
18
  "properties",
@@ -341,7 +342,7 @@ export const tokenize = function(rawInput) {
341
342
  break;
342
343
  }
343
344
  case TokenType.RightParens: {
344
- if (state.variableScopeStack.length > 0) {
345
+ if (state.variableExpressionStack.length > 0) {
345
346
  state.variableExpressionStack.pop();
346
347
  }
347
348
  break;
package/dist/parser.d.ts CHANGED
@@ -3,7 +3,7 @@ import { Diagnostic } from './diagnostic.js';
3
3
  import * as AST from './ast.js';
4
4
  export declare const locationMap: WeakMap<symbol, Location>;
5
5
  export declare const memoTable: {
6
- roles?: string[];
6
+ roles?: readonly string[];
7
7
  };
8
8
  export declare const parse: (tokens: (Token | undefined)[]) => {
9
9
  ast: AST.ProgramNode;
package/dist/parser.js CHANGED
@@ -189,23 +189,20 @@ const parse = (tokens) => {
189
189
  symbols,
190
190
  };
191
191
  };
192
- const parseArrayBlockWithAttributes = () => {
192
+ const parseArrayBlockWithAttributes = (allowedAttributes, cb) => {
193
193
  const array = {};
194
194
  let hasAttributes = false;
195
195
  consume(token_js_1.TokenType.LeftBracket);
196
196
  while (!match(token_js_1.TokenType.RightBracket)) {
197
197
  const { value: identifier } = consume(token_js_1.TokenType.Identifier);
198
- array[identifier] = {};
199
- while (match(token_js_1.TokenType.AttributeName)) {
198
+ array[identifier] = true;
199
+ if (match(token_js_1.TokenType.AttributeName)) {
200
200
  hasAttributes = true;
201
- const { value: attributeName } = consume(token_js_1.TokenType.AttributeName);
202
- if (match(token_js_1.TokenType.LeftParens)) {
203
- consume(token_js_1.TokenType.LeftParens);
204
- consume(token_js_1.TokenType.RightParens);
205
- }
206
- else {
207
- array[identifier][attributeName] = true;
208
- }
201
+ }
202
+ while (match(token_js_1.TokenType.AttributeName)) {
203
+ array[identifier] = {};
204
+ const { value: attributeName } = consume(token_js_1.TokenType.AttributeName, allowedAttributes);
205
+ cb(attributeName, array, identifier);
209
206
  }
210
207
  }
211
208
  consume(token_js_1.TokenType.RightBracket);
@@ -679,6 +676,10 @@ const parse = (tokens) => {
679
676
  const { value: keyword } = consume(token_js_1.TokenType.Keyword, lexer.COLLECTION_KEYWORDS);
680
677
  try {
681
678
  switch (keyword) {
679
+ case 'middlewares': {
680
+ node.middlewares = parseArrayBlock().value;
681
+ break;
682
+ }
682
683
  case 'owned': {
683
684
  if (match(token_js_1.TokenType.Boolean)) {
684
685
  node.owned = consume(token_js_1.TokenType.Boolean).value;
@@ -710,7 +711,19 @@ const parse = (tokens) => {
710
711
  break;
711
712
  }
712
713
  case 'required': {
713
- node.required = parseArrayBlockWithAttributes();
714
+ node.required = parseArrayBlockWithAttributes(['if'], (attributeName, array, identifier) => {
715
+ switch (attributeName) {
716
+ /* eslint-disable-next-line */
717
+ case 'if': {
718
+ consume(token_js_1.TokenType.LeftParens);
719
+ const ifTerms = [];
720
+ array[identifier] = parseCondition(ifTerms);
721
+ node[AST.LOCATION_SYMBOL].requiredTerms = ifTerms;
722
+ consume(token_js_1.TokenType.RightParens);
723
+ break;
724
+ }
725
+ }
726
+ });
714
727
  break;
715
728
  }
716
729
  case 'presets': {
@@ -812,6 +825,7 @@ const parse = (tokens) => {
812
825
  }
813
826
  Object.assign(functions, functionset.functions);
814
827
  consume(token_js_1.TokenType.RightParens);
828
+ break;
815
829
  }
816
830
  }
817
831
  continue;
@@ -1223,7 +1237,7 @@ const parse = (tokens) => {
1223
1237
  operator = 'lt';
1224
1238
  break;
1225
1239
  default: {
1226
- throw new diagnostic_js_1.Diagnostic(`unsuported operator: "${operatorSymbol}"`, location);
1240
+ throw new diagnostic_js_1.Diagnostic(`unsupported operator: "${operatorSymbol}"`, location);
1227
1241
  }
1228
1242
  }
1229
1243
  return {
package/dist/parser.mjs CHANGED
@@ -151,22 +151,20 @@ export const parse = (tokens) => {
151
151
  symbols
152
152
  };
153
153
  };
154
- const parseArrayBlockWithAttributes = () => {
154
+ const parseArrayBlockWithAttributes = (allowedAttributes, cb) => {
155
155
  const array = {};
156
156
  let hasAttributes = false;
157
157
  consume(TokenType.LeftBracket);
158
158
  while (!match(TokenType.RightBracket)) {
159
159
  const { value: identifier } = consume(TokenType.Identifier);
160
- array[identifier] = {};
161
- while (match(TokenType.AttributeName)) {
160
+ array[identifier] = true;
161
+ if (match(TokenType.AttributeName)) {
162
162
  hasAttributes = true;
163
- const { value: attributeName } = consume(TokenType.AttributeName);
164
- if (match(TokenType.LeftParens)) {
165
- consume(TokenType.LeftParens);
166
- consume(TokenType.RightParens);
167
- } else {
168
- array[identifier][attributeName] = true;
169
- }
163
+ }
164
+ while (match(TokenType.AttributeName)) {
165
+ array[identifier] = {};
166
+ const { value: attributeName } = consume(TokenType.AttributeName, allowedAttributes);
167
+ cb(attributeName, array, identifier);
170
168
  }
171
169
  }
172
170
  consume(TokenType.RightBracket);
@@ -625,6 +623,10 @@ export const parse = (tokens) => {
625
623
  const { value: keyword } = consume(TokenType.Keyword, lexer.COLLECTION_KEYWORDS);
626
624
  try {
627
625
  switch (keyword) {
626
+ case "middlewares": {
627
+ node.middlewares = parseArrayBlock().value;
628
+ break;
629
+ }
628
630
  case "owned": {
629
631
  if (match(TokenType.Boolean)) {
630
632
  node.owned = consume(TokenType.Boolean).value;
@@ -655,7 +657,18 @@ export const parse = (tokens) => {
655
657
  break;
656
658
  }
657
659
  case "required": {
658
- node.required = parseArrayBlockWithAttributes();
660
+ node.required = parseArrayBlockWithAttributes(["if"], (attributeName, array, identifier) => {
661
+ switch (attributeName) {
662
+ case "if": {
663
+ consume(TokenType.LeftParens);
664
+ const ifTerms = [];
665
+ array[identifier] = parseCondition(ifTerms);
666
+ node[AST.LOCATION_SYMBOL].requiredTerms = ifTerms;
667
+ consume(TokenType.RightParens);
668
+ break;
669
+ }
670
+ }
671
+ });
659
672
  break;
660
673
  }
661
674
  case "presets": {
@@ -755,6 +768,7 @@ export const parse = (tokens) => {
755
768
  }
756
769
  Object.assign(functions, functionset.functions);
757
770
  consume(TokenType.RightParens);
771
+ break;
758
772
  }
759
773
  }
760
774
  continue;
@@ -1159,7 +1173,7 @@ export const parse = (tokens) => {
1159
1173
  operator = "lt";
1160
1174
  break;
1161
1175
  default: {
1162
- throw new Diagnostic(`unsuported operator: "${operatorSymbol}"`, location);
1176
+ throw new Diagnostic(`unsupported operator: "${operatorSymbol}"`, location);
1163
1177
  }
1164
1178
  }
1165
1179
  return {
package/dist/semantic.js CHANGED
@@ -140,6 +140,14 @@ const analyze = async (ast, options, errors = []) => {
140
140
  const subNode = node.properties[propName];
141
141
  await recurseProperty(subNode);
142
142
  }
143
+ if (node[AST.LOCATION_SYMBOL].requiredTerms) {
144
+ for (const [name, symbol] of node[AST.LOCATION_SYMBOL].requiredTerms) {
145
+ if (!(name in node.properties)) {
146
+ const location = parser_js_1.locationMap.get(symbol);
147
+ errors.push(new diagnostic_js_1.Diagnostic(`invalid left operand "${name}"`, location));
148
+ }
149
+ }
150
+ }
143
151
  if (node.layout) {
144
152
  if (node.layout.options) {
145
153
  for (const [name, value] of Object.entries(node.layout[AST.LOCATION_SYMBOL].options)) {
package/dist/semantic.mjs CHANGED
@@ -103,6 +103,14 @@ export const analyze = async (ast, options, errors = []) => {
103
103
  const subNode = node.properties[propName];
104
104
  await recurseProperty(subNode);
105
105
  }
106
+ if (node[AST.LOCATION_SYMBOL].requiredTerms) {
107
+ for (const [name, symbol] of node[AST.LOCATION_SYMBOL].requiredTerms) {
108
+ if (!(name in node.properties)) {
109
+ const location = locationMap.get(symbol);
110
+ errors.push(new Diagnostic(`invalid left operand "${name}"`, location));
111
+ }
112
+ }
113
+ }
106
114
  if (node.layout) {
107
115
  if (node.layout.options) {
108
116
  for (const [name, value] of Object.entries(node.layout[AST.LOCATION_SYMBOL].options)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aeriajs/compiler",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -21,8 +21,8 @@
21
21
  "dist"
22
22
  ],
23
23
  "peerDependencies": {
24
- "@aeriajs/common": "^0.0.142",
25
- "@aeriajs/types": "^0.0.124"
24
+ "@aeriajs/common": "^0.0.143",
25
+ "@aeriajs/types": "^0.0.125"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@aeriajs/common": "link:../common",