@gxp-dev/tools 2.0.63 → 2.0.64
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 +32 -31
- package/bin/gx-devtools.js +74 -54
- package/bin/lib/cli.js +23 -21
- package/bin/lib/commands/add-dependency.js +366 -325
- package/bin/lib/commands/assets.js +137 -139
- package/bin/lib/commands/build.js +169 -174
- package/bin/lib/commands/datastore.js +181 -183
- package/bin/lib/commands/dev.js +127 -131
- package/bin/lib/commands/extensions.js +147 -149
- package/bin/lib/commands/extract-config.js +73 -67
- package/bin/lib/commands/index.js +12 -12
- package/bin/lib/commands/init.js +342 -240
- package/bin/lib/commands/publish.js +69 -75
- package/bin/lib/commands/socket.js +69 -69
- package/bin/lib/commands/ssl.js +14 -14
- package/bin/lib/constants.js +10 -24
- package/bin/lib/tui/App.tsx +761 -705
- package/bin/lib/tui/components/AIPanel.tsx +191 -171
- package/bin/lib/tui/components/CommandInput.tsx +394 -343
- package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
- package/bin/lib/tui/components/Header.tsx +23 -21
- package/bin/lib/tui/components/LogPanel.tsx +244 -220
- package/bin/lib/tui/components/TabBar.tsx +50 -48
- package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
- package/bin/lib/tui/index.tsx +37 -39
- package/bin/lib/tui/services/AIService.ts +518 -462
- package/bin/lib/tui/services/ExtensionService.ts +140 -129
- package/bin/lib/tui/services/GeminiService.ts +367 -337
- package/bin/lib/tui/services/ServiceManager.ts +344 -322
- package/bin/lib/tui/services/SocketService.ts +168 -168
- package/bin/lib/tui/services/ViteService.ts +88 -88
- package/bin/lib/tui/services/index.ts +47 -22
- package/bin/lib/utils/ai-scaffold.js +291 -280
- package/bin/lib/utils/extract-config.js +157 -140
- package/bin/lib/utils/files.js +82 -86
- package/bin/lib/utils/index.js +7 -7
- package/bin/lib/utils/paths.js +34 -34
- package/bin/lib/utils/prompts.js +194 -169
- package/bin/lib/utils/ssl.js +79 -81
- package/browser-extensions/README.md +0 -1
- package/browser-extensions/chrome/background.js +244 -237
- package/browser-extensions/chrome/content.js +32 -29
- package/browser-extensions/chrome/devtools.html +7 -7
- package/browser-extensions/chrome/devtools.js +19 -19
- package/browser-extensions/chrome/inspector.js +802 -767
- package/browser-extensions/chrome/manifest.json +71 -63
- package/browser-extensions/chrome/panel.html +674 -636
- package/browser-extensions/chrome/panel.js +722 -712
- package/browser-extensions/chrome/popup.html +586 -543
- package/browser-extensions/chrome/popup.js +282 -244
- package/browser-extensions/chrome/rules.json +1 -1
- package/browser-extensions/chrome/test-chrome.html +216 -136
- package/browser-extensions/chrome/test-mixed-content.html +284 -189
- package/browser-extensions/chrome/test-uri-pattern.html +221 -198
- package/browser-extensions/firefox/README.md +9 -6
- package/browser-extensions/firefox/background.js +221 -218
- package/browser-extensions/firefox/content.js +55 -52
- package/browser-extensions/firefox/debug-errors.html +386 -228
- package/browser-extensions/firefox/debug-https.html +153 -105
- package/browser-extensions/firefox/devtools.html +7 -7
- package/browser-extensions/firefox/devtools.js +23 -20
- package/browser-extensions/firefox/inspector.js +802 -767
- package/browser-extensions/firefox/manifest.json +68 -68
- package/browser-extensions/firefox/panel.html +674 -636
- package/browser-extensions/firefox/panel.js +722 -712
- package/browser-extensions/firefox/popup.html +572 -535
- package/browser-extensions/firefox/popup.js +281 -236
- package/browser-extensions/firefox/test-gramercy.html +170 -125
- package/browser-extensions/firefox/test-imports.html +59 -55
- package/browser-extensions/firefox/test-masking.html +231 -140
- package/browser-extensions/firefox/test-uri-pattern.html +221 -198
- package/dist/tui/App.d.ts +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +154 -150
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/AIPanel.d.ts.map +1 -1
- package/dist/tui/components/AIPanel.js +42 -35
- package/dist/tui/components/AIPanel.js.map +1 -1
- package/dist/tui/components/CommandInput.d.ts +1 -1
- package/dist/tui/components/CommandInput.d.ts.map +1 -1
- package/dist/tui/components/CommandInput.js +92 -62
- package/dist/tui/components/CommandInput.js.map +1 -1
- package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
- package/dist/tui/components/GeminiPanel.js +37 -30
- package/dist/tui/components/GeminiPanel.js.map +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +1 -1
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/LogPanel.d.ts +1 -1
- package/dist/tui/components/LogPanel.d.ts.map +1 -1
- package/dist/tui/components/LogPanel.js +26 -24
- package/dist/tui/components/LogPanel.js.map +1 -1
- package/dist/tui/components/TabBar.d.ts +2 -2
- package/dist/tui/components/TabBar.d.ts.map +1 -1
- package/dist/tui/components/TabBar.js +11 -11
- package/dist/tui/components/TabBar.js.map +1 -1
- package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
- package/dist/tui/components/WelcomeScreen.js +6 -6
- package/dist/tui/components/WelcomeScreen.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +8 -8
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/services/AIService.d.ts +2 -2
- package/dist/tui/services/AIService.d.ts.map +1 -1
- package/dist/tui/services/AIService.js +165 -125
- package/dist/tui/services/AIService.js.map +1 -1
- package/dist/tui/services/ExtensionService.d.ts +1 -1
- package/dist/tui/services/ExtensionService.d.ts.map +1 -1
- package/dist/tui/services/ExtensionService.js +33 -26
- package/dist/tui/services/ExtensionService.js.map +1 -1
- package/dist/tui/services/GeminiService.d.ts +1 -1
- package/dist/tui/services/GeminiService.d.ts.map +1 -1
- package/dist/tui/services/GeminiService.js +87 -76
- package/dist/tui/services/GeminiService.js.map +1 -1
- package/dist/tui/services/ServiceManager.d.ts +3 -3
- package/dist/tui/services/ServiceManager.d.ts.map +1 -1
- package/dist/tui/services/ServiceManager.js +72 -58
- package/dist/tui/services/ServiceManager.js.map +1 -1
- package/dist/tui/services/SocketService.d.ts.map +1 -1
- package/dist/tui/services/SocketService.js +32 -32
- package/dist/tui/services/SocketService.js.map +1 -1
- package/dist/tui/services/ViteService.d.ts.map +1 -1
- package/dist/tui/services/ViteService.js +26 -28
- package/dist/tui/services/ViteService.js.map +1 -1
- package/dist/tui/services/index.d.ts +6 -6
- package/dist/tui/services/index.d.ts.map +1 -1
- package/dist/tui/services/index.js +6 -6
- package/dist/tui/services/index.js.map +1 -1
- package/mcp/gxp-api-server.js +83 -81
- package/package.json +109 -93
- package/runtime/PortalContainer.vue +258 -234
- package/runtime/dev-tools/DevToolsModal.vue +153 -155
- package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
- package/runtime/dev-tools/MockDataEditor.vue +456 -433
- package/runtime/dev-tools/SocketSimulator.vue +379 -371
- package/runtime/dev-tools/StoreInspector.vue +517 -455
- package/runtime/dev-tools/index.js +5 -5
- package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
- package/runtime/fallback-layouts/PublicLayout.vue +2 -2
- package/runtime/fallback-layouts/SystemLayout.vue +2 -2
- package/runtime/gxpStringsPlugin.js +159 -134
- package/runtime/index.html +17 -19
- package/runtime/main.js +24 -22
- package/runtime/mock-api/auth-middleware.js +15 -15
- package/runtime/mock-api/image-generator.js +46 -46
- package/runtime/mock-api/index.js +55 -55
- package/runtime/mock-api/response-generator.js +116 -105
- package/runtime/mock-api/route-generator.js +107 -84
- package/runtime/mock-api/socket-triggers.js +94 -93
- package/runtime/mock-api/spec-loader.js +79 -80
- package/runtime/package.json +3 -0
- package/runtime/server.js +68 -68
- package/runtime/stores/gxpPortalConfigStore.js +204 -186
- package/runtime/stores/index.js +2 -2
- package/runtime/vite-inspector-plugin.js +858 -707
- package/runtime/vite-source-tracker-plugin.js +132 -113
- package/runtime/vite.config.js +191 -139
- package/scripts/launch-chrome.js +41 -41
- package/scripts/pack-chrome.js +38 -39
- package/socket-events/AiSessionMessageCreated.json +17 -17
- package/socket-events/SocialStreamPostCreated.json +23 -23
- package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
- package/template/.claude/agents/gxp-developer.md +100 -99
- package/template/.claude/settings.json +7 -7
- package/template/AGENTS.md +30 -23
- package/template/GEMINI.md +20 -20
- package/template/README.md +70 -53
- package/template/app-manifest.json +2 -4
- package/template/configuration.json +10 -10
- package/template/default-styling.css +1 -1
- package/template/index.html +18 -20
- package/template/main.js +24 -22
- package/template/src/DemoPage.vue +415 -362
- package/template/src/Plugin.vue +76 -85
- package/template/src/stores/index.js +3 -3
- package/template/src/stores/test-data.json +164 -172
- package/template/theme-layouts/AdditionalStyling.css +50 -50
- package/template/theme-layouts/PrivateLayout.vue +8 -12
- package/template/theme-layouts/PublicLayout.vue +8 -12
- package/template/theme-layouts/SystemLayout.vue +8 -12
- package/template/vite.extend.js +45 -0
- package/template/vite.config.js +0 -409
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* using Faker.js for realistic values.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { faker } = require("@faker-js/faker")
|
|
8
|
+
const { faker } = require("@faker-js/faker")
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Resolve a $ref reference in the spec
|
|
@@ -15,22 +15,22 @@ const { faker } = require("@faker-js/faker");
|
|
|
15
15
|
*/
|
|
16
16
|
function resolveRef(ref, spec) {
|
|
17
17
|
if (!ref || !ref.startsWith("#/")) {
|
|
18
|
-
return null
|
|
18
|
+
return null
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const parts = ref.slice(2).split("/")
|
|
22
|
-
let current = spec
|
|
21
|
+
const parts = ref.slice(2).split("/")
|
|
22
|
+
let current = spec
|
|
23
23
|
|
|
24
24
|
for (const part of parts) {
|
|
25
25
|
if (current && typeof current === "object" && part in current) {
|
|
26
|
-
current = current[part]
|
|
26
|
+
current = current[part]
|
|
27
27
|
} else {
|
|
28
|
-
console.warn(`⚠️ Could not resolve $ref: ${ref}`)
|
|
29
|
-
return null
|
|
28
|
+
console.warn(`⚠️ Could not resolve $ref: ${ref}`)
|
|
29
|
+
return null
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
return current
|
|
33
|
+
return current
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
@@ -43,37 +43,37 @@ function resolveRef(ref, spec) {
|
|
|
43
43
|
function generateValue(type, format, schema = {}) {
|
|
44
44
|
// Handle enums first
|
|
45
45
|
if (schema.enum && schema.enum.length > 0) {
|
|
46
|
-
return faker.helpers.arrayElement(schema.enum)
|
|
46
|
+
return faker.helpers.arrayElement(schema.enum)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Handle examples
|
|
50
50
|
if (schema.example !== undefined) {
|
|
51
|
-
return schema.example
|
|
51
|
+
return schema.example
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// Handle default values
|
|
55
55
|
if (schema.default !== undefined) {
|
|
56
|
-
return schema.default
|
|
56
|
+
return schema.default
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
switch (type) {
|
|
60
60
|
case "string":
|
|
61
|
-
return generateStringValue(format, schema)
|
|
61
|
+
return generateStringValue(format, schema)
|
|
62
62
|
|
|
63
63
|
case "integer":
|
|
64
|
-
return generateIntegerValue(schema)
|
|
64
|
+
return generateIntegerValue(schema)
|
|
65
65
|
|
|
66
66
|
case "number":
|
|
67
|
-
return generateNumberValue(schema)
|
|
67
|
+
return generateNumberValue(schema)
|
|
68
68
|
|
|
69
69
|
case "boolean":
|
|
70
|
-
return faker.datatype.boolean()
|
|
70
|
+
return faker.datatype.boolean()
|
|
71
71
|
|
|
72
72
|
case "null":
|
|
73
|
-
return null
|
|
73
|
+
return null
|
|
74
74
|
|
|
75
75
|
default:
|
|
76
|
-
return faker.lorem.word()
|
|
76
|
+
return faker.lorem.word()
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -86,51 +86,51 @@ function generateValue(type, format, schema = {}) {
|
|
|
86
86
|
function generateStringValue(format, schema) {
|
|
87
87
|
switch (format) {
|
|
88
88
|
case "email":
|
|
89
|
-
return faker.internet.email()
|
|
89
|
+
return faker.internet.email()
|
|
90
90
|
|
|
91
91
|
case "uuid":
|
|
92
|
-
return faker.string.uuid()
|
|
92
|
+
return faker.string.uuid()
|
|
93
93
|
|
|
94
94
|
case "uri":
|
|
95
95
|
case "url":
|
|
96
|
-
return faker.internet.url()
|
|
96
|
+
return faker.internet.url()
|
|
97
97
|
|
|
98
98
|
case "hostname":
|
|
99
|
-
return faker.internet.domainName()
|
|
99
|
+
return faker.internet.domainName()
|
|
100
100
|
|
|
101
101
|
case "ipv4":
|
|
102
|
-
return faker.internet.ipv4()
|
|
102
|
+
return faker.internet.ipv4()
|
|
103
103
|
|
|
104
104
|
case "ipv6":
|
|
105
|
-
return faker.internet.ipv6()
|
|
105
|
+
return faker.internet.ipv6()
|
|
106
106
|
|
|
107
107
|
case "date":
|
|
108
|
-
return faker.date.recent().toISOString().split("T")[0]
|
|
108
|
+
return faker.date.recent().toISOString().split("T")[0]
|
|
109
109
|
|
|
110
110
|
case "date-time":
|
|
111
|
-
return faker.date.recent().toISOString()
|
|
111
|
+
return faker.date.recent().toISOString()
|
|
112
112
|
|
|
113
113
|
case "time":
|
|
114
|
-
return faker.date.recent().toISOString().split("T")[1].split(".")[0]
|
|
114
|
+
return faker.date.recent().toISOString().split("T")[1].split(".")[0]
|
|
115
115
|
|
|
116
116
|
case "password":
|
|
117
|
-
return faker.internet.password()
|
|
117
|
+
return faker.internet.password()
|
|
118
118
|
|
|
119
119
|
case "byte":
|
|
120
|
-
return Buffer.from(faker.lorem.word()).toString("base64")
|
|
120
|
+
return Buffer.from(faker.lorem.word()).toString("base64")
|
|
121
121
|
|
|
122
122
|
case "binary":
|
|
123
|
-
return faker.string.alphanumeric(32)
|
|
123
|
+
return faker.string.alphanumeric(32)
|
|
124
124
|
|
|
125
125
|
case "phone":
|
|
126
|
-
return faker.phone.number()
|
|
126
|
+
return faker.phone.number()
|
|
127
127
|
|
|
128
128
|
case "color":
|
|
129
|
-
return faker.color.rgb()
|
|
129
|
+
return faker.color.rgb()
|
|
130
130
|
|
|
131
131
|
default:
|
|
132
132
|
// Use property name hints if available
|
|
133
|
-
return generateStringByPattern(schema)
|
|
133
|
+
return generateStringByPattern(schema)
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -140,48 +140,52 @@ function generateStringValue(format, schema) {
|
|
|
140
140
|
* @returns {string} Generated string
|
|
141
141
|
*/
|
|
142
142
|
function generateStringByPattern(schema) {
|
|
143
|
-
const name = (schema.propertyName || "").toLowerCase()
|
|
143
|
+
const name = (schema.propertyName || "").toLowerCase()
|
|
144
144
|
|
|
145
145
|
// Common field name patterns
|
|
146
146
|
if (name.includes("name")) {
|
|
147
|
-
if (name.includes("first")) return faker.person.firstName()
|
|
148
|
-
if (name.includes("last")) return faker.person.lastName()
|
|
149
|
-
if (name.includes("full")) return faker.person.fullName()
|
|
150
|
-
if (name.includes("company")) return faker.company.name()
|
|
151
|
-
return faker.person.fullName()
|
|
147
|
+
if (name.includes("first")) return faker.person.firstName()
|
|
148
|
+
if (name.includes("last")) return faker.person.lastName()
|
|
149
|
+
if (name.includes("full")) return faker.person.fullName()
|
|
150
|
+
if (name.includes("company")) return faker.company.name()
|
|
151
|
+
return faker.person.fullName()
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
if (name.includes("email")) return faker.internet.email()
|
|
154
|
+
if (name.includes("email")) return faker.internet.email()
|
|
155
155
|
if (name.includes("phone") || name.includes("mobile"))
|
|
156
|
-
return faker.phone.number()
|
|
157
|
-
if (name.includes("address")) return faker.location.streetAddress()
|
|
158
|
-
if (name.includes("city")) return faker.location.city()
|
|
159
|
-
if (name.includes("state")) return faker.location.state()
|
|
160
|
-
if (name.includes("country")) return faker.location.country()
|
|
156
|
+
return faker.phone.number()
|
|
157
|
+
if (name.includes("address")) return faker.location.streetAddress()
|
|
158
|
+
if (name.includes("city")) return faker.location.city()
|
|
159
|
+
if (name.includes("state")) return faker.location.state()
|
|
160
|
+
if (name.includes("country")) return faker.location.country()
|
|
161
161
|
if (name.includes("zip") || name.includes("postal"))
|
|
162
|
-
return faker.location.zipCode()
|
|
163
|
-
if (name.includes("url") || name.includes("link")) return faker.internet.url()
|
|
164
|
-
if (
|
|
165
|
-
|
|
162
|
+
return faker.location.zipCode()
|
|
163
|
+
if (name.includes("url") || name.includes("link")) return faker.internet.url()
|
|
164
|
+
if (
|
|
165
|
+
name.includes("image") ||
|
|
166
|
+
name.includes("avatar") ||
|
|
167
|
+
name.includes("photo")
|
|
168
|
+
)
|
|
169
|
+
return faker.image.url()
|
|
166
170
|
if (name.includes("description") || name.includes("bio"))
|
|
167
|
-
return faker.lorem.paragraph()
|
|
168
|
-
if (name.includes("title")) return faker.lorem.sentence()
|
|
169
|
-
if (name.includes("slug")) return faker.helpers.slugify(faker.lorem.words(3))
|
|
170
|
-
if (name.includes("color")) return faker.color.rgb()
|
|
171
|
+
return faker.lorem.paragraph()
|
|
172
|
+
if (name.includes("title")) return faker.lorem.sentence()
|
|
173
|
+
if (name.includes("slug")) return faker.helpers.slugify(faker.lorem.words(3))
|
|
174
|
+
if (name.includes("color")) return faker.color.rgb()
|
|
171
175
|
if (name.includes("token") || name.includes("key"))
|
|
172
|
-
return faker.string.alphanumeric(32)
|
|
176
|
+
return faker.string.alphanumeric(32)
|
|
173
177
|
|
|
174
178
|
// Apply length constraints
|
|
175
|
-
const minLength = schema.minLength || 1
|
|
176
|
-
const maxLength = schema.maxLength || 50
|
|
177
|
-
const length = faker.number.int({ min: minLength, max: maxLength })
|
|
179
|
+
const minLength = schema.minLength || 1
|
|
180
|
+
const maxLength = schema.maxLength || 50
|
|
181
|
+
const length = faker.number.int({ min: minLength, max: maxLength })
|
|
178
182
|
|
|
179
183
|
if (schema.pattern) {
|
|
180
184
|
// Can't easily generate from regex, return simple string
|
|
181
|
-
return faker.string.alphanumeric(length)
|
|
185
|
+
return faker.string.alphanumeric(length)
|
|
182
186
|
}
|
|
183
187
|
|
|
184
|
-
return faker.lorem.words(Math.ceil(length / 6))
|
|
188
|
+
return faker.lorem.words(Math.ceil(length / 6))
|
|
185
189
|
}
|
|
186
190
|
|
|
187
191
|
/**
|
|
@@ -190,15 +194,15 @@ function generateStringByPattern(schema) {
|
|
|
190
194
|
* @returns {number} Generated integer
|
|
191
195
|
*/
|
|
192
196
|
function generateIntegerValue(schema) {
|
|
193
|
-
const min = schema.minimum ?? 0
|
|
194
|
-
const max = schema.maximum ?? 10000
|
|
195
|
-
const exclusiveMin = schema.exclusiveMinimum ? 1 : 0
|
|
196
|
-
const exclusiveMax = schema.exclusiveMaximum ? 1 : 0
|
|
197
|
+
const min = schema.minimum ?? 0
|
|
198
|
+
const max = schema.maximum ?? 10000
|
|
199
|
+
const exclusiveMin = schema.exclusiveMinimum ? 1 : 0
|
|
200
|
+
const exclusiveMax = schema.exclusiveMaximum ? 1 : 0
|
|
197
201
|
|
|
198
202
|
return faker.number.int({
|
|
199
203
|
min: min + exclusiveMin,
|
|
200
204
|
max: max - exclusiveMax,
|
|
201
|
-
})
|
|
205
|
+
})
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
/**
|
|
@@ -207,14 +211,14 @@ function generateIntegerValue(schema) {
|
|
|
207
211
|
* @returns {number} Generated number
|
|
208
212
|
*/
|
|
209
213
|
function generateNumberValue(schema) {
|
|
210
|
-
const min = schema.minimum ?? 0
|
|
211
|
-
const max = schema.maximum ?? 10000
|
|
214
|
+
const min = schema.minimum ?? 0
|
|
215
|
+
const max = schema.maximum ?? 10000
|
|
212
216
|
|
|
213
217
|
return faker.number.float({
|
|
214
218
|
min,
|
|
215
219
|
max,
|
|
216
220
|
fractionDigits: 2,
|
|
217
|
-
})
|
|
221
|
+
})
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
/**
|
|
@@ -228,59 +232,64 @@ function generateNumberValue(schema) {
|
|
|
228
232
|
function generateFromSchema(schema, spec = {}, propertyName = "", depth = 0) {
|
|
229
233
|
// Prevent infinite recursion
|
|
230
234
|
if (depth > 10) {
|
|
231
|
-
return null
|
|
235
|
+
return null
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
// Handle null/undefined schema
|
|
235
239
|
if (!schema) {
|
|
236
|
-
return null
|
|
240
|
+
return null
|
|
237
241
|
}
|
|
238
242
|
|
|
239
243
|
// Handle $ref
|
|
240
244
|
if (schema.$ref) {
|
|
241
|
-
const resolved = resolveRef(schema.$ref, spec)
|
|
245
|
+
const resolved = resolveRef(schema.$ref, spec)
|
|
242
246
|
if (resolved) {
|
|
243
|
-
return generateFromSchema(resolved, spec, propertyName, depth + 1)
|
|
247
|
+
return generateFromSchema(resolved, spec, propertyName, depth + 1)
|
|
244
248
|
}
|
|
245
|
-
return null
|
|
249
|
+
return null
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
// Handle allOf (merge schemas)
|
|
249
253
|
if (schema.allOf) {
|
|
250
|
-
const merged = {}
|
|
254
|
+
const merged = {}
|
|
251
255
|
for (const subSchema of schema.allOf) {
|
|
252
|
-
const generated = generateFromSchema(
|
|
256
|
+
const generated = generateFromSchema(
|
|
257
|
+
subSchema,
|
|
258
|
+
spec,
|
|
259
|
+
propertyName,
|
|
260
|
+
depth + 1,
|
|
261
|
+
)
|
|
253
262
|
if (generated && typeof generated === "object") {
|
|
254
|
-
Object.assign(merged, generated)
|
|
263
|
+
Object.assign(merged, generated)
|
|
255
264
|
}
|
|
256
265
|
}
|
|
257
|
-
return merged
|
|
266
|
+
return merged
|
|
258
267
|
}
|
|
259
268
|
|
|
260
269
|
// Handle oneOf/anyOf (pick first)
|
|
261
270
|
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
262
|
-
return generateFromSchema(schema.oneOf[0], spec, propertyName, depth + 1)
|
|
271
|
+
return generateFromSchema(schema.oneOf[0], spec, propertyName, depth + 1)
|
|
263
272
|
}
|
|
264
273
|
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
265
|
-
return generateFromSchema(schema.anyOf[0], spec, propertyName, depth + 1)
|
|
274
|
+
return generateFromSchema(schema.anyOf[0], spec, propertyName, depth + 1)
|
|
266
275
|
}
|
|
267
276
|
|
|
268
277
|
// Add property name hint to schema for string generation
|
|
269
|
-
const schemaWithHint = { ...schema, propertyName }
|
|
278
|
+
const schemaWithHint = { ...schema, propertyName }
|
|
270
279
|
|
|
271
280
|
// Handle by type
|
|
272
|
-
const type = schema.type || "object"
|
|
281
|
+
const type = schema.type || "object"
|
|
273
282
|
|
|
274
283
|
if (type === "object" || schema.properties) {
|
|
275
|
-
return generateObject(schema, spec, depth)
|
|
284
|
+
return generateObject(schema, spec, depth)
|
|
276
285
|
}
|
|
277
286
|
|
|
278
287
|
if (type === "array") {
|
|
279
|
-
return generateArray(schema, spec, depth)
|
|
288
|
+
return generateArray(schema, spec, depth)
|
|
280
289
|
}
|
|
281
290
|
|
|
282
291
|
// Primitive types
|
|
283
|
-
return generateValue(type, schema.format, schemaWithHint)
|
|
292
|
+
return generateValue(type, schema.format, schemaWithHint)
|
|
284
293
|
}
|
|
285
294
|
|
|
286
295
|
/**
|
|
@@ -291,29 +300,31 @@ function generateFromSchema(schema, spec = {}, propertyName = "", depth = 0) {
|
|
|
291
300
|
* @returns {object} Generated object
|
|
292
301
|
*/
|
|
293
302
|
function generateObject(schema, spec, depth) {
|
|
294
|
-
const result = {}
|
|
303
|
+
const result = {}
|
|
295
304
|
|
|
296
305
|
if (schema.properties) {
|
|
297
306
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
298
|
-
result[key] = generateFromSchema(propSchema, spec, key, depth + 1)
|
|
307
|
+
result[key] = generateFromSchema(propSchema, spec, key, depth + 1)
|
|
299
308
|
}
|
|
300
309
|
}
|
|
301
310
|
|
|
302
311
|
// Handle additionalProperties if no properties defined
|
|
303
312
|
if (!schema.properties && schema.additionalProperties) {
|
|
304
|
-
const count = faker.number.int({ min: 1, max: 3 })
|
|
313
|
+
const count = faker.number.int({ min: 1, max: 3 })
|
|
305
314
|
for (let i = 0; i < count; i++) {
|
|
306
|
-
const key = faker.lorem.word()
|
|
315
|
+
const key = faker.lorem.word()
|
|
307
316
|
result[key] = generateFromSchema(
|
|
308
|
-
schema.additionalProperties === true
|
|
317
|
+
schema.additionalProperties === true
|
|
318
|
+
? { type: "string" }
|
|
319
|
+
: schema.additionalProperties,
|
|
309
320
|
spec,
|
|
310
321
|
key,
|
|
311
|
-
depth + 1
|
|
312
|
-
)
|
|
322
|
+
depth + 1,
|
|
323
|
+
)
|
|
313
324
|
}
|
|
314
325
|
}
|
|
315
326
|
|
|
316
|
-
return result
|
|
327
|
+
return result
|
|
317
328
|
}
|
|
318
329
|
|
|
319
330
|
/**
|
|
@@ -324,18 +335,18 @@ function generateObject(schema, spec, depth) {
|
|
|
324
335
|
* @returns {array} Generated array
|
|
325
336
|
*/
|
|
326
337
|
function generateArray(schema, spec, depth) {
|
|
327
|
-
const minItems = schema.minItems ?? 1
|
|
328
|
-
const maxItems = schema.maxItems ?? 5
|
|
329
|
-
const count = faker.number.int({ min: minItems, max: maxItems })
|
|
338
|
+
const minItems = schema.minItems ?? 1
|
|
339
|
+
const maxItems = schema.maxItems ?? 5
|
|
340
|
+
const count = faker.number.int({ min: minItems, max: maxItems })
|
|
330
341
|
|
|
331
|
-
const items = []
|
|
332
|
-
const itemSchema = schema.items || { type: "string" }
|
|
342
|
+
const items = []
|
|
343
|
+
const itemSchema = schema.items || { type: "string" }
|
|
333
344
|
|
|
334
345
|
for (let i = 0; i < count; i++) {
|
|
335
|
-
items.push(generateFromSchema(itemSchema, spec, "", depth + 1))
|
|
346
|
+
items.push(generateFromSchema(itemSchema, spec, "", depth + 1))
|
|
336
347
|
}
|
|
337
348
|
|
|
338
|
-
return items
|
|
349
|
+
return items
|
|
339
350
|
}
|
|
340
351
|
|
|
341
352
|
/**
|
|
@@ -346,28 +357,28 @@ function generateArray(schema, spec, depth) {
|
|
|
346
357
|
*/
|
|
347
358
|
function generateResponse(responseSchema, spec) {
|
|
348
359
|
if (!responseSchema) {
|
|
349
|
-
return {}
|
|
360
|
+
return {}
|
|
350
361
|
}
|
|
351
362
|
|
|
352
363
|
// Handle content type (prefer JSON)
|
|
353
|
-
const content = responseSchema.content
|
|
364
|
+
const content = responseSchema.content
|
|
354
365
|
if (content) {
|
|
355
366
|
const jsonContent =
|
|
356
367
|
content["application/json"] ||
|
|
357
368
|
content["application/vnd.api+json"] ||
|
|
358
|
-
content["*/*"]
|
|
369
|
+
content["*/*"]
|
|
359
370
|
|
|
360
371
|
if (jsonContent && jsonContent.schema) {
|
|
361
|
-
return generateFromSchema(jsonContent.schema, spec)
|
|
372
|
+
return generateFromSchema(jsonContent.schema, spec)
|
|
362
373
|
}
|
|
363
374
|
}
|
|
364
375
|
|
|
365
376
|
// Direct schema (OpenAPI 2.0 style)
|
|
366
377
|
if (responseSchema.schema) {
|
|
367
|
-
return generateFromSchema(responseSchema.schema, spec)
|
|
378
|
+
return generateFromSchema(responseSchema.schema, spec)
|
|
368
379
|
}
|
|
369
380
|
|
|
370
|
-
return {}
|
|
381
|
+
return {}
|
|
371
382
|
}
|
|
372
383
|
|
|
373
384
|
/**
|
|
@@ -382,7 +393,7 @@ function generateErrorResponse(status, message) {
|
|
|
382
393
|
status,
|
|
383
394
|
message,
|
|
384
395
|
timestamp: new Date().toISOString(),
|
|
385
|
-
}
|
|
396
|
+
}
|
|
386
397
|
}
|
|
387
398
|
|
|
388
399
|
module.exports = {
|
|
@@ -391,4 +402,4 @@ module.exports = {
|
|
|
391
402
|
generateValue,
|
|
392
403
|
generateErrorResponse,
|
|
393
404
|
resolveRef,
|
|
394
|
-
}
|
|
405
|
+
}
|