@ak--47/dungeon-master 1.0.0
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/README.md +518 -0
- package/dungeons/array-of-object-lookup-schema.json +327 -0
- package/dungeons/array-of-object-lookup.js +220 -0
- package/dungeons/ecommerce-schema.json +462 -0
- package/dungeons/ecommerce.js +447 -0
- package/dungeons/education-schema.json +2409 -0
- package/dungeons/education.js +768 -0
- package/dungeons/fintech-schema.json +14034 -0
- package/dungeons/fintech.js +696 -0
- package/dungeons/foobar-schema.json +403 -0
- package/dungeons/foobar.js +296 -0
- package/dungeons/food-delivery-schema.json +192 -0
- package/dungeons/food-delivery.js +602 -0
- package/dungeons/food-schema.json +1152 -0
- package/dungeons/food.js +754 -0
- package/dungeons/gaming-schema.json +1270 -0
- package/dungeons/gaming.js +508 -0
- package/dungeons/insurance-application-schema.json +204 -0
- package/dungeons/insurance-application.js +605 -0
- package/dungeons/media-schema.json +906 -0
- package/dungeons/media.js +790 -0
- package/dungeons/retention-cadence-schema.json +78 -0
- package/dungeons/retention-cadence.js +244 -0
- package/dungeons/rpg-schema.json +4526 -0
- package/dungeons/rpg.js +919 -0
- package/dungeons/sanity-schema.json +255 -0
- package/dungeons/sanity.js +152 -0
- package/dungeons/sass-schema.json +1291 -0
- package/dungeons/sass.js +795 -0
- package/dungeons/scd-schema.json +919 -0
- package/dungeons/scd.js +277 -0
- package/dungeons/simple-schema.json +608 -0
- package/dungeons/simple.js +285 -0
- package/dungeons/simplest-schema.json +1418 -0
- package/dungeons/simplest.js +392 -0
- package/dungeons/social-schema.json +1118 -0
- package/dungeons/social.js +686 -0
- package/dungeons/text-generation-schema.json +3096 -0
- package/dungeons/text-generation.js +812 -0
- package/index.js +567 -0
- package/lib/core/config-validator.js +395 -0
- package/lib/core/context.js +204 -0
- package/lib/core/dungeon-loader.js +337 -0
- package/lib/core/storage.js +379 -0
- package/lib/generators/adspend.js +132 -0
- package/lib/generators/events.js +271 -0
- package/lib/generators/funnels.js +407 -0
- package/lib/generators/mirror.js +167 -0
- package/lib/generators/product-lookup.js +262 -0
- package/lib/generators/product-names.js +195 -0
- package/lib/generators/profiles.js +93 -0
- package/lib/generators/scd.js +124 -0
- package/lib/generators/text.js +1192 -0
- package/lib/orchestrators/mixpanel-sender.js +266 -0
- package/lib/orchestrators/user-loop.js +335 -0
- package/lib/templates/abbreviated.d.ts +169 -0
- package/lib/templates/defaults.js +1405 -0
- package/lib/templates/phrases.js +2526 -0
- package/lib/templates/schema.d.ts +173 -0
- package/lib/templates/soup-presets.js +188 -0
- package/lib/utils/function-registry.js +302 -0
- package/lib/utils/json-evaluator.js +172 -0
- package/lib/utils/logger.js +34 -0
- package/lib/utils/utils.js +1490 -0
- package/package.json +89 -0
- package/types.d.ts +865 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Evaluator for converting JSON function call format to JavaScript
|
|
3
|
+
* Replaces the old regex-based string parsing approach
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { validateFunctionCall } from './function-registry.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Evaluate a value that might contain function calls
|
|
10
|
+
* @param {any} value - The value to evaluate (could be object with functionName, array, or primitive)
|
|
11
|
+
* @returns {string} - JavaScript code string
|
|
12
|
+
*/
|
|
13
|
+
export function evaluateValue(value) {
|
|
14
|
+
// Handle function call objects
|
|
15
|
+
if (typeof value === 'object' && value !== null && 'functionName' in value) {
|
|
16
|
+
return evaluateFunctionCall(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Handle arrays (return as-is)
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
return JSON.stringify(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Handle nested objects (recursively evaluate)
|
|
25
|
+
if (typeof value === 'object' && value !== null) {
|
|
26
|
+
const entries = Object.entries(value).map(([key, val]) => {
|
|
27
|
+
const evaluatedVal = evaluateValue(val);
|
|
28
|
+
// Use quotes for keys that need them
|
|
29
|
+
const quotedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`;
|
|
30
|
+
return `${quotedKey}: ${evaluatedVal}`;
|
|
31
|
+
});
|
|
32
|
+
return `{${entries.join(', ')}}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Handle primitives
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Evaluate a function call object to JavaScript code
|
|
41
|
+
* @param {Object} funcCall - Object with functionName and args/body
|
|
42
|
+
* @returns {string} - JavaScript function call string
|
|
43
|
+
*/
|
|
44
|
+
export function evaluateFunctionCall(funcCall) {
|
|
45
|
+
if (!validateFunctionCall(funcCall)) {
|
|
46
|
+
throw new Error(`Invalid function call: ${JSON.stringify(funcCall)}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { functionName, args, body } = funcCall;
|
|
50
|
+
|
|
51
|
+
// Special handling for arrow functions
|
|
52
|
+
if (functionName === 'arrow') {
|
|
53
|
+
return `() => ${body}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Handle chance.* functions
|
|
57
|
+
if (functionName.startsWith('chance.')) {
|
|
58
|
+
const method = functionName.split('.')[1];
|
|
59
|
+
if (!args || args.length === 0) {
|
|
60
|
+
return `chance.${method}.bind(chance)`;
|
|
61
|
+
} else if (args.length === 1 && typeof args[0] === 'object') {
|
|
62
|
+
// For methods that take an options object
|
|
63
|
+
return `() => chance.${method}(${JSON.stringify(args[0])})`;
|
|
64
|
+
} else {
|
|
65
|
+
// For methods with regular arguments
|
|
66
|
+
const argsStr = args.map(arg => evaluateValue(arg)).join(', ');
|
|
67
|
+
return `() => chance.${method}(${argsStr})`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Handle regular functions
|
|
72
|
+
if (!args || args.length === 0) {
|
|
73
|
+
return `${functionName}()`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Evaluate each argument
|
|
77
|
+
const evaluatedArgs = args.map(arg => {
|
|
78
|
+
// If arg is an object with functionName, evaluate it as a function call
|
|
79
|
+
if (typeof arg === 'object' && arg !== null && 'functionName' in arg) {
|
|
80
|
+
return evaluateFunctionCall(arg);
|
|
81
|
+
}
|
|
82
|
+
// For primitive values (strings, numbers, booleans), use JSON.stringify
|
|
83
|
+
// but strings need special handling to avoid double-escaping
|
|
84
|
+
if (typeof arg === 'string') {
|
|
85
|
+
return `"${arg}"`;
|
|
86
|
+
}
|
|
87
|
+
// For other primitives and arrays, use JSON.stringify
|
|
88
|
+
return JSON.stringify(arg);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return `${functionName}(${evaluatedArgs.join(', ')})`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Convert a complete dungeon config from JSON to JavaScript
|
|
96
|
+
* @param {Object} config - The dungeon configuration object
|
|
97
|
+
* @returns {Object} - Configuration with function strings
|
|
98
|
+
*/
|
|
99
|
+
export function convertDungeonConfig(config) {
|
|
100
|
+
const converted = {};
|
|
101
|
+
|
|
102
|
+
for (const [key, value] of Object.entries(config)) {
|
|
103
|
+
// Skip certain keys that shouldn't be processed
|
|
104
|
+
if (key === 'seed' || key === 'name' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') {
|
|
105
|
+
converted[key] = value;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Special handling for groupKeys - preserve as array of arrays
|
|
110
|
+
if (key === 'groupKeys' && Array.isArray(value)) {
|
|
111
|
+
converted[key] = value;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Process arrays of objects (like events)
|
|
116
|
+
if (Array.isArray(value)) {
|
|
117
|
+
converted[key] = value.map(item => {
|
|
118
|
+
if (typeof item === 'object' && item !== null) {
|
|
119
|
+
return processConfigObject(item);
|
|
120
|
+
}
|
|
121
|
+
return item;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// Process objects
|
|
125
|
+
else if (typeof value === 'object' && value !== null) {
|
|
126
|
+
converted[key] = processConfigObject(value);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
converted[key] = value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return converted;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Process a configuration object, converting function calls
|
|
138
|
+
* @param {Object} obj - Object to process
|
|
139
|
+
* @returns {Object} - Processed object
|
|
140
|
+
*/
|
|
141
|
+
function processConfigObject(obj) {
|
|
142
|
+
const processed = {};
|
|
143
|
+
|
|
144
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
145
|
+
// Check if this is a function call
|
|
146
|
+
if (typeof value === 'object' && value !== null && 'functionName' in value) {
|
|
147
|
+
// Store as string for the JS file generation
|
|
148
|
+
processed[key] = evaluateFunctionCall(value);
|
|
149
|
+
}
|
|
150
|
+
// Process nested arrays
|
|
151
|
+
else if (Array.isArray(value)) {
|
|
152
|
+
processed[key] = value.map(item => {
|
|
153
|
+
if (typeof item === 'object' && item !== null && 'functionName' in item) {
|
|
154
|
+
return evaluateFunctionCall(item);
|
|
155
|
+
}
|
|
156
|
+
if (typeof item === 'object' && item !== null) {
|
|
157
|
+
return processConfigObject(item);
|
|
158
|
+
}
|
|
159
|
+
return item;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Process nested objects
|
|
163
|
+
else if (typeof value === 'object' && value !== null) {
|
|
164
|
+
processed[key] = processConfigObject(value);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
processed[key] = value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return processed;
|
|
172
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logger using Pino
|
|
3
|
+
*
|
|
4
|
+
* Pretty-printed in development, JSON in production for Cloud Run
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import pino from 'pino';
|
|
8
|
+
|
|
9
|
+
const isDev = process.env.NODE_ENV !== 'production';
|
|
10
|
+
const isTest = process.env.NODE_ENV === 'test';
|
|
11
|
+
|
|
12
|
+
// Create the logger with appropriate transport
|
|
13
|
+
// In production, use 'message' instead of 'msg' for GCP Cloud Logging compatibility
|
|
14
|
+
const logger = pino({
|
|
15
|
+
level: process.env.LOG_LEVEL || (isTest ? 'silent' : isDev ? 'warn' : 'info'),
|
|
16
|
+
// Use 'message' instead of 'msg' for GCP Cloud Logging
|
|
17
|
+
messageKey: isDev ? 'msg' : 'message',
|
|
18
|
+
transport: isDev
|
|
19
|
+
? {
|
|
20
|
+
target: 'pino-pretty',
|
|
21
|
+
options: {
|
|
22
|
+
colorize: true,
|
|
23
|
+
translateTime: 'HH:MM:ss.l',
|
|
24
|
+
ignore: 'pid,hostname',
|
|
25
|
+
messageFormat: '{msg}',
|
|
26
|
+
errorLikeObjectKeys: ['err', 'error']
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
: undefined // JSON output in production for Cloud Run
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const dataLogger = logger.child({ component: 'data' });
|
|
33
|
+
|
|
34
|
+
export default logger;
|