зеркало из https://github.com/microsoft/jacdac-ts.git
patch: Azure function to serve device model function (#245)
* try to build that function * skip lib check * fix proxy settings * more scafoling * npm install * add model generation * patch add sdmi support to CLI * updated parsing code * azure goo * normalize parse * updated path * fix more issues * another fix
This commit is contained in:
Родитель
14d78e1c40
Коммит
046cf22581
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
|
"ms-azuretools.vscode-azurefunctions",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"silvenon.mdx"
|
"silvenon.mdx"
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "pwa-node",
|
||||||
|
"name": "cli sdmi",
|
||||||
|
"request": "launch",
|
||||||
|
"skipFiles": ["<node_internals>/**"],
|
||||||
|
"program": "${workspaceFolder}/dist/jacdac-cli.js",
|
||||||
|
"args": ["--sdmi=dtmi/jacdac/devices/x1473a263/x12fc91032-1.json"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "pwa-node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "cli usb",
|
||||||
|
"skipFiles": ["<node_internals>/**"],
|
||||||
|
"program": "${workspaceFolder}/dist/jacdac-cli.js",
|
||||||
|
"args": ["--usb=true"],
|
||||||
|
"outFiles": ["${workspaceFolder}/dist/*.js"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Attach to Node Functions",
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 9229,
|
||||||
|
"preLaunchTask": "func: host start"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -10,5 +10,10 @@
|
||||||
},
|
},
|
||||||
"[jsonc]": {
|
"[jsonc]": {
|
||||||
"editor.defaultFormatter": "vscode.json-language-features"
|
"editor.defaultFormatter": "vscode.json-language-features"
|
||||||
}
|
},
|
||||||
|
"azureFunctions.deploySubpath": "device-models-function",
|
||||||
|
"azureFunctions.postDeployTask": "npm install (functions)",
|
||||||
|
"azureFunctions.projectLanguage": "TypeScript",
|
||||||
|
"azureFunctions.projectRuntime": "~3",
|
||||||
|
"debug.internalConsoleOptions": "neverOpen",
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "func",
|
||||||
|
"command": "host start",
|
||||||
|
"problemMatcher": "$func-node-watch",
|
||||||
|
"isBackground": true,
|
||||||
|
"dependsOn": "npm build (functions)",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/device-models-function"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "npm build (functions)",
|
||||||
|
"command": "npm run build",
|
||||||
|
"dependsOn": "npm install (functions)",
|
||||||
|
"problemMatcher": "$tsc",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/device-models-function"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "npm install (functions)",
|
||||||
|
"command": "yarn install --frozen-lockfile",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/device-models-function"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"label": "npm prune (functions)",
|
||||||
|
"command": "npm prune --production",
|
||||||
|
"dependsOn": "npm build (functions)",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/device-models-function"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
*.js.map
|
||||||
|
*.ts
|
||||||
|
.git*
|
||||||
|
.vscode
|
||||||
|
local.settings.json
|
||||||
|
test
|
||||||
|
tsconfig.json
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TypeScript output
|
||||||
|
dist
|
||||||
|
out
|
||||||
|
|
||||||
|
# Azure Functions artifacts
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
appsettings.json
|
||||||
|
local.settings.json
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"authLevel": "anonymous",
|
||||||
|
"type": "httpTrigger",
|
||||||
|
"direction": "in",
|
||||||
|
"name": "req",
|
||||||
|
"route": "{*dtmi}",
|
||||||
|
"methods": [
|
||||||
|
"get",
|
||||||
|
"post"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "http",
|
||||||
|
"direction": "out",
|
||||||
|
"name": "res"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scriptFile": "../dist/dtmi/index.js"
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { AzureFunction, Context } from "@azure/functions"
|
||||||
|
import { routeToDTDL } from "jacdac-ts"
|
||||||
|
|
||||||
|
const httpTrigger: AzureFunction = async function (
|
||||||
|
context: Context
|
||||||
|
): Promise<void> {
|
||||||
|
const { bindingData } = context
|
||||||
|
const dtmi = bindingData.dtmi as string
|
||||||
|
const dtdl = routeToDTDL(dtmi)
|
||||||
|
context.res = {
|
||||||
|
status: dtdl ? 200 : 404,
|
||||||
|
body: dtdl ? JSON.stringify(dtdl) : undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default httpTrigger
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"version": "2.0",
|
||||||
|
"logging": {
|
||||||
|
"applicationInsights": {
|
||||||
|
"samplingSettings": {
|
||||||
|
"isEnabled": true,
|
||||||
|
"excludedTypes": "Request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"http": {
|
||||||
|
"routePrefix": "dtmi/jacdac"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extensionBundle": {
|
||||||
|
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||||
|
"version": "[2.*, 3.0.0)"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "device-models-function",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"watch": "tsc -w",
|
||||||
|
"prestart": "npm run build",
|
||||||
|
"start": "func start",
|
||||||
|
"test": "echo \"No tests yet...\""
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jacdac-ts": "latest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@azure/functions": "^1.2.3",
|
||||||
|
"typescript": "^4.3.5"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/proxies",
|
||||||
|
"proxies": {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es6",
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": ".",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@azure/functions@^1.2.3":
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@azure/functions/-/functions-1.2.3.tgz#65765837e7319eedffbf8a971cb2f78d4e043d54"
|
||||||
|
integrity sha512-dZITbYPNg6ay6ngcCOjRUh1wDhlFITS0zIkqplyH5KfKEAVPooaoaye5mUFnR+WP9WdGRjlNXyl/y2tgWKHcRg==
|
||||||
|
|
||||||
|
"@types/node@^16.7.1":
|
||||||
|
version "16.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0"
|
||||||
|
integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==
|
||||||
|
|
||||||
|
"@types/w3c-web-serial@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/w3c-web-serial/-/w3c-web-serial-1.0.2.tgz#8bf21f90b40dda6d2e2e6b188417b6bd66525d03"
|
||||||
|
integrity sha512-Ftx4BtLxgAnel7V7GbHylCYjSq827A+jeEE3SnTS7huCGUN0pSwUn+CchTCT9TkZj9w+NVMUq4Bk2R0GvUNmAQ==
|
||||||
|
|
||||||
|
"@types/w3c-web-usb@^1.0.5":
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/w3c-web-usb/-/w3c-web-usb-1.0.5.tgz#90284d17f35de981670c85d29053ae8b88fa5543"
|
||||||
|
integrity sha512-dYolx2XWesl1TMu+1BjtjU6eC6c2zZ2VDKhjU4f/mtR3+UBfMW6h1tPCQt7leY5Y8JBg0Fe/mMnoDMkPPNX9sw==
|
||||||
|
|
||||||
|
"@types/web-bluetooth@^0.0.11":
|
||||||
|
version "0.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.11.tgz#2dc7ae7a809b70723e064b58245103028d5ea616"
|
||||||
|
integrity sha512-2CF3Kk2Rcvg/c2QzO7mXUhY7eL9CC3aKzrF+dNWNmp7Q8bmlvjmUM1nFPMSngawdJ+CcIdu8eJlQRytBgAZR9w==
|
||||||
|
|
||||||
|
fs-extra@^10.0.0:
|
||||||
|
version "10.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
|
||||||
|
integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
|
||||||
|
dependencies:
|
||||||
|
graceful-fs "^4.2.0"
|
||||||
|
jsonfile "^6.0.1"
|
||||||
|
universalify "^2.0.0"
|
||||||
|
|
||||||
|
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||||
|
version "4.2.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||||
|
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
||||||
|
|
||||||
|
jacdac-ts@latest:
|
||||||
|
version "1.14.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/jacdac-ts/-/jacdac-ts-1.14.19.tgz#34a593e6a09526bbb0ca0182b0b2f736684caef4"
|
||||||
|
integrity sha512-TUqQYkAyHpACceTQ2sNUe6z45LgDleo/zHt8KDK1hPd+lzL1+1BsGFSkOScUO/UFdRfsyG+4YhJq8HzvXV3peQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "^16.7.1"
|
||||||
|
"@types/w3c-web-serial" "^1.0.2"
|
||||||
|
"@types/w3c-web-usb" "^1.0.5"
|
||||||
|
"@types/web-bluetooth" "^0.0.11"
|
||||||
|
fs-extra "^10.0.0"
|
||||||
|
regenerator-runtime "^0.13.9"
|
||||||
|
|
||||||
|
jsonfile@^6.0.1:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||||
|
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||||
|
dependencies:
|
||||||
|
universalify "^2.0.0"
|
||||||
|
optionalDependencies:
|
||||||
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
|
regenerator-runtime@^0.13.9:
|
||||||
|
version "0.13.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||||
|
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||||
|
|
||||||
|
typescript@^4.3.5:
|
||||||
|
version "4.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
|
||||||
|
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
|
||||||
|
|
||||||
|
universalify@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||||
|
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
|
@ -1 +1 @@
|
||||||
Subproject commit 794589fb18ccb016e163510026284e4925339b40
|
Subproject commit 92a61228187b225e4dcd5df125ae8d14be8dc870
|
|
@ -19,7 +19,7 @@ import {
|
||||||
serviceSpecificationFromClassIdentifier,
|
serviceSpecificationFromClassIdentifier,
|
||||||
serviceSpecifications,
|
serviceSpecifications,
|
||||||
} from "../jdom/spec"
|
} from "../jdom/spec"
|
||||||
import { uniqueMap } from "../jdom/utils"
|
import { arrayConcatMany, uniqueMap } from "../jdom/utils"
|
||||||
import {
|
import {
|
||||||
arraySchema,
|
arraySchema,
|
||||||
DTDLContent,
|
DTDLContent,
|
||||||
|
@ -31,10 +31,14 @@ import {
|
||||||
objectSchema,
|
objectSchema,
|
||||||
} from "./dtdl"
|
} from "./dtdl"
|
||||||
|
|
||||||
|
export const DTDL_JACDAC_PATH = "jacdac"
|
||||||
|
export const DTDL_SERVICES_PATH = "services"
|
||||||
|
export const DTDL_DEVICES_PATH = "devices"
|
||||||
|
|
||||||
// https://github.com/Azure/digital-twin-model-identifier
|
// https://github.com/Azure/digital-twin-model-identifier
|
||||||
// ^dtmi:(?:_+[A-Za-z0-9]|[A-Za-z])(?:[A-Za-z0-9_]*[A-Za-z0-9])?(?::(?:_+[A-Za-z0-9]|[A-Za-z])(?:[A-Za-z0-9_]*[A-Za-z0-9])?)*;[1-9][0-9]{0,8}$
|
// ^dtmi:(?:_+[A-Za-z0-9]|[A-Za-z])(?:[A-Za-z0-9_]*[A-Za-z0-9])?(?::(?:_+[A-Za-z0-9]|[A-Za-z])(?:[A-Za-z0-9_]*[A-Za-z0-9])?)*;[1-9][0-9]{0,8}$
|
||||||
export function toDTMI(segments: (string | number)[], version?: number) {
|
export function toDTMI(segments: (string | number)[], version?: number) {
|
||||||
return `dtmi:jacdac:${[...segments]
|
return `dtmi:${DTDL_JACDAC_PATH}:${[...segments]
|
||||||
.map(seg =>
|
.map(seg =>
|
||||||
seg === undefined
|
seg === undefined
|
||||||
? "???"
|
? "???"
|
||||||
|
@ -391,11 +395,11 @@ export function serviceSpecificationDTMI(
|
||||||
srv: jdspec.ServiceSpec,
|
srv: jdspec.ServiceSpec,
|
||||||
customPath?: string
|
customPath?: string
|
||||||
) {
|
) {
|
||||||
return toDTMI([customPath || "services", srv.classIdentifier])
|
return toDTMI([customPath || DTDL_SERVICES_PATH, srv.classIdentifier])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deviceSpecificationDTMI(dev: jdspec.DeviceSpec) {
|
export function deviceSpecificationDTMI(dev: jdspec.DeviceSpec) {
|
||||||
return toDTMI(["devices", dev.id.replace(/-/g, ":")])
|
return toDTMI([DTDL_DEVICES_PATH, dev.id.replace(/-/g, ":")])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DTMIToRoute(dtmi: string) {
|
export function DTMIToRoute(dtmi: string) {
|
||||||
|
@ -404,6 +408,75 @@ export function DTMIToRoute(dtmi: string) {
|
||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseRoute(route: string, normalize?: boolean) {
|
||||||
|
const [, path, version] = /(.*)-(\d+)\.json$/.exec(route)
|
||||||
|
const parts = path.split("/")
|
||||||
|
if (normalize)
|
||||||
|
while (parts[0] === "dtmi" || parts[0] === DTDL_JACDAC_PATH)
|
||||||
|
parts.shift()
|
||||||
|
return { version, parts }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function routeToDTMI(route: string) {
|
||||||
|
const { parts, version } = parseRoute(route)
|
||||||
|
if (parts[0] !== "dtmi") parts.unshift("dtmi")
|
||||||
|
if (parts[1] !== DTDL_JACDAC_PATH) parts.splice(1, 0, DTDL_JACDAC_PATH)
|
||||||
|
return `${parts.join(":")}-${version}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serviceRouteToDTDL(route: string) {
|
||||||
|
const { parts } = parseRoute(route, true)
|
||||||
|
if (parts[0] !== DTDL_SERVICES_PATH) throw Error("invalid route")
|
||||||
|
const serviceClass = parseInt("0" + parts[1], 16)
|
||||||
|
const specification = serviceSpecificationFromClassIdentifier(serviceClass)
|
||||||
|
const dtdl = serviceSpecificationToDTDL(specification)
|
||||||
|
return dtdl
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encodedDeviceRouteToDTDL(route: string) {
|
||||||
|
const { parts } = parseRoute(route, true)
|
||||||
|
if (parts[0] !== DTDL_DEVICES_PATH) throw Error("invalid route")
|
||||||
|
const services = parts.slice(1).map(part => {
|
||||||
|
const m = /^x(\w{8,8})(\d*)$/.exec(part)
|
||||||
|
return {
|
||||||
|
service: serviceSpecificationFromClassIdentifier(
|
||||||
|
parseInt(m[1], 16)
|
||||||
|
),
|
||||||
|
occurance: m[2] ? parseInt(m[2]) : 1,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const dtdl: DTDLInterface = {
|
||||||
|
"@type": "Interface",
|
||||||
|
"@id": routeToDTMI(route),
|
||||||
|
displayName: route,
|
||||||
|
contents: arrayConcatMany(
|
||||||
|
services.map(({ occurance, service }) =>
|
||||||
|
Array(occurance)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, i) =>
|
||||||
|
serviceSpecificationToComponent(
|
||||||
|
service,
|
||||||
|
`${service.shortName}${i}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"@context": DTDL_CONTEXT,
|
||||||
|
}
|
||||||
|
return dtdl
|
||||||
|
}
|
||||||
|
|
||||||
|
const routes: Record<string, (route: string) => DTDLContent> = {
|
||||||
|
services: serviceRouteToDTDL,
|
||||||
|
devices: encodedDeviceRouteToDTDL,
|
||||||
|
}
|
||||||
|
export function routeToDTDL(route: string) {
|
||||||
|
const { parts } = parseRoute(route, true)
|
||||||
|
const path = parts[0]
|
||||||
|
const handler = routes[path]
|
||||||
|
return handler?.(route)
|
||||||
|
}
|
||||||
|
|
||||||
export function deviceSpecificationToDTDL(
|
export function deviceSpecificationToDTDL(
|
||||||
dev: jdspec.DeviceSpec,
|
dev: jdspec.DeviceSpec,
|
||||||
options?: DTDLGenerationOptions
|
options?: DTDLGenerationOptions
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { createUSBTransport } from "../jdom/transport/usb"
|
||||||
import { createNodeUSBOptions } from "../jdom/transport/nodewebusb"
|
import { createNodeUSBOptions } from "../jdom/transport/nodewebusb"
|
||||||
import {
|
import {
|
||||||
deviceSpecificationToDTDL,
|
deviceSpecificationToDTDL,
|
||||||
|
routeToDTDL,
|
||||||
serviceSpecificationsWithDTDL,
|
serviceSpecificationsWithDTDL,
|
||||||
serviceSpecificationToDTDL,
|
serviceSpecificationToDTDL,
|
||||||
} from "../azure-iot/dtdlspec"
|
} from "../azure-iot/dtdlspec"
|
||||||
|
@ -27,6 +28,7 @@ interface OptionsType {
|
||||||
usb?: boolean
|
usb?: boolean
|
||||||
packets?: boolean
|
packets?: boolean
|
||||||
dtdl?: boolean
|
dtdl?: boolean
|
||||||
|
sdmi?: string
|
||||||
devices?: string
|
devices?: string
|
||||||
services?: string
|
services?: string
|
||||||
rm?: boolean
|
rm?: boolean
|
||||||
|
@ -37,12 +39,20 @@ const options: OptionsType = cli.parse({
|
||||||
usb: ["u", "listen to Jacdac over USB", true],
|
usb: ["u", "listen to Jacdac over USB", true],
|
||||||
packets: ["p", "show/hide all packets", true],
|
packets: ["p", "show/hide all packets", true],
|
||||||
dtdl: [false, "generate DTDL files", "file"],
|
dtdl: [false, "generate DTDL files", "file"],
|
||||||
|
sdmi: [false, "generate dynamic DTDL files", "string"],
|
||||||
devices: ["d", "regular expression filter for devices", "string"],
|
devices: ["d", "regular expression filter for devices", "string"],
|
||||||
services: [false, "regular expression filter for services", "string"],
|
services: [false, "regular expression filter for services", "string"],
|
||||||
rm: [false, "delete files from output folder", true],
|
rm: [false, "delete files from output folder", true],
|
||||||
parse: ["l", "parse logic analyzer log file", "string"],
|
parse: ["l", "parse logic analyzer log file", "string"],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// SDMI
|
||||||
|
if (options.sdmi) {
|
||||||
|
console.log(`sdmi: generate DTDL for ${options.sdmi}`)
|
||||||
|
const dtdl = routeToDTDL(options.sdmi)
|
||||||
|
console.log(dtdl)
|
||||||
|
}
|
||||||
|
|
||||||
// DTDL
|
// DTDL
|
||||||
if (options.dtdl) {
|
if (options.dtdl) {
|
||||||
cli.info(`generating DTDL models`)
|
cli.info(`generating DTDL models`)
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export * from "./jdom/jacdac-jdom"
|
export * from "./jdom/jacdac-jdom"
|
||||||
export * from "./servers/jacdac-servers"
|
export * from "./servers/jacdac-servers"
|
||||||
|
export * from "./azure-iot/jacdac-azure-iot"
|
|
@ -201,11 +201,7 @@ export function serviceSpecificationFromName(
|
||||||
export function serviceSpecificationFromClassIdentifier(
|
export function serviceSpecificationFromClassIdentifier(
|
||||||
classIdentifier: number
|
classIdentifier: number
|
||||||
): jdspec.ServiceSpec {
|
): jdspec.ServiceSpec {
|
||||||
if (
|
if (isNaN(classIdentifier))
|
||||||
classIdentifier === null ||
|
|
||||||
classIdentifier === undefined ||
|
|
||||||
isNaN(classIdentifier)
|
|
||||||
)
|
|
||||||
return undefined
|
return undefined
|
||||||
return (
|
return (
|
||||||
_serviceSpecifications.find(
|
_serviceSpecifications.find(
|
||||||
|
|
Загрузка…
Ссылка в новой задаче