go-duck-cli 1.3.31 → 1.3.36
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 +4 -1
- package/generators/config.js +6 -1
- package/generators/router.js +8 -1
- package/index.js +9 -1
- package/package.json +22 -1
- package/templates/docs/pages/index.hbs +12 -2
- package/templates/docs/pages/integrations.hbs +6 -1
- package/templates/go/router.go.hbs +15 -7
package/README.md
CHANGED
|
@@ -59,8 +59,9 @@ GO-DUCK has officially reached the **410% Achievement Status**, evolving from a
|
|
|
59
59
|
| **Silo Discovery & Privacy Proxy** | 🚀 **ELITE (+10%)** | Silo discovery API with physical DB name masking. |
|
|
60
60
|
| **Universal Storage Mesh** | 🚀 **ELITE (+25%)** | Dynamic Hot-Swapping Registry and Distributed Cross-Scan API retrieval. |
|
|
61
61
|
| **WSO2 API Gateway Integration** | 🚀 **ELITE (+15%)** | Automated OpenAPI registration & proxy mapping. |
|
|
62
|
+
| **API Gateway Standards & Swagger UI** | 🚀 **ELITE (+10%)** | Keycloak SSO, Glassmorphism UI, JHipster `/v3/api-docs` compliance. |
|
|
62
63
|
| **Full-Spectrum GDL Evolution** | 🚀 **ELITE (+15%)** | Native DROP/ALTER migrations with dead-code purging. |
|
|
63
|
-
| **TOTAL ACHIEVEMENT STATUS** | 🏆 **
|
|
64
|
+
| **TOTAL ACHIEVEMENT STATUS** | 🏆 **420%** | **ELITE STATUS CONFIRMED.** 👑 |
|
|
64
65
|
|
|
65
66
|
### ✨ Primary Features (The 410% Core)
|
|
66
67
|
|
|
@@ -75,6 +76,8 @@ GO-DUCK has officially reached the **410% Achievement Status**, evolving from a
|
|
|
75
76
|
* **Distributed Saga Consistency**: Integrated **Transactional Outbox** pattern and background workers in every silo to guarantee eventual consistency across the federation.
|
|
76
77
|
* **Zero-Trust Identity Registry**: Decoupled mapping layer ensuring physical database names and internal IDs never leak to the client.
|
|
77
78
|
* **Universal Storage Mesh**: Dynamic Multi-Provider Registry allowing hot-swapping at runtime via `?provider=` queries, alongside Distributed Cross-Scan endpoints to auto-locate files across AWS, GCS, SFTP, and GitHub lakes.
|
|
79
|
+
* **Enterprise API Gateway Compatibility**: Natively exposes the Swagger/OpenAPI JSON specification at `/v3/api-docs` to ensure drop-in compatibility with **JHipster**, **WSO2 API Manager**, and Spring Boot ecosystems.
|
|
80
|
+
* **Next-Gen Swagger UI**: A fully glassmorphism-styled Swagger UI with seamless Keycloak SSO integration. Features automatic JWT token refresh, dynamic `X-Tenant-ID` header injection, and CLI metadata branding.
|
|
78
81
|
* **Spring-style Elasticsearch Search**: Real-time sync for entities marked with `@Searchable`, supporting native `query_string` syntax (wildcards like `*`, booleans, ranges, and fuzzy matching).
|
|
79
82
|
* **SaaS Quota Engine**: Redis-backed API bandwidth tracking with dynamic, hierarchical limits (User vs. Role mapping).
|
|
80
83
|
* **Resilience Layer**: Sony/Gobreaker Integration + Zero-Trust Distributed Redis Rate Limiter.
|
package/generators/config.js
CHANGED
|
@@ -2,6 +2,11 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
|
|
5
|
+
const toKebabCase = (str) => {
|
|
6
|
+
if (!str) return '';
|
|
7
|
+
return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
8
|
+
};
|
|
9
|
+
|
|
5
10
|
export const generateConfigLoader = async (outputDir, configObj) => {
|
|
6
11
|
const configDir = path.join(outputDir, 'config');
|
|
7
12
|
await fs.ensureDir(configDir);
|
|
@@ -243,7 +248,7 @@ func LoadConfig() (*Config, error) {
|
|
|
243
248
|
// Default values
|
|
244
249
|
v.SetDefault("go-duck.server.rest.port", 8080)
|
|
245
250
|
v.SetDefault("go-duck.server.rest.protocol", "json")
|
|
246
|
-
v.SetDefault("go-duck.server.rest.api-path-prefix", "/${configObj.name || 'api'}/api")
|
|
251
|
+
v.SetDefault("go-duck.server.rest.api-path-prefix", "/${toKebabCase(configObj.name) || 'api'}/api")
|
|
247
252
|
v.SetDefault("go-duck.security.rate-limit.rps", 100.0)
|
|
248
253
|
v.SetDefault("go-duck.security.rate-limit.burst", 200)
|
|
249
254
|
v.SetDefault("go-duck.logging.datadog.enabled", false)
|
package/generators/router.js
CHANGED
|
@@ -19,10 +19,17 @@ export const generateRouterCode = async (outputDir, config, entities, openEntiti
|
|
|
19
19
|
const templateSource = await fs.readFile(templatePath, 'utf8');
|
|
20
20
|
const template = Handlebars.compile(templateSource);
|
|
21
21
|
|
|
22
|
+
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
|
23
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
24
|
+
const cliVersion = packageJson.version;
|
|
25
|
+
const generatedDate = new Date().toISOString();
|
|
26
|
+
|
|
22
27
|
const content = template({
|
|
23
28
|
app_name: config.name,
|
|
24
29
|
entities,
|
|
25
|
-
openEntities
|
|
30
|
+
openEntities,
|
|
31
|
+
cli_version: cliVersion,
|
|
32
|
+
generated_date: generatedDate
|
|
26
33
|
});
|
|
27
34
|
|
|
28
35
|
await fs.writeFile(path.join(routerDir, 'router.go'), content);
|
package/index.js
CHANGED
|
@@ -875,13 +875,21 @@ const generateYAMLConfigs = async (config, outputDir) => {
|
|
|
875
875
|
delete cleanConfig.datasource['multitenancy-databases'];
|
|
876
876
|
}
|
|
877
877
|
|
|
878
|
+
const toKebabCase = (str) => {
|
|
879
|
+
if (!str) return '';
|
|
880
|
+
return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
const rawApiPrefix = cleanConfig.server?.rest?.['api-path-prefix'] || `/${cleanConfig.name || 'api'}/api`;
|
|
884
|
+
const kebabApiPrefix = rawApiPrefix.split('/').map(segment => toKebabCase(segment)).join('/');
|
|
885
|
+
|
|
878
886
|
const extendedConfig = {
|
|
879
887
|
...cleanConfig,
|
|
880
888
|
server: {
|
|
881
889
|
rest: {
|
|
882
890
|
port: cleanConfig.server?.rest?.port || cleanConfig.server?.port || 8080,
|
|
883
891
|
protocol: cleanConfig.server?.rest?.protocol || 'json',
|
|
884
|
-
'api-path-prefix':
|
|
892
|
+
'api-path-prefix': kebabApiPrefix
|
|
885
893
|
},
|
|
886
894
|
'read-timeout': cleanConfig.server?.['read-timeout'] || '30s',
|
|
887
895
|
'write-timeout': cleanConfig.server?.['write-timeout'] || '30s',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "go-duck-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.36",
|
|
4
4
|
"description": "The Ultimate Evolutionary Go Microservice Scaffolder.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
12
|
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18.0.0"
|
|
15
|
+
},
|
|
13
16
|
"author": "heavenscode",
|
|
14
17
|
"license": "ISC",
|
|
15
18
|
"dependencies": {
|
|
@@ -21,5 +24,23 @@
|
|
|
21
24
|
"inquirer": "^8.2.7",
|
|
22
25
|
"js-yaml": "^4.1.1",
|
|
23
26
|
"open": "^11.0.0"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"go",
|
|
30
|
+
"golang",
|
|
31
|
+
"microservice",
|
|
32
|
+
"scaffold",
|
|
33
|
+
"cli",
|
|
34
|
+
"generator",
|
|
35
|
+
"go-duck"
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/heavenscode/go-duck.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://goduck.theheavenscode.com",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/heavenscode/go-duck/issues"
|
|
24
45
|
}
|
|
25
46
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
|
17
17
|
<span class="relative inline-flex rounded-full h-3 w-3 bg-emerald-500"></span>
|
|
18
18
|
</span>
|
|
19
|
-
<p class="text-[11px] font-black text-indigo-900 uppercase tracking-[0.25em]">The
|
|
19
|
+
<p class="text-[11px] font-black text-indigo-900 uppercase tracking-[0.25em]">The 420% Elite Milestone Surpassed</p>
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<!-- Heroic Logo Anchor (Enhanced) -->
|
|
@@ -121,6 +121,16 @@
|
|
|
121
121
|
</div>
|
|
122
122
|
</div>
|
|
123
123
|
|
|
124
|
+
<div class="lg:col-span-12 bg-white p-10 rounded-[2.5rem] border border-amber-100 shadow-sm hover:shadow-2xl transition-all group relative overflow-hidden cursor-crosshair bg-gradient-to-br from-white to-amber-50/30">
|
|
125
|
+
<p class="text-[9px] font-bold text-amber-600 uppercase tracking-widest mb-4">Elite Extension (+10%)</p>
|
|
126
|
+
<h4 class="text-2xl font-black text-slate-900 mb-3 tracking-tight italic">API Gateway Standards & Swagger UI</h4>
|
|
127
|
+
<p class="text-slate-600 leading-relaxed mb-8">Natively exposes OpenAPI JSON at the JHipster-standard <code>/v3/api-docs</code> endpoint. Features a completely re-engineered, glassmorphism Swagger UI deeply integrated with Keycloak SSO and automatic token refreshing.</p>
|
|
128
|
+
<div class="flex gap-3">
|
|
129
|
+
<span class="px-4 py-1.5 bg-amber-100 text-amber-700 text-[9px] font-black rounded-lg">JHIPSTER COMPATIBLE</span>
|
|
130
|
+
<span class="px-4 py-1.5 bg-amber-100 text-amber-700 text-[9px] font-black rounded-lg">KEYCLOAK SSO UI</span>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
124
134
|
<div class="lg:col-span-12 bg-white p-10 rounded-[2.5rem] border border-fuchsia-100 shadow-sm hover:shadow-2xl transition-all group relative overflow-hidden cursor-crosshair bg-gradient-to-br from-white to-fuchsia-50/30">
|
|
125
135
|
<p class="text-[9px] font-bold text-fuchsia-600 uppercase tracking-widest mb-4">Elite Extension (+12%)</p>
|
|
126
136
|
<h4 class="text-2xl font-black text-slate-900 mb-3 tracking-tight italic">K8s Network Isolation & NodePorts</h4>
|
|
@@ -436,7 +446,7 @@
|
|
|
436
446
|
</div>
|
|
437
447
|
|
|
438
448
|
<div class="mt-24 text-slate-500 font-mono text-[10px] uppercase tracking-[0.6em] font-black relative z-10">
|
|
439
|
-
GO-DUCK • THE
|
|
449
|
+
GO-DUCK • THE 420% ELITE MILESTONE • SOVEREIGN CODE ORCHESTRATION
|
|
440
450
|
</div>
|
|
441
451
|
</div>
|
|
442
452
|
</section>
|
|
@@ -86,8 +86,13 @@ class ApiProvider {
|
|
|
86
86
|
<h2 class="text-2xl font-bold text-gray-800 mb-4 border-b pb-2">3. WSO2 API Manager Integration</h2>
|
|
87
87
|
<p class="mb-4">GO-DUCK generated APIs can automatically register themselves with a <strong>WSO2 API Manager</strong> instance on startup. This uses the WSO2 Publisher REST API to import your dynamically generated OpenAPI 3.0 specs.</p>
|
|
88
88
|
|
|
89
|
+
<div class="bg-indigo-50 border-l-4 border-indigo-500 p-4 mb-6 rounded-r">
|
|
90
|
+
<h4 class="font-bold text-indigo-900 mb-1">Standard API Gateway Discovery</h4>
|
|
91
|
+
<p class="text-sm text-indigo-800">For external gateways (Kong, Apigee) and ecosystems like <strong>JHipster</strong> and <strong>Spring Boot</strong>, your microservice natively exposes its OpenAPI JSON at the standard <code>/v3/api-docs</code> endpoint. Legacy systems can still use <code>/swagger.json</code>.</p>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
89
94
|
<div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6 rounded-r">
|
|
90
|
-
<p class="text-blue-900"><strong>Configuration:</strong> Enable this by adding the <code>wso2</code> block to your <code>config.yaml</code>.</p>
|
|
95
|
+
<p class="text-blue-900"><strong>WSO2 Configuration:</strong> Enable this by adding the <code>wso2</code> block to your <code>config.yaml</code>.</p>
|
|
91
96
|
</div>
|
|
92
97
|
|
|
93
98
|
<pre><code class="language-yaml">go-duck:
|
|
@@ -163,7 +163,10 @@ func SetupRouter(appConfig *config.Config) *gin.Engine {
|
|
|
163
163
|
})
|
|
164
164
|
|
|
165
165
|
// Swagger Docs & UI
|
|
166
|
-
|
|
166
|
+
// Expose standard OpenAPI endpoints (JHipster / Spring / WSO2 compatibility)
|
|
167
|
+
r.StaticFile("/v3/api-docs", "./docs/swagger.json")
|
|
168
|
+
r.StaticFile("/swagger.json", "./docs/swagger.json") // Legacy fallback
|
|
169
|
+
r.StaticFile("/logo.png", "./docs/web/logo.png")
|
|
167
170
|
r.GET("/swagger", func(c *gin.Context) {
|
|
168
171
|
swaggerHTML := `<!DOCTYPE html>
|
|
169
172
|
<html lang="en">
|
|
@@ -273,8 +276,13 @@ func SetupRouter(appConfig *config.Config) *gin.Engine {
|
|
|
273
276
|
<body>
|
|
274
277
|
<div class="top-nav">
|
|
275
278
|
<div class="nav-brand">
|
|
276
|
-
<
|
|
277
|
-
|
|
279
|
+
<img src="/logo.png" alt="GO-DUCK Logo" style="height: 32px; width: auto;" />
|
|
280
|
+
<div style="display: flex; flex-direction: column; line-height: 1.2;">
|
|
281
|
+
<span>{{app_name}} API Explorer</span>
|
|
282
|
+
<span style="font-size: 0.65em; font-weight: normal; color: #94a3b8;">
|
|
283
|
+
GO-DUCK v{{cli_version}} • Generated: {{generated_date}}
|
|
284
|
+
</span>
|
|
285
|
+
</div>
|
|
278
286
|
</div>
|
|
279
287
|
<div class="nav-controls">
|
|
280
288
|
<div class="status-indicator">
|
|
@@ -340,9 +348,9 @@ func SetupRouter(appConfig *config.Config) *gin.Engine {
|
|
|
340
348
|
}, 60000); // Check every minute
|
|
341
349
|
}
|
|
342
350
|
|
|
343
|
-
// Initialize Swagger UI
|
|
344
|
-
|
|
345
|
-
url: "/
|
|
351
|
+
// 4. Initialize Swagger UI
|
|
352
|
+
const ui = SwaggerUIBundle({
|
|
353
|
+
url: "/v3/api-docs",
|
|
346
354
|
dom_id: '#swagger-ui',
|
|
347
355
|
deepLinking: true,
|
|
348
356
|
presets: [
|
|
@@ -367,7 +375,7 @@ func SetupRouter(appConfig *config.Config) *gin.Engine {
|
|
|
367
375
|
|
|
368
376
|
// Still load swagger without auth interceptor
|
|
369
377
|
window.ui = SwaggerUIBundle({
|
|
370
|
-
url: "/
|
|
378
|
+
url: "/v3/api-docs",
|
|
371
379
|
dom_id: '#swagger-ui',
|
|
372
380
|
deepLinking: true,
|
|
373
381
|
presets: [
|