ondc-code-generator 0.0.1
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/.idea/code-generator.iml +12 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/custom-loader.js +4 -0
- package/dist/Generator/config-compiler.js +53 -0
- package/dist/Generator/config-validator.js +21 -0
- package/dist/Generator/generators/classes/abstract-generator.js +16 -0
- package/dist/Generator/generators/documentation/markdown-message-generator.js +37 -0
- package/dist/Generator/generators/documentation/md-generator.js +57 -0
- package/dist/Generator/generators/markdown-message-generator.js +25 -0
- package/dist/Generator/generators/python/py-generator.js +1 -0
- package/dist/Generator/generators/typescript/templates/json-path-utils.js +15 -0
- package/dist/Generator/generators/typescript/templates/validation-utils.js +91 -0
- package/dist/Generator/generators/typescript/ts-ast.js +50 -0
- package/dist/Generator/generators/typescript/ts-generator.js +184 -0
- package/dist/Generator/pipline.js +1 -0
- package/dist/Generator/validators/abstract-validator.js +6 -0
- package/dist/Generator/validators/config-validator.js +32 -0
- package/dist/Generator/validators/session-data-config/session-data-validator.js +35 -0
- package/dist/Generator/validators/tests-config/sub-validations.js +194 -0
- package/dist/Generator/validators/tests-config/test-list-validator.js +36 -0
- package/dist/Generator/validators/tests-config/test-validator.js +24 -0
- package/dist/Generator/validators/validation-error.js +9 -0
- package/dist/constants/operations.js +17 -0
- package/dist/constants/syntax.js +75 -0
- package/dist/index.js +39 -0
- package/dist/services/rename-later/main.js +1 -0
- package/dist/services/rename-later/parser.js +22 -0
- package/dist/services/rename-later/tokens.js +32 -0
- package/dist/services/rename-later/tokens1.js +33 -0
- package/dist/services/return-complier/ast-functions/compile-to-markdown.js +66 -0
- package/dist/services/return-complier/ast-functions/semantic-validations.js +30 -0
- package/dist/services/return-complier/ast.js +92 -0
- package/dist/services/return-complier/combined.js +7 -0
- package/dist/services/return-complier/parser.js +95 -0
- package/dist/services/return-complier/tokens.js +144 -0
- package/dist/services/schema-service.js +29 -0
- package/dist/types/build.js +1 -0
- package/dist/types/compiler-types.js +4 -0
- package/dist/types/config-types.js +1 -0
- package/dist/types/error-codes.js +1 -0
- package/dist/types/general-types.js +1 -0
- package/dist/utils/config-utils/json-schema-utils.js +91 -0
- package/dist/utils/config-utils/yaml.js +16 -0
- package/dist/utils/file-system.js +1 -0
- package/dist/utils/fs-utils.js +20 -0
- package/dist/utils/general-utils/string-utils.js +56 -0
- package/dist/utils/general-utils/test-object-utils.js +12 -0
- package/dist/utils/general-utils/validation-utils.js +21 -0
- package/dist/utils/json-path-utils/extract-string-paths.js +113 -0
- package/dist/utils/json-path-utils/paths.js +46 -0
- package/dist/utils/logger.js +41 -0
- package/docs/error-gen.md +33 -0
- package/docs/return-grammer.md +23 -0
- package/docs/sampleConfig.md +39 -0
- package/generated/L1-validations/api-tests/cancel.ts +569 -0
- package/generated/L1-validations/api-tests/confirm.ts +1162 -0
- package/generated/L1-validations/api-tests/init.ts +1063 -0
- package/generated/L1-validations/api-tests/on_cancel.ts +2069 -0
- package/generated/L1-validations/api-tests/on_confirm.ts +2219 -0
- package/generated/L1-validations/api-tests/on_init.ts +1949 -0
- package/generated/L1-validations/api-tests/on_search.ts +1574 -0
- package/generated/L1-validations/api-tests/on_select.ts +1723 -0
- package/generated/L1-validations/api-tests/on_status.ts +2221 -0
- package/generated/L1-validations/api-tests/on_update.ts +1969 -0
- package/generated/L1-validations/api-tests/search.ts +695 -0
- package/generated/L1-validations/api-tests/select.ts +994 -0
- package/generated/L1-validations/api-tests/status.ts +443 -0
- package/generated/L1-validations/api-tests/update.ts +898 -0
- package/generated/L1-validations/error.ts +64 -0
- package/generated/L1-validations/index.ts +138 -0
- package/generated/L1-validations/page/index.html +2118 -0
- package/generated/L1-validations/page/style.css +225 -0
- package/generated/L1-validations/readme.md +1779 -0
- package/generated/L1-validations/types/test-config.ts +27 -0
- package/generated/L1-validations/utils/json-path-utils.ts +17 -0
- package/generated/L1-validations/utils/validation-utils.ts +116 -0
- package/generated-structure/api-tests/search.ts +24 -0
- package/generated-structure/error.ts +0 -0
- package/generated-structure/index.ts +0 -0
- package/generated-structure/types/test-config.ts +21 -0
- package/nodemon.json +5 -0
- package/package.json +40 -0
- package/samples/build.yaml +24799 -0
- package/samples/output.md +91 -0
- package/samples/output.ts +27 -0
- package/samples/selections.json +216 -0
- package/samples/validation-config.json +3422 -0
- package/samples/x-validations.yaml +2893 -0
- package/src/constants/operations.ts +19 -0
- package/src/constants/syntax.ts +81 -0
- package/src/example.ts +25 -0
- package/src/generator/config-compiler.ts +122 -0
- package/src/generator/generators/classes/abstract-generator.ts +29 -0
- package/src/generator/generators/documentation/markdown-message-generator.ts +43 -0
- package/src/generator/generators/documentation/md-generator.ts +76 -0
- package/src/generator/generators/documentation/templates/index.mustache +36 -0
- package/src/generator/generators/documentation/templates/style.css +204 -0
- package/src/generator/generators/python/py-generator.ts +0 -0
- package/src/generator/generators/typescript/templates/api-test.mustache +7 -0
- package/src/generator/generators/typescript/templates/json-path-utils.ts +17 -0
- package/src/generator/generators/typescript/templates/schema-template.mustache +18 -0
- package/src/generator/generators/typescript/templates/test-config.mustache +28 -0
- package/src/generator/generators/typescript/templates/test-object.mustache +20 -0
- package/src/generator/generators/typescript/templates/validation-code.mustache +39 -0
- package/src/generator/generators/typescript/templates/validation-utils.ts +117 -0
- package/src/generator/generators/typescript/ts-ast.ts +72 -0
- package/src/generator/generators/typescript/ts-generator.ts +275 -0
- package/src/generator/validators/abstract-validator.ts +23 -0
- package/src/generator/validators/config-validator.ts +55 -0
- package/src/generator/validators/session-data-config/session-data-validator.ts +58 -0
- package/src/generator/validators/tests-config/sub-validations.ts +302 -0
- package/src/generator/validators/tests-config/test-list-validator.ts +59 -0
- package/src/generator/validators/tests-config/test-validator.ts +69 -0
- package/src/index.ts +2 -0
- package/src/services/return-complier/ast-functions/compile-to-markdown.ts +152 -0
- package/src/services/return-complier/ast-functions/semantic-validations.ts +44 -0
- package/src/services/return-complier/ast.ts +147 -0
- package/src/services/return-complier/combined.ts +8 -0
- package/src/services/return-complier/parser.ts +128 -0
- package/src/services/return-complier/tokens.ts +184 -0
- package/src/services/schema-service.ts +42 -0
- package/src/types/build.ts +51 -0
- package/src/types/compiler-types.ts +3 -0
- package/src/types/config-types.ts +27 -0
- package/src/types/error-codes.ts +6 -0
- package/src/types/general-types.ts +2 -0
- package/src/utils/config-utils/json-schema-utils.ts +150 -0
- package/src/utils/config-utils/yaml.ts +17 -0
- package/src/utils/fs-utils.ts +32 -0
- package/src/utils/general-utils/string-utils.ts +76 -0
- package/src/utils/general-utils/test-object-utils.ts +14 -0
- package/src/utils/general-utils/validation-utils.ts +30 -0
- package/src/utils/json-path-utils/extract-string-paths.ts +139 -0
- package/src/utils/json-path-utils/paths.ts +44 -0
- package/src/utils/logger.ts +53 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts all possible JSON paths from a given JSON Schema Draft-07.
|
|
3
|
+
*
|
|
4
|
+
* @param schema - The JSON Schema Draft-07 object.
|
|
5
|
+
* @returns An array of JSON paths as strings.
|
|
6
|
+
*/
|
|
7
|
+
export function getAllJsonPaths(schema) {
|
|
8
|
+
const paths = new Set();
|
|
9
|
+
/**
|
|
10
|
+
* Recursively traverses the JSON schema to extract paths.
|
|
11
|
+
*
|
|
12
|
+
* @param currentSchema - The current schema node being traversed.
|
|
13
|
+
* @param currentPath - The JSON path accumulated so far.
|
|
14
|
+
*/
|
|
15
|
+
function traverse(currentSchema, currentPath) {
|
|
16
|
+
if (!currentSchema)
|
|
17
|
+
return;
|
|
18
|
+
// Normalize the 'type' property to an array for consistent processing
|
|
19
|
+
const schemaTypes = Array.isArray(currentSchema.type)
|
|
20
|
+
? currentSchema.type
|
|
21
|
+
: currentSchema.type
|
|
22
|
+
? [currentSchema.type]
|
|
23
|
+
: [];
|
|
24
|
+
// Handle combinators: allOf, anyOf, oneOf
|
|
25
|
+
const combinators = ["allOf", "anyOf", "oneOf"];
|
|
26
|
+
for (const comb of combinators) {
|
|
27
|
+
if (currentSchema[comb]) {
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
for (const subSchema of currentSchema[comb]) {
|
|
30
|
+
traverse(subSchema, currentPath);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Handle 'not' by skipping as it signifies exclusion
|
|
35
|
+
if (currentSchema.not) {
|
|
36
|
+
// Skipping 'not' schemas as they represent negations
|
|
37
|
+
}
|
|
38
|
+
// If the schema is of type 'object', traverse its properties
|
|
39
|
+
if (schemaTypes.includes("object") && currentSchema.properties) {
|
|
40
|
+
for (const [propName, propSchema] of Object.entries(currentSchema.properties)) {
|
|
41
|
+
const newPath = currentPath === "$" ? `$.${propName}` : `${currentPath}.${propName}`;
|
|
42
|
+
traverse(propSchema, newPath);
|
|
43
|
+
}
|
|
44
|
+
// Handle 'additionalProperties' if it's a schema
|
|
45
|
+
if (currentSchema.additionalProperties &&
|
|
46
|
+
typeof currentSchema.additionalProperties === "object") {
|
|
47
|
+
const newPath = `${currentPath}.*`; // Using '*' to denote any additional property
|
|
48
|
+
traverse(currentSchema.additionalProperties, newPath);
|
|
49
|
+
}
|
|
50
|
+
// Handle 'patternProperties'
|
|
51
|
+
if (currentSchema.patternProperties) {
|
|
52
|
+
for (const [pattern, patternSchema] of Object.entries(currentSchema.patternProperties)) {
|
|
53
|
+
const newPath = `${currentPath}.*`; // Using '*' as a placeholder for any matching pattern
|
|
54
|
+
traverse(patternSchema, newPath);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// If the schema is of type 'array', traverse its items
|
|
59
|
+
if (schemaTypes.includes("array") && currentSchema.items) {
|
|
60
|
+
if (Array.isArray(currentSchema.items)) {
|
|
61
|
+
// Tuple validation: items is an array of schemas
|
|
62
|
+
currentSchema.items.forEach((itemSchema, index) => {
|
|
63
|
+
const newPath = `${currentPath}[*]`; // Using [*] to denote any index
|
|
64
|
+
traverse(itemSchema, newPath);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// List validation: items is a single schema
|
|
69
|
+
const newPath = `${currentPath}[*]`;
|
|
70
|
+
traverse(currentSchema.items, newPath);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Define primitive types considered as leaf nodes
|
|
74
|
+
const primitiveTypes = [
|
|
75
|
+
"string",
|
|
76
|
+
"number",
|
|
77
|
+
"integer",
|
|
78
|
+
"boolean",
|
|
79
|
+
"null",
|
|
80
|
+
];
|
|
81
|
+
// If the schema defines a primitive type, record the path
|
|
82
|
+
if (schemaTypes.some((type) => primitiveTypes.includes(type))) {
|
|
83
|
+
paths.add(currentPath);
|
|
84
|
+
}
|
|
85
|
+
// If 'enum' is present without a specific type, consider it as a leaf node
|
|
86
|
+
if (currentSchema.enum) {
|
|
87
|
+
paths.add(currentPath);
|
|
88
|
+
}
|
|
89
|
+
// If 'const' is present, consider it as a leaf node
|
|
90
|
+
if (currentSchema.const !== undefined) {
|
|
91
|
+
paths.add(currentPath);
|
|
92
|
+
}
|
|
93
|
+
// Handle cases where 'type' is not specified but 'properties' or 'items' are present
|
|
94
|
+
if (!currentSchema.type) {
|
|
95
|
+
if (currentSchema.properties) {
|
|
96
|
+
for (const [propName, propSchema] of Object.entries(currentSchema.properties)) {
|
|
97
|
+
const newPath = currentPath === "$"
|
|
98
|
+
? `$.${propName}`
|
|
99
|
+
: `${currentPath}.${propName}`;
|
|
100
|
+
traverse(propSchema, newPath);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (currentSchema.items) {
|
|
104
|
+
const newPath = `${currentPath}[*]`;
|
|
105
|
+
traverse(currentSchema.items, newPath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Initialize traversal with the root schema and the root path symbol '$'
|
|
110
|
+
traverse(schema, "$");
|
|
111
|
+
// Convert the Set to an array and return
|
|
112
|
+
return Array.from(paths);
|
|
113
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import jsonpath from "jsonpath";
|
|
2
|
+
export function isValidJsonPath(jsonPath) {
|
|
3
|
+
try {
|
|
4
|
+
jsonpath.query({}, jsonPath);
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Replaces all content inside square brackets in a JSONPath with an asterisk '*',
|
|
13
|
+
* handling nested brackets if they occur.
|
|
14
|
+
*
|
|
15
|
+
* @param jsonPath - The JSONPath string to transform.
|
|
16
|
+
* @returns The transformed JSONPath string with contents inside brackets replaced by '*'.
|
|
17
|
+
*/
|
|
18
|
+
export function replaceBracketsWithAsteriskNested(jsonPath) {
|
|
19
|
+
let result = "";
|
|
20
|
+
let i = 0;
|
|
21
|
+
while (i < jsonPath.length) {
|
|
22
|
+
if (jsonPath[i] === "[") {
|
|
23
|
+
// Start of bracketed expression
|
|
24
|
+
let bracketDepth = 1;
|
|
25
|
+
let j = i + 1;
|
|
26
|
+
while (j < jsonPath.length && bracketDepth > 0) {
|
|
27
|
+
if (jsonPath[j] === "[") {
|
|
28
|
+
bracketDepth++;
|
|
29
|
+
}
|
|
30
|
+
else if (jsonPath[j] === "]") {
|
|
31
|
+
bracketDepth--;
|
|
32
|
+
}
|
|
33
|
+
j++;
|
|
34
|
+
}
|
|
35
|
+
// Replace the content inside the brackets with '*'
|
|
36
|
+
result += "[*]";
|
|
37
|
+
i = j; // Move i to after the closing ']'
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Copy character as-is
|
|
41
|
+
result += jsonPath[i];
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import winston from "winston";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
const { combine, timestamp, printf, errors } = winston.format;
|
|
4
|
+
// Define colors for log levels and messages
|
|
5
|
+
const levelColors = {
|
|
6
|
+
error: chalk.bold.red, // Bright red for errors
|
|
7
|
+
warn: chalk.hex("#FFA500"), // Orange for warnings
|
|
8
|
+
info: chalk.blue, // Blue for information
|
|
9
|
+
debug: chalk.green, // Green for debugging
|
|
10
|
+
default: chalk.white, // Default color for others
|
|
11
|
+
};
|
|
12
|
+
const messageColors = {
|
|
13
|
+
error: chalk.redBright, // Highlight error messages
|
|
14
|
+
warn: chalk.yellowBright, // Bright yellow for warnings
|
|
15
|
+
info: chalk.cyan, // Cyan for information messages
|
|
16
|
+
debug: chalk.magentaBright, // Bright magenta for debugging
|
|
17
|
+
default: chalk.gray, // Default gray for fallback
|
|
18
|
+
};
|
|
19
|
+
// Custom log format
|
|
20
|
+
const logFormat = printf(({ level, message, timestamp, stack }) => {
|
|
21
|
+
const levelColor = levelColors[level] || levelColors.default; // Colorize level
|
|
22
|
+
const messageColor = messageColors[level] || messageColors.default; // Colorize message
|
|
23
|
+
const coloredLevel = levelColor(`[${level.toUpperCase()}]`); // Apply color to log level
|
|
24
|
+
const coloredTimestamp = chalk.dim(timestamp); // Dim timestamp
|
|
25
|
+
const coloredMessage = messageColor(message); // Apply message-specific color
|
|
26
|
+
const coloredStack = stack ? chalk.dim(stack) : ""; // Dim stack trace if present
|
|
27
|
+
return `${coloredTimestamp} ${coloredLevel}: ${coloredMessage} ${coloredStack}`;
|
|
28
|
+
});
|
|
29
|
+
// Determine log level based on environment
|
|
30
|
+
const logLevel = process.env.NODE_ENV === "production" ? "info" : "debug";
|
|
31
|
+
// Configure Winston logger
|
|
32
|
+
const logger = winston.createLogger({
|
|
33
|
+
level: logLevel,
|
|
34
|
+
format: combine(timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), errors({ stack: true }), // Include stack trace in error messages
|
|
35
|
+
logFormat),
|
|
36
|
+
transports: [
|
|
37
|
+
// Console transport with colorized output
|
|
38
|
+
new winston.transports.Console(),
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
export default logger;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!-- request failed the api requirements:
|
|
2
|
+
|
|
3
|
+
- **Api Condition** all of the following sub conditions must be met _(condition1 **and** condition2)_:
|
|
4
|
+
|
|
5
|
+
- **condition 1**: none of the "context.action" should be one of ['null']
|
|
6
|
+
- **condition 2**: any one of the sub conditions must be met (condition 2.1 or condition 2.2):
|
|
7
|
+
|
|
8
|
+
- **condition 2.1**: all of "ids" must be unique
|
|
9
|
+
- **condition 2.2**: categories must follow all regex in :['^\\w+$']
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
> _**Note**_: the **api condition** can be skipped if any of the skip conditions are met
|
|
14
|
+
>
|
|
15
|
+
> - **Skip Condition**:
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
**Search** api condtions:
|
|
21
|
+
|
|
22
|
+
all of the following sub conditions must pass as per the api specifications:
|
|
23
|
+
|
|
24
|
+
- **condition 1**: none of the "context.action" should be one of ['null']
|
|
25
|
+
- **condition 2**: any one of the sub conditions must be met (condition 2.1 or condition 2.2):
|
|
26
|
+
|
|
27
|
+
- **condition 2.1**: all of "ids" must be unique
|
|
28
|
+
- **condition 2.2**: categories must follow all regex in :['^\\w+$']
|
|
29
|
+
|
|
30
|
+
> _**Note**_: the **api condition** can be skipped if any of the skip conditions
|
|
31
|
+
> are met
|
|
32
|
+
>
|
|
33
|
+
> - **Skip Condition**:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#### **Grammar in EBNF:**
|
|
2
|
+
|
|
3
|
+
```ebnf
|
|
4
|
+
Expression ::= OrExpression
|
|
5
|
+
|
|
6
|
+
OrExpression ::= AndExpression ( '||' AndExpression )*
|
|
7
|
+
|
|
8
|
+
AndExpression ::= NotExpression ( '&&' NotExpression )*
|
|
9
|
+
|
|
10
|
+
NotExpression ::= '!'? PrimaryExpression
|
|
11
|
+
|
|
12
|
+
PrimaryExpression ::= '(' Expression ')' | BinaryFunctionExpression | UnaryFunctionExpression
|
|
13
|
+
|
|
14
|
+
BinaryFunctionExpression ::= Identifier BinaryFunction ( Identifier )
|
|
15
|
+
|
|
16
|
+
UnaryFunctionExpression ::= Identifier UnaryFunction
|
|
17
|
+
|
|
18
|
+
BinaryFunction ::= 'all in' | 'none in' | 'follow regex'
|
|
19
|
+
|
|
20
|
+
UnaryFunction ::= 'are unique'
|
|
21
|
+
|
|
22
|
+
Identifier ::= /* as defined in the lexer */
|
|
23
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
```
|
|
2
|
+
{
|
|
3
|
+
"search": {
|
|
4
|
+
"_SESSION_DATA_": {
|
|
5
|
+
"transId" : $.json.path,
|
|
6
|
+
"constValue": ["value"]
|
|
7
|
+
"some_external_var": null, // to make config believe something with this name will be instered after the code is generated
|
|
8
|
+
},
|
|
9
|
+
"_TESTS_": {
|
|
10
|
+
{
|
|
11
|
+
"_NAME_": "any-name",
|
|
12
|
+
"_SCOPE_": "$.json.path.for.array.of.object",
|
|
13
|
+
"var-names": "$.json.path.for.array.of.strings",
|
|
14
|
+
"_CONTINUE_": boolean operation using vars string
|
|
15
|
+
"_RETURN_" : a array of more test objects or boolean operation using var string
|
|
16
|
+
"_ERROR_CODE_" :
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
"_TESTS_":{
|
|
25
|
+
search: {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"_SESSION_DATA_":{
|
|
30
|
+
search: {
|
|
31
|
+
"transId" : $.json.path,
|
|
32
|
+
"constValue": ["value"]
|
|
33
|
+
"some_external_var": null, // to make config believe something with this name will be instered after the code is generated
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
// session data is combined all keys and will be null in starting
|
|
39
|
+
// and session data gets updates as the requests are recived
|