@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.
Files changed (66) hide show
  1. package/README.md +518 -0
  2. package/dungeons/array-of-object-lookup-schema.json +327 -0
  3. package/dungeons/array-of-object-lookup.js +220 -0
  4. package/dungeons/ecommerce-schema.json +462 -0
  5. package/dungeons/ecommerce.js +447 -0
  6. package/dungeons/education-schema.json +2409 -0
  7. package/dungeons/education.js +768 -0
  8. package/dungeons/fintech-schema.json +14034 -0
  9. package/dungeons/fintech.js +696 -0
  10. package/dungeons/foobar-schema.json +403 -0
  11. package/dungeons/foobar.js +296 -0
  12. package/dungeons/food-delivery-schema.json +192 -0
  13. package/dungeons/food-delivery.js +602 -0
  14. package/dungeons/food-schema.json +1152 -0
  15. package/dungeons/food.js +754 -0
  16. package/dungeons/gaming-schema.json +1270 -0
  17. package/dungeons/gaming.js +508 -0
  18. package/dungeons/insurance-application-schema.json +204 -0
  19. package/dungeons/insurance-application.js +605 -0
  20. package/dungeons/media-schema.json +906 -0
  21. package/dungeons/media.js +790 -0
  22. package/dungeons/retention-cadence-schema.json +78 -0
  23. package/dungeons/retention-cadence.js +244 -0
  24. package/dungeons/rpg-schema.json +4526 -0
  25. package/dungeons/rpg.js +919 -0
  26. package/dungeons/sanity-schema.json +255 -0
  27. package/dungeons/sanity.js +152 -0
  28. package/dungeons/sass-schema.json +1291 -0
  29. package/dungeons/sass.js +795 -0
  30. package/dungeons/scd-schema.json +919 -0
  31. package/dungeons/scd.js +277 -0
  32. package/dungeons/simple-schema.json +608 -0
  33. package/dungeons/simple.js +285 -0
  34. package/dungeons/simplest-schema.json +1418 -0
  35. package/dungeons/simplest.js +392 -0
  36. package/dungeons/social-schema.json +1118 -0
  37. package/dungeons/social.js +686 -0
  38. package/dungeons/text-generation-schema.json +3096 -0
  39. package/dungeons/text-generation.js +812 -0
  40. package/index.js +567 -0
  41. package/lib/core/config-validator.js +395 -0
  42. package/lib/core/context.js +204 -0
  43. package/lib/core/dungeon-loader.js +337 -0
  44. package/lib/core/storage.js +379 -0
  45. package/lib/generators/adspend.js +132 -0
  46. package/lib/generators/events.js +271 -0
  47. package/lib/generators/funnels.js +407 -0
  48. package/lib/generators/mirror.js +167 -0
  49. package/lib/generators/product-lookup.js +262 -0
  50. package/lib/generators/product-names.js +195 -0
  51. package/lib/generators/profiles.js +93 -0
  52. package/lib/generators/scd.js +124 -0
  53. package/lib/generators/text.js +1192 -0
  54. package/lib/orchestrators/mixpanel-sender.js +266 -0
  55. package/lib/orchestrators/user-loop.js +335 -0
  56. package/lib/templates/abbreviated.d.ts +169 -0
  57. package/lib/templates/defaults.js +1405 -0
  58. package/lib/templates/phrases.js +2526 -0
  59. package/lib/templates/schema.d.ts +173 -0
  60. package/lib/templates/soup-presets.js +188 -0
  61. package/lib/utils/function-registry.js +302 -0
  62. package/lib/utils/json-evaluator.js +172 -0
  63. package/lib/utils/logger.js +34 -0
  64. package/lib/utils/utils.js +1490 -0
  65. package/package.json +89 -0
  66. 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;