Compare commits
No commits in common. "develop" and "v1.0.4" have entirely different histories.
12 changed files with 3585 additions and 5549 deletions
1
.envrc
1
.envrc
|
@ -1 +0,0 @@
|
||||||
use flake
|
|
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
@ -1,2 +1 @@
|
||||||
github: lstrojny
|
github: lstrojny
|
||||||
custom: ["https://paypal.me/larsstrojny"]
|
|
||||||
|
|
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
|
@ -20,16 +20,16 @@ jobs:
|
||||||
name: nodejs ${{ matrix.node-version }} (${{ matrix.lint && 'lint → ' || '' }}${{ matrix.tests && 'test → ' || '' }}build)
|
name: nodejs ${{ matrix.node-version }} (${{ matrix.lint && 'lint → ' || '' }}${{ matrix.tests && 'test → ' || '' }}build)
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.0
|
- uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v3.8.1
|
uses: actions/setup-node@v3.6.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Cache node modules
|
||||||
id: cache-npm
|
id: cache-npm
|
||||||
uses: actions/cache@v3.3.2
|
uses: actions/cache@v3.2.2
|
||||||
env:
|
env:
|
||||||
cache-name: cache-node-modules
|
cache-name: cache-node-modules
|
||||||
with:
|
with:
|
||||||
|
@ -38,7 +38,7 @@ jobs:
|
||||||
|
|
||||||
- name: Cache eslint
|
- name: Cache eslint
|
||||||
id: cache-eslint
|
id: cache-eslint
|
||||||
uses: actions/cache@v3.3.2
|
uses: actions/cache@v3.2.2
|
||||||
env:
|
env:
|
||||||
cache-name: cache-eslint
|
cache-name: cache-eslint
|
||||||
with:
|
with:
|
||||||
|
@ -47,7 +47,7 @@ jobs:
|
||||||
|
|
||||||
- name: Cache TypeScript
|
- name: Cache TypeScript
|
||||||
id: cache-typescript
|
id: cache-typescript
|
||||||
uses: actions/cache@v3.3.2
|
uses: actions/cache@v3.2.2
|
||||||
env:
|
env:
|
||||||
cache-name: cache-typescript
|
cache-name: cache-typescript
|
||||||
with:
|
with:
|
||||||
|
@ -56,7 +56,7 @@ jobs:
|
||||||
|
|
||||||
- name: Cache prettier
|
- name: Cache prettier
|
||||||
id: cache-prettier
|
id: cache-prettier
|
||||||
uses: actions/cache@v3.3.2
|
uses: actions/cache@v3.2.2
|
||||||
env:
|
env:
|
||||||
cache-name: cache-prettier
|
cache-name: cache-prettier
|
||||||
with:
|
with:
|
||||||
|
@ -76,7 +76,7 @@ jobs:
|
||||||
if: ${{ matrix.tests }}
|
if: ${{ matrix.tests }}
|
||||||
|
|
||||||
- name: Upload code coverage
|
- name: Upload code coverage
|
||||||
uses: actions/upload-artifact@v3.1.3
|
uses: actions/upload-artifact@v3.1.1
|
||||||
with:
|
with:
|
||||||
name: code-coverage
|
name: code-coverage
|
||||||
path: coverage/lcov.info
|
path: coverage/lcov.info
|
||||||
|
|
28
.github/workflows/dependabot-automerge.yml
vendored
28
.github/workflows/dependabot-automerge.yml
vendored
|
@ -1,28 +0,0 @@
|
||||||
name: Dependabot auto merge
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: [CI]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
automerge:
|
|
||||||
name: Auto merge "${{ github.event.workflow_run.head_branch }}"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
if: >
|
|
||||||
github.event.workflow_run.event == 'pull_request'
|
|
||||||
&& github.event.workflow_run.conclusion == 'success'
|
|
||||||
&& github.actor == 'dependabot[bot]'
|
|
||||||
&& startsWith(github.event.workflow_run.head_branch, 'dependabot/')
|
|
||||||
steps:
|
|
||||||
- name: Checkout source
|
|
||||||
uses: actions/checkout@v4.1.0
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.workflow_run.head_commit.id }}
|
|
||||||
|
|
||||||
- name: Instruct @dependabot to merge
|
|
||||||
run: "gh issue comment $ISSUE_ID --body \"(This is an automated comment from workflow $WORKFLOW_URL)\n\n@dependabot squash and merge\""
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.DEPENDABOT_COMMENT_TOKEN }}
|
|
||||||
ISSUE_ID: ${{ github.event.workflow_run.pull_requests[0].number }}
|
|
||||||
WORKFLOW_URL: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
|
|
6
.github/workflows/sonar.yml
vendored
6
.github/workflows/sonar.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Sonar scan
|
name: Sonar
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_run:
|
||||||
|
@ -7,12 +7,12 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
sonar:
|
sonar:
|
||||||
name: Sonar scan on "${{ github.event.workflow_run.head_branch }}"
|
name: Sonar
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.workflow_run.conclusion == 'success'
|
if: github.event.workflow_run.conclusion == 'success'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.0
|
- uses: actions/checkout@v3.3.0
|
||||||
with:
|
with:
|
||||||
repository: ${{ github.event.workflow_run.head_repository.full_name }}
|
repository: ${{ github.event.workflow_run.head_repository.full_name }}
|
||||||
ref: ${{ github.event.workflow_run.head_branch }}
|
ref: ${{ github.event.workflow_run.head_branch }}
|
||||||
|
|
9017
package-lock.json
generated
9017
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "homebridge-prometheus-exporter",
|
"name": "homebridge-prometheus-exporter",
|
||||||
"version": "1.0.5",
|
"version": "1.0.4",
|
||||||
"description": "Prometheus exporter for homebridge accessories.",
|
"description": "Prometheus exporter for homebridge accessories.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -35,11 +35,10 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/globals": "^29.3.0",
|
"@jest/globals": "^29.3.0",
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/node": "^20.2.3",
|
"@types/node": "^18.11.9",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
||||||
"@typescript-eslint/parser": "^5.42.0",
|
"@typescript-eslint/parser": "^5.42.0",
|
||||||
"array.prototype.flatmap": "^1.3.1",
|
|
||||||
"eslint": "^8.0.1",
|
"eslint": "^8.0.1",
|
||||||
"eslint-import-resolver-typescript": "^3.5.2",
|
"eslint-import-resolver-typescript": "^3.5.2",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
@ -49,14 +48,14 @@
|
||||||
"homebridge-cmdswitch2": "^0.2.10",
|
"homebridge-cmdswitch2": "^0.2.10",
|
||||||
"jest": "^29.3.0",
|
"jest": "^29.3.0",
|
||||||
"json-schema-to-zod": "^0.6.0",
|
"json-schema-to-zod": "^0.6.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^2.0.13",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"release-it": "^16.0.0",
|
"release-it": "^15.5.0",
|
||||||
"rimraf": "^5.0.0",
|
"rimraf": "^3.0.2",
|
||||||
"supertest": "^6.3.1",
|
"supertest": "^6.3.1",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"ts-node": "^10.3.0",
|
"ts-node": "^10.3.0",
|
||||||
"typescript": "^5.0.2"
|
"typescript": "^4.4.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/auth": "^4.1.0",
|
"@fastify/auth": "^4.1.0",
|
||||||
|
|
5
src/ambient.d.ts
vendored
5
src/ambient.d.ts
vendored
|
@ -14,6 +14,11 @@ declare module 'hap-node-client' {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Workaround for "node_modules/hap-nodejs/dist/lib/Advertiser.d.ts:5:29 - error TS7016: Could not find a declaration file for module '@homebridge/dbus-native'. '…/node_modules/@homebridge/dbus-native/index.js' implicitly has an 'any' type."
|
||||||
|
declare module '@homebridge/dbus-native' {
|
||||||
|
type InvokeError = unknown
|
||||||
|
}
|
||||||
|
|
||||||
declare module 'array.prototype.group' {
|
declare module 'array.prototype.group' {
|
||||||
function shim(): void
|
function shim(): void
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,14 @@ export class MetricsRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
render(metrics: Metric[]): string {
|
render(metrics: Metric[]): string {
|
||||||
return (
|
return Object.entries(metrics.sort().group((metric) => this.metricName(metric.name)))
|
||||||
Object.entries(metrics.sort().group((metric) => this.metricName(metric.name)))
|
.map(([name, metrics]) => {
|
||||||
.map(([name, metrics]) => {
|
return [
|
||||||
return [
|
`# TYPE ${name} ${name.endsWith('_total') ? 'counter' : 'gauge'}`,
|
||||||
`# TYPE ${name} ${name.endsWith('_total') ? 'counter' : 'gauge'}`,
|
metrics.map((metric) => this.formatMetric(metric)).join('\n'),
|
||||||
metrics.map((metric) => this.formatMetric(metric)).join('\n'),
|
].join('\n')
|
||||||
].join('\n')
|
})
|
||||||
})
|
.join('\n\n')
|
||||||
.join('\n\n') + '\n'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private formatMetric(metric: Metric): string {
|
private formatMetric(metric: Metric): string {
|
||||||
|
|
|
@ -74,7 +74,6 @@ describe('Fastify HTTP adapter', () => {
|
||||||
'',
|
'',
|
||||||
'# TYPE homebridge_something_total counter',
|
'# TYPE homebridge_something_total counter',
|
||||||
'homebridge_something_total{name="counter"} 100 1577836800000',
|
'homebridge_something_total{name="counter"} 100 1577836800000',
|
||||||
'',
|
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -122,7 +121,6 @@ describe('Fastify HTTP adapter', () => {
|
||||||
'',
|
'',
|
||||||
'# TYPE homebridge_something_total counter',
|
'# TYPE homebridge_something_total counter',
|
||||||
'homebridge_something_total{name="counter"} 100 1577836800000',
|
'homebridge_something_total{name="counter"} 100 1577836800000',
|
||||||
'',
|
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,16 +8,14 @@ describe('Render prometheus metrics', () => {
|
||||||
test('Renders simple metric', () => {
|
test('Renders simple metric', () => {
|
||||||
expect(renderer.render([new Metric('metric', 0.000001)])).toEqual(
|
expect(renderer.render([new Metric('metric', 0.000001)])).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric 0.000001
|
prefix_metric 0.000001`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Renders simple metric with timestamp', () => {
|
test('Renders simple metric with timestamp', () => {
|
||||||
expect(renderer.render([new Metric('metric', 0.000001, new Date('2000-01-01 00:00:00 UTC'))])).toEqual(
|
expect(renderer.render([new Metric('metric', 0.000001, new Date('2000-01-01 00:00:00 UTC'))])).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric 0.000001 946684800000
|
prefix_metric 0.000001 946684800000`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -28,8 +26,7 @@ prefix_metric 0.000001 946684800000
|
||||||
]),
|
]),
|
||||||
).toEqual(
|
).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric{label="Some Label"} 0.000001 946684800000
|
prefix_metric{label="Some Label"} 0.000001 946684800000`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -41,8 +38,7 @@ prefix_metric{label="Some Label"} 0.000001 946684800000
|
||||||
]),
|
]),
|
||||||
).toEqual(
|
).toEqual(
|
||||||
`# TYPE prefix_some_metric_total counter
|
`# TYPE prefix_some_metric_total counter
|
||||||
prefix_some_metric_total{label="Some Label"} 42 946684800000
|
prefix_some_metric_total{label="Some Label"} 42 946684800000`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -60,40 +56,35 @@ prefix_some_gauge 10 946684800000
|
||||||
prefix_some_gauge 20 946684800000
|
prefix_some_gauge 20 946684800000
|
||||||
|
|
||||||
# TYPE prefix_another_gauge gauge
|
# TYPE prefix_another_gauge gauge
|
||||||
prefix_another_gauge 30 946684800000
|
prefix_another_gauge 30 946684800000`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Sanitizes metric names', () => {
|
test('Sanitizes metric names', () => {
|
||||||
expect(renderer.render([new Metric('mätric name', 0)])).toEqual(
|
expect(renderer.render([new Metric('mätric name', 0)])).toEqual(
|
||||||
`# TYPE prefix_m_tric_name gauge
|
`# TYPE prefix_m_tric_name gauge
|
||||||
prefix_m_tric_name 0
|
prefix_m_tric_name 0`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Sanitizes label names', () => {
|
test('Sanitizes label names', () => {
|
||||||
expect(renderer.render([new Metric('metric', 0, null, { 'yet another label': 'foo' })])).toEqual(
|
expect(renderer.render([new Metric('metric', 0, null, { 'yet another label': 'foo' })])).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric{yet_another_label="foo"} 0
|
prefix_metric{yet_another_label="foo"} 0`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Escapes newlines in attribute value', () => {
|
test('Escapes newlines in attribute value', () => {
|
||||||
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo\nbar' })])).toEqual(
|
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo\nbar' })])).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric{label="foo\\nbar"} 0
|
prefix_metric{label="foo\\nbar"} 0`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Escapes quotes in attribute value', () => {
|
test('Escapes quotes in attribute value', () => {
|
||||||
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo"bar' })])).toEqual(
|
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo"bar' })])).toEqual(
|
||||||
`# TYPE prefix_metric gauge
|
`# TYPE prefix_metric gauge
|
||||||
prefix_metric{label="foo\\"bar"} 0
|
prefix_metric{label="foo\\"bar"} 0`,
|
||||||
`,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"rootDir": "./",
|
"rootDir": "./",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"verbatimModuleSyntax": false,
|
"importsNotUsedAsValues": "error",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"tsBuildInfoFile": ".tsbuildinfo",
|
"tsBuildInfoFile": ".tsbuildinfo",
|
||||||
|
|
Loading…
Add table
Reference in a new issue