@cloudcare/guance-front-tools 1.0.13 → 1.0.16
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/lib/cjs/scripts/convert-grafana-dashboard-core.js +1678 -0
- package/lib/cjs/scripts/convert-grafana-dashboard.js +130 -0
- package/lib/cjs/scripts/grafana-covert-to-guance-core.js +2 -2
- package/lib/esm/scripts/convert-grafana-dashboard-core.js +1675 -0
- package/lib/esm/scripts/convert-grafana-dashboard.js +125 -0
- package/lib/esm/scripts/grafana-covert-to-guance-core.js +1 -1
- package/lib/scripts/convert-grafana-dashboard-core.js +1770 -0
- package/lib/scripts/convert-grafana-dashboard.js +147 -0
- package/lib/scripts/grafana-covert-to-guance-core.js +1 -1
- package/lib/scripts/grafana-covert-to-guance-core.ts +1 -1
- package/lib/scripts/grafana-covert-to-guance.js +3 -1
- package/lib/scripts/grafana-covert-to-guance.ts +3 -4
- package/package.json +3 -2
- package/scripts/sync-converter.mjs +57 -0
- package/skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard-core.js +1675 -0
- package/skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs +106 -1880
- package/test/cli.test.mjs +123 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
import { pathToFileURL } from 'url'
|
|
6
|
+
import Ajv from 'ajv'
|
|
7
|
+
import { convertDashboard } from './convert-grafana-dashboard-core.js'
|
|
8
|
+
|
|
9
|
+
if (isDirectExecution()) {
|
|
10
|
+
main()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isDirectExecution() {
|
|
14
|
+
if (!process.argv[1]) return false
|
|
15
|
+
return import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function main() {
|
|
19
|
+
const { inputPath, outputPath, validateOutput, schemaId, guancePromqlCompatible, keepGrafanaMeta } = parseArgs(process.argv.slice(2))
|
|
20
|
+
const grafanaDashboard = readJson(inputPath)
|
|
21
|
+
const guanceDashboard = convertDashboard(grafanaDashboard, { guancePromqlCompatible, keepGrafanaMeta })
|
|
22
|
+
|
|
23
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true })
|
|
24
|
+
fs.writeFileSync(outputPath, `${JSON.stringify(guanceDashboard, null, 2)}\n`, 'utf8')
|
|
25
|
+
console.log(`Converted ${inputPath} -> ${outputPath}`)
|
|
26
|
+
|
|
27
|
+
if (validateOutput) {
|
|
28
|
+
validateDashboardFile(outputPath, schemaId)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseArgs(args) {
|
|
33
|
+
let inputPath = ''
|
|
34
|
+
let outputPath = ''
|
|
35
|
+
let validateOutput = false
|
|
36
|
+
let schemaId = 'dashboard-schema.json'
|
|
37
|
+
let guancePromqlCompatible = false
|
|
38
|
+
let keepGrafanaMeta = false
|
|
39
|
+
|
|
40
|
+
for (let index = 0; index < args.length; index++) {
|
|
41
|
+
const value = args[index]
|
|
42
|
+
if ((value === '-i' || value === '--input') && args[index + 1]) {
|
|
43
|
+
inputPath = path.resolve(args[++index])
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
if ((value === '-o' || value === '--output') && args[index + 1]) {
|
|
47
|
+
outputPath = path.resolve(args[++index])
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
if (value === '--validate') {
|
|
51
|
+
validateOutput = true
|
|
52
|
+
continue
|
|
53
|
+
}
|
|
54
|
+
if (value === '--schema' && args[index + 1]) {
|
|
55
|
+
schemaId = args[++index]
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
if (value === '--guance-promql-compatible') {
|
|
59
|
+
guancePromqlCompatible = true
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
if (value === '--keep-grafana-meta') {
|
|
63
|
+
keepGrafanaMeta = true
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
if (value === '-h' || value === '--help') {
|
|
67
|
+
printHelp()
|
|
68
|
+
process.exit(0)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!inputPath) {
|
|
73
|
+
printHelp()
|
|
74
|
+
process.exit(1)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!outputPath) {
|
|
78
|
+
const parsed = path.parse(inputPath)
|
|
79
|
+
outputPath = path.join(parsed.dir, `${parsed.name}.guance.json`)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { inputPath, outputPath, validateOutput, schemaId, guancePromqlCompatible, keepGrafanaMeta }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function printHelp() {
|
|
86
|
+
console.error(
|
|
87
|
+
'Usage: node convert-grafana-dashboard.mjs --input <grafana.json> [--output <guance.json>] [--validate] [--schema <schema-id>] [--guance-promql-compatible] [--keep-grafana-meta]'
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function validateDashboardFile(filePath, schemaId) {
|
|
92
|
+
const projectRoot = findProjectRoot()
|
|
93
|
+
const schemasDirectory = path.join(projectRoot, 'schemas')
|
|
94
|
+
const ajv = new Ajv({ allErrors: true })
|
|
95
|
+
|
|
96
|
+
forEachFile(schemasDirectory, (schemaPath) => {
|
|
97
|
+
if (!schemaPath.endsWith('.json')) return
|
|
98
|
+
ajv.addSchema(readJson(schemaPath))
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const valid = ajv.validate(schemaId, readJson(filePath))
|
|
102
|
+
if (valid) {
|
|
103
|
+
console.log(`Validated ${filePath} against ${schemaId}`)
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.error(`Validation failed for ${filePath} against ${schemaId}:`)
|
|
108
|
+
for (const error of ajv.errors || []) {
|
|
109
|
+
const instancePath = error.instancePath || '/'
|
|
110
|
+
console.error(`- ${instancePath} ${error.message}`)
|
|
111
|
+
}
|
|
112
|
+
process.exit(1)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function findProjectRoot() {
|
|
116
|
+
let currentDirectory = process.cwd()
|
|
117
|
+
|
|
118
|
+
while (true) {
|
|
119
|
+
if (fs.existsSync(path.join(currentDirectory, 'schemas', 'dashboard-schema.json'))) {
|
|
120
|
+
return currentDirectory
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const parentDirectory = path.dirname(currentDirectory)
|
|
124
|
+
if (parentDirectory === currentDirectory) {
|
|
125
|
+
throw new Error('Could not locate project root containing schemas/dashboard-schema.json')
|
|
126
|
+
}
|
|
127
|
+
currentDirectory = parentDirectory
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function readJson(filePath) {
|
|
132
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'))
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function forEachFile(directoryPath, visitor) {
|
|
136
|
+
const entries = fs.readdirSync(directoryPath, { withFileTypes: true })
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const entryPath = path.join(directoryPath, entry.name)
|
|
139
|
+
if (entry.isDirectory()) {
|
|
140
|
+
forEachFile(entryPath, visitor)
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
visitor(entryPath)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { convertDashboard }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This script is the shared conversion source for the published API and CLI.
|
|
2
2
|
// Keep it thin and delegate to the maintained converter implementation.
|
|
3
3
|
// @ts-ignore
|
|
4
|
-
import { convertDashboard } from '
|
|
4
|
+
import { convertDashboard } from './convert-grafana-dashboard-core.js';
|
|
5
5
|
export function covert(grafanaData) {
|
|
6
6
|
return convertDashboard(grafanaData);
|
|
7
7
|
}
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
// This script is the shared conversion source for the published API and CLI.
|
|
10
10
|
// Keep it thin and delegate to the maintained converter implementation.
|
|
11
11
|
// @ts-ignore
|
|
12
|
-
import { convertDashboard } from '
|
|
12
|
+
import { convertDashboard } from './convert-grafana-dashboard-core.js'
|
|
13
13
|
|
|
14
14
|
export function covert(grafanaData: GrafanaDashboardType): GuanceDashboardType {
|
|
15
15
|
return convertDashboard(grafanaData) as GuanceDashboardType
|
|
@@ -11,7 +11,9 @@ import fs from 'fs';
|
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import yargs from 'yargs';
|
|
13
13
|
// @ts-ignore
|
|
14
|
-
import { convertDashboard
|
|
14
|
+
import { convertDashboard } from './convert-grafana-dashboard-core.js';
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
import { validateDashboardFile } from './convert-grafana-dashboard.js';
|
|
15
17
|
export function run(args) {
|
|
16
18
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
19
|
const { argv } = yargs(args)
|
|
@@ -2,10 +2,9 @@ import fs from 'fs'
|
|
|
2
2
|
import path from 'path'
|
|
3
3
|
import yargs from 'yargs'
|
|
4
4
|
// @ts-ignore
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '../../skills/grafana-to-guance-dashboard/scripts/convert-grafana-dashboard.mjs'
|
|
5
|
+
import { convertDashboard } from './convert-grafana-dashboard-core.js'
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
import { validateDashboardFile } from './convert-grafana-dashboard.js'
|
|
9
8
|
|
|
10
9
|
export async function run(args: string[]) {
|
|
11
10
|
const { argv } = yargs(args)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcare/guance-front-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"types": "lib/cjs/src/index.d.ts",
|
|
17
17
|
"module": "lib/esm/src/index.js",
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "npm run clean && npm run generate && npm run build:cjs && npm run build:esm && npm run build:script",
|
|
19
|
+
"build": "npm run clean && npm run generate && npm run build:cjs && npm run build:esm && npm run build:script && npm run sync:converter",
|
|
20
20
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
21
21
|
"build:esm": "tsc -p tsconfig.esm.json",
|
|
22
22
|
"build:script": "tsc -p tsconfig.script.json",
|
|
23
|
+
"sync:converter": "node scripts/sync-converter.mjs",
|
|
23
24
|
"clean": "rm -rf ./lib/generated && rm -rf ./lib/esm && rm -rf ./lib/cjs",
|
|
24
25
|
"generate": "node scripts/generate.mjs",
|
|
25
26
|
"test": "node --test test/*.test.mjs",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import ts from 'typescript'
|
|
4
|
+
|
|
5
|
+
const projectRoot = process.cwd()
|
|
6
|
+
const syncPairs = [
|
|
7
|
+
{
|
|
8
|
+
sourcePath: path.join(projectRoot, 'lib', 'scripts', 'convert-grafana-dashboard.js'),
|
|
9
|
+
targets: [
|
|
10
|
+
path.join(projectRoot, 'lib', 'esm', 'scripts', 'convert-grafana-dashboard.js'),
|
|
11
|
+
path.join(projectRoot, 'lib', 'cjs', 'scripts', 'convert-grafana-dashboard.js'),
|
|
12
|
+
path.join(projectRoot, 'skills', 'grafana-to-guance-dashboard', 'scripts', 'convert-grafana-dashboard.mjs'),
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
sourcePath: path.join(projectRoot, 'lib', 'scripts', 'convert-grafana-dashboard-core.js'),
|
|
17
|
+
targets: [
|
|
18
|
+
path.join(projectRoot, 'lib', 'esm', 'scripts', 'convert-grafana-dashboard-core.js'),
|
|
19
|
+
path.join(projectRoot, 'lib', 'cjs', 'scripts', 'convert-grafana-dashboard-core.js'),
|
|
20
|
+
path.join(projectRoot, 'skills', 'grafana-to-guance-dashboard', 'scripts', 'convert-grafana-dashboard-core.js'),
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
]
|
|
24
|
+
const staleTargets = [
|
|
25
|
+
path.join(projectRoot, 'lib', 'scripts', 'convert-grafana-dashboard.mjs'),
|
|
26
|
+
path.join(projectRoot, 'lib', 'esm', 'scripts', 'convert-grafana-dashboard.mjs'),
|
|
27
|
+
path.join(projectRoot, 'lib', 'cjs', 'scripts', 'convert-grafana-dashboard.mjs'),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
function transpileForTarget(sourcePath, targetPath) {
|
|
31
|
+
const source = fs.readFileSync(sourcePath, 'utf8')
|
|
32
|
+
const isCommonJsTarget = targetPath.includes(`${path.sep}lib${path.sep}cjs${path.sep}`)
|
|
33
|
+
const fileName = targetPath.endsWith('.mjs') ? targetPath.replace(/\.mjs$/, '.mts') : targetPath
|
|
34
|
+
const { outputText } = ts.transpileModule(source, {
|
|
35
|
+
fileName,
|
|
36
|
+
compilerOptions: {
|
|
37
|
+
target: ts.ScriptTarget.ES2018,
|
|
38
|
+
module: isCommonJsTarget ? ts.ModuleKind.CommonJS : ts.ModuleKind.ES2020,
|
|
39
|
+
allowJs: true,
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
return outputText
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const { sourcePath, targets } of syncPairs) {
|
|
46
|
+
for (const target of targets) {
|
|
47
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
48
|
+
fs.writeFileSync(target, transpileForTarget(sourcePath, target), 'utf8')
|
|
49
|
+
console.log(`Synced ${path.relative(projectRoot, sourcePath)} -> ${path.relative(projectRoot, target)}`)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (const target of staleTargets) {
|
|
54
|
+
if (!fs.existsSync(target)) continue
|
|
55
|
+
fs.rmSync(target, { force: true })
|
|
56
|
+
console.log(`Removed stale ${path.relative(projectRoot, target)}`)
|
|
57
|
+
}
|