dev-api: add developer portal, OpenAPI spec, and Flatenbadet case study

- New /developers/ page with API docs, SDKs, pricing, use cases
- OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics
- Case study: Glasskiosken i Flatenbadet — complete ROI analysis
- Updated /order/ with recurring missions and frequency dropdown
This commit is contained in:
Bernt
2026-07-14 15:27:33 +00:00
parent 3c522e39f0
commit 1a12fb870b
6296 changed files with 911440 additions and 55607 deletions
@@ -0,0 +1,18 @@
import * as fs from 'fs'
import { once } from 'events'
import { Transform } from 'stream'
async function run (opts: { destination?: fs.PathLike }): Promise<Transform> {
if (!opts.destination) throw new Error('kaboom')
const stream = fs.createWriteStream(opts.destination)
await once(stream, 'open')
const t = new Transform({
transform (chunk, enc, cb) {
setImmediate(cb, null, chunk.toString().toUpperCase())
}
})
t.pipe(stream)
return t
}
export default run
@@ -0,0 +1,11 @@
import * as fs from 'fs'
import { once } from 'events'
async function run (opts: { destination?: fs.PathLike }): Promise<fs.WriteStream> {
if (!opts.destination) throw new Error('kaboom')
const stream = fs.createWriteStream(opts.destination, { encoding: 'utf8' })
await once(stream, 'open')
return stream
}
export default run
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env node
const execa = require('execa')
const fs = require('fs')
const existsSync = fs.existsSync
const stat = fs.promises.stat
// Hardcoded parameters
const esVersions = ['es5', 'es6', 'es2017', 'esnext']
const filesToTranspile = ['to-file-transport.ts']
async function transpile () {
process.chdir(__dirname)
for (const sourceFileName of filesToTranspile) {
const sourceStat = await stat(sourceFileName)
for (const esVersion of esVersions) {
const intermediateFileName = sourceFileName.replace(/\.ts$/, '.js')
const targetFileName = sourceFileName.replace(/\.ts$/, `.${esVersion}.cjs`)
const shouldTranspile = !existsSync(targetFileName) || (await stat(targetFileName)).mtimeMs < sourceStat.mtimeMs
if (shouldTranspile) {
await execa('tsc', ['--target', esVersion, '--module', 'commonjs', sourceFileName])
await execa('mv', [intermediateFileName, targetFileName])
}
}
}
}
transpile().catch(err => {
process.exitCode = 1
throw err
})
@@ -0,0 +1,15 @@
import pino from '../../..'
import { join } from 'path'
const transport = pino.transport({
target: join(__dirname, 'to-file-transport-with-transform.ts'),
options: {
destination: process.argv[2]
}
})
const logger = pino(transport)
logger.info('Hello')
logger.info('World')
process.exit(0)
@@ -0,0 +1,10 @@
import pino from '../../..'
const transport = pino.transport({
target: 'pino/file'
})
const logger = pino(transport)
logger.info('Hello')
process.exit(0)
@@ -0,0 +1,11 @@
import pino from '../../..'
const transport = pino.transport({
target: 'pino/file'
})
const logger = pino(transport)
transport.on('ready', function () {
logger.info('Hello')
process.exit(0)
})
@@ -0,0 +1,8 @@
import { join } from 'path'
import pino from '../../..'
const transport = pino.transport({
target: join(__dirname, 'transport-worker.ts')
})
const logger = pino(transport)
logger.info('Hello')
@@ -0,0 +1,8 @@
import pino from '../../..'
const transport = pino.transport({
target: 'pino/file',
options: { destination: '1' }
})
const logger = pino(transport)
logger.info('Hello')
@@ -0,0 +1,14 @@
import { Writable } from 'stream'
export default (): Writable => {
const myTransportStream = new Writable({
autoDestroy: true,
write (chunk, _enc, cb) {
console.log(chunk.toString())
cb()
},
defaultEncoding: 'utf8'
})
return myTransportStream
}