├── .dockerignore
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .github
├── CODEOWNERS
└── workflows
│ ├── browser-test.yml
│ └── ci.yaml
├── .gitignore
├── .husky
├── pre-commit
└── pre-push
├── .prettierignore
├── .prettierrc.json
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── API.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.md
├── NOTICE.md
├── README.md
├── SECURITY.md
├── codecov.yml
├── examples
├── browser
│ ├── counter.html
│ ├── counter.js
│ ├── images
│ │ └── coffee-161112.svg
│ ├── index.html
│ ├── index.js
│ ├── smart-coffee-machine.html
│ ├── smart-coffee-machine.js
│ └── styles.css
├── quickstart
│ ├── README.md
│ ├── presence-sensor.js
│ ├── simple-coffee-machine.js
│ └── smart-clock.js
├── scripts
│ ├── $DO_NOT_EDIT_JS_FILES.md
│ ├── countdown.js
│ ├── counter-client.js
│ ├── counter.js
│ ├── smart-coffee-machine-client.conf.json
│ ├── smart-coffee-machine-client.js
│ ├── smart-coffee-machine.js
│ └── wot-servient.conf.json
├── security
│ ├── README.md
│ ├── certificate.pem
│ ├── oauth
│ │ ├── README.md
│ │ ├── consumer.js
│ │ ├── exposer.js
│ │ ├── memory-model.js
│ │ ├── package.json
│ │ ├── server.js
│ │ ├── wot-client-servient-conf.json
│ │ └── wot-server-servient-conf.json
│ ├── privatekey.pem
│ └── wot-servient.conf.json
├── templates
│ └── exposed-thing
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ └── base.ts
│ │ └── tsconfig.json
└── testthing
│ ├── $DO_NOT_EDIT_JS_FILES.md
│ ├── testclient.js
│ └── testthing.js
├── license.template.txt
├── package-lock.json
├── package.json
├── packages
├── binding-coap
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── coap-client-factory.ts
│ │ ├── coap-client.ts
│ │ ├── coap-server.ts
│ │ ├── coap.ts
│ │ ├── coaps-client-factory.ts
│ │ ├── coaps-client.ts
│ │ ├── mdns-introducer.ts
│ │ └── util.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── coap-client-test.ts
│ │ ├── coap-server-test.ts
│ │ ├── coap-types-test.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-file
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── file-client-factory.ts
│ │ ├── file-client.ts
│ │ └── file.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ └── file-client-test.ts
│ └── tsconfig.json
├── binding-http
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── codecs
│ │ │ └── tuya-codec.ts
│ │ ├── credential.ts
│ │ ├── http-browser.ts
│ │ ├── http-client-browser.ts
│ │ ├── http-client-factory.ts
│ │ ├── http-client-impl.ts
│ │ ├── http-client.ts
│ │ ├── http-server-middleware.ts
│ │ ├── http-server.ts
│ │ ├── http.ts
│ │ ├── https-client-factory.ts
│ │ ├── oauth-manager.ts
│ │ ├── oauth-token-validation.ts
│ │ ├── routes
│ │ │ ├── action.ts
│ │ │ ├── common.ts
│ │ │ ├── event.ts
│ │ │ ├── properties.ts
│ │ │ ├── property-observe.ts
│ │ │ ├── property.ts
│ │ │ ├── thing-description.ts
│ │ │ └── things.ts
│ │ └── subscription-protocols.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── credential-test.ts
│ │ ├── http-client-basic-test.ts
│ │ ├── http-client-oauth-tests.ts
│ │ ├── http-client-test.ts
│ │ ├── http-server-oauth-tests.ts
│ │ ├── http-server-test.ts
│ │ ├── memory-model.ts
│ │ ├── oauth-token-validation-tests.ts
│ │ ├── server.cert
│ │ ├── server.key
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-mbus
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── mbus-client-factory.ts
│ │ ├── mbus-client.ts
│ │ ├── mbus-connection.ts
│ │ ├── mbus.ts
│ │ └── node-mbus.d.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── mbus-client-test.ts
│ │ ├── mbus-connection-test.ts
│ │ ├── test-servient.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-modbus
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── modbus-client-factory.ts
│ │ ├── modbus-client.ts
│ │ ├── modbus-connection.ts
│ │ ├── modbus.ts
│ │ └── utils.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── modbus-client-test.ts
│ │ ├── modbus-connection-test.ts
│ │ ├── test-modbus-server.ts
│ │ ├── test-servient.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-mqtt
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── mqtt-broker-server.ts
│ │ ├── mqtt-client-factory.ts
│ │ ├── mqtt-client.ts
│ │ ├── mqtt-message-pool.ts
│ │ ├── mqtt.ts
│ │ ├── mqtts-client-factory.ts
│ │ └── util.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── mqtt-broker-server-interaction-test.integration.ts
│ │ ├── mqtt-client-subscribe-test.integration.ts
│ │ ├── mqtt-client-subscribe-test.unit.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-netconf
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── async-node-netconf.ts
│ │ ├── codecs
│ │ │ └── netconf-codec.ts
│ │ ├── netconf-client-factory.ts
│ │ ├── netconf-client.ts
│ │ ├── netconf.ts
│ │ └── xpath2json.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── netconf-client-test.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── binding-opcua
│ ├── .eslintrc.json
│ ├── .mocharc.yml
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── codec.ts
│ │ ├── factory.ts
│ │ ├── index.ts
│ │ └── opcua-protocol-client.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── client-test.ts
│ │ ├── fixture
│ │ │ └── basic-opcua-server.ts
│ │ ├── full-opcua-thing-test.ts
│ │ ├── opcua-codec-test.ts
│ │ ├── opcua-href-test.ts
│ │ └── schema-validation-test.ts
│ └── tsconfig.json
├── binding-websockets
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── ws-browser.ts
│ │ ├── ws-client-factory.ts
│ │ ├── ws-client.ts
│ │ ├── ws-server.ts
│ │ ├── ws.ts
│ │ └── wss-client-factory.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── tsconfig.json
│ │ └── ws-tests.ts
│ └── tsconfig.json
├── browser-bundle
│ ├── .gitignore
│ ├── README.md
│ ├── esbuild.js
│ ├── index.ts
│ ├── package.json
│ ├── test
│ │ ├── main.js
│ │ └── resources
│ │ │ └── test-thing.tm.json
│ ├── tsconfig.json
│ └── web-test-runner.config.mjs
├── cli
│ ├── .eslintrc.json
│ ├── README.md
│ ├── bin
│ │ └── index.js
│ ├── package.json
│ ├── src
│ │ ├── cli-default-servient.ts
│ │ ├── cli.ts
│ │ └── wot-servient-schema.conf.json
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── RuntimeTest.ts
│ │ └── tsconfig.json
│ ├── tsconfig.json
│ └── wot-servient.conf.json.md
├── core
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── codecs
│ │ │ ├── base64-codec.ts
│ │ │ ├── cbor-codec.ts
│ │ │ ├── json-codec.ts
│ │ │ ├── octetstream-codec.ts
│ │ │ └── text-codec.ts
│ │ ├── consumed-thing.ts
│ │ ├── content-serdes.ts
│ │ ├── content.ts
│ │ ├── core.ts
│ │ ├── errors.ts
│ │ ├── exposed-thing.ts
│ │ ├── helpers.ts
│ │ ├── interaction-output.ts
│ │ ├── logger.ts
│ │ ├── protocol-helpers.ts
│ │ ├── protocol-interfaces.ts
│ │ ├── protocol-listener-registry.ts
│ │ ├── serdes.ts
│ │ ├── servient.ts
│ │ ├── thing-description.ts
│ │ ├── validation.ts
│ │ └── wot-impl.ts
│ ├── test
│ │ ├── .eslintrc.json
│ │ ├── ClientTest.ts
│ │ ├── ContentSerdesTest.ts
│ │ ├── DiscoveryTest.ts
│ │ ├── HelpersTest.ts
│ │ ├── InteractionOutputTest.ts
│ │ ├── ProtocolHelpersStreamTest.ts
│ │ ├── ProtocolHelpersTest.ts
│ │ ├── ProtocolListenerRegistryTest.ts
│ │ ├── SerDesTest.ts
│ │ ├── ServerTest.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
└── examples
│ ├── .eslintrc.json
│ ├── README.md
│ ├── package.json
│ ├── src
│ ├── bindings
│ │ ├── coap
│ │ │ ├── example-client.ts
│ │ │ └── example-server.ts
│ │ ├── http
│ │ │ ├── example-client.ts
│ │ │ ├── example-server-secure.ts
│ │ │ └── example-server.ts
│ │ └── opcua
│ │ │ ├── demo-opcua-thing-description.ts
│ │ │ ├── demo-opcua1.ts
│ │ │ ├── demo-opcua2.ts
│ │ │ ├── opcua-coffee-machine-demo.ts
│ │ │ └── opcua-coffee-machine-thing-description.ts
│ ├── quickstart
│ │ ├── README.md
│ │ ├── presence-sensor.ts
│ │ ├── simple-coffee-machine.ts
│ │ └── smart-clock.ts
│ ├── scripts
│ │ ├── countdown.ts
│ │ ├── counter-client.ts
│ │ ├── counter.ts
│ │ ├── smart-coffee-machine-client.ts
│ │ └── smart-coffee-machine.ts
│ ├── security
│ │ ├── certificate.pem
│ │ ├── oauth
│ │ │ ├── README.md
│ │ │ ├── consumer.ts
│ │ │ ├── exposer.ts
│ │ │ ├── memory-model.js
│ │ │ ├── package.json
│ │ │ ├── server.js
│ │ │ ├── tsconfig.json
│ │ │ ├── wot-client-servient-conf.json
│ │ │ └── wot-server-servient-conf.json
│ │ └── privatekey.pem
│ └── testthing
│ │ ├── testclient.ts
│ │ └── testthing.ts
│ └── tsconfig.json
├── tsconfig.eslint.json
├── tsconfig.json
└── utils
├── .eslintrc.json
└── check_package_version_consistency.js
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .vscode
3 | .idea/
4 | .nyc_output/
5 | examples
6 | **/node_modules/
7 | node_modules/
8 | coverage/
9 | .*/
10 | tmp/
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [{src,test}/**.{ts,json,js}]
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | indent_style = space
9 | indent_size = 4
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | packages/browser-bundle/web-test-runner.config.mjs
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: "@typescript-eslint/parser",
3 | parserOptions: {
4 | tsconfigRootDir: __dirname,
5 | project: ["./tsconfig.eslint.json"],
6 | },
7 | extends: [
8 | "eslint:recommended",
9 | "standard",
10 | "prettier",
11 | "plugin:@typescript-eslint/recommended",
12 | "plugin:workspaces/recommended",
13 | ],
14 | plugins: ["@typescript-eslint", "unused-imports", "workspaces", "notice"],
15 | env: {
16 | es6: true,
17 | node: true,
18 | },
19 | ignorePatterns: [".eslintrc.js", "dist", "node_modules", "/examples", "bin", "*.js"],
20 | rules: {
21 | "notice/notice": [
22 | "error",
23 | {
24 | mustMatch: "Copyright \\(c\\) [0-9]{0,4} Contributors to the Eclipse Foundation",
25 | templateFile: __dirname + "/license.template.txt",
26 | onNonMatchingHeader: "replace",
27 | },
28 | ],
29 | "@typescript-eslint/no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
30 | "no-use-before-define": "off",
31 | "@typescript-eslint/no-use-before-define": ["error"],
32 | "@typescript-eslint/prefer-nullish-coalescing": "error",
33 | "unused-imports/no-unused-imports": "error",
34 | "@typescript-eslint/strict-boolean-expressions": "error",
35 | "import/no-extraneous-dependencies": "error",
36 | "guard-for-in": "error",
37 | "unused-imports/no-unused-vars": [
38 | "warn",
39 | {
40 | args: "none",
41 | varsIgnorePattern: "Test", // Ignore test suites from unused-imports
42 | },
43 | ],
44 | },
45 | };
46 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Explicitly declare text files we want to always be normalized and converted
5 | # to native line endings on checkout.
6 |
7 | # Declare files that will always have LF line endings on checkout.
8 | *.c text eol=lf
9 | *.css text eol=lf
10 | *.cpp text eol=lf
11 | .editorconfig text eol=lf
12 | .gitattributes text eol=lf
13 | .gitignore text eol=lf
14 | .gitmodules text eol=lf
15 | *.gyp text eol=lf
16 | *.h text eol=lf
17 | *.hpp text eol=lf
18 | *.js text eol=lf
19 | *.ts text eol=lf
20 | *.json text eol=lf
21 | LICENSE text eol=lf
22 | *.md text eol=lf
23 | *.svg text eol=lf
24 | *.sh text eol=lf
25 |
26 | # Declare files that will always have CRLF line endings on checkout.
27 | *.bat text eol=crlf
28 | *.cmd text eol=crlf
29 |
30 | # Denote all files that are truly binary and should not be modified.
31 | *.gif binary
32 | *.jpg binary
33 | *.node binary
34 | *.png binary
35 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Default owners (used as a fallback, last matching pattern takes the most precedence)
2 | * @danielpeintner @relu91
3 |
4 | # CoAP-Binding
5 | /packages/binding-coap/ @JKRhb
6 |
7 | # HTTP-Binding
8 | /packages/binding-http/ @danielpeintner @relu91
9 |
10 | # Mbus-Binding
11 | # /packages/binding-modbus/
12 |
13 | # Modbus-Binding
14 | /packages/binding-modbus/ @relu91
15 |
16 | # MQTT-Binding
17 | /packages/binding-mqtt/ @sebastiankb @egekorkan
18 |
19 | # NETCONF Binding
20 | # /packages/binding-netconf/
21 |
22 | # OPCUA Binding
23 | # /packages/binding-opcua/
24 |
25 | # WebSockets Binding
26 | # /packages/binding-websockets/
27 |
28 | # Browser Bundle
29 | /packages/browser-bundle/ @danielpeintner @relu91
30 |
31 | # CLI
32 | /packages/browser-bundle/ @danielpeintner @relu91 @mkovatsc
33 |
34 | # Core
35 | /packages/core/ @danielpeintner @relu91 @JKRhb
36 |
37 | # TD Tools
38 | /packages/td-tools/ @danielpeintner @relu91
39 |
--------------------------------------------------------------------------------
/.github/workflows/browser-test.yml:
--------------------------------------------------------------------------------
1 | # docs https://playwright.dev/docs/ci-intro#setting-up-github-actions
2 | name: Browser Tests
3 |
4 | on:
5 | workflow_dispatch:
6 | push:
7 | branches: [master]
8 | pull_request:
9 | branches: [master]
10 |
11 | jobs:
12 | test-browser:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Use Node.js 20.x
17 | uses: actions/setup-node@v4
18 | with:
19 | node-version: 20.x
20 | cache: "npm"
21 | - name: Install Dependencies
22 | run: npm ci
23 | - name: Install linux rollup optional dependencies
24 | run: npm i @rollup/rollup-linux-x64-gnu -D
25 | - name: Install Playwright Browsers
26 | run: npx playwright install --with-deps
27 | - name: Build
28 | run: npm run build
29 | - name: Test with browser bundle
30 | timeout-minutes: 2
31 | run: |
32 | npm run test:browser
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | # ignore dist
40 | dist/
41 |
42 | # ignore compiled tests and scratch compiles
43 | test/**/*.js
44 | src/**/*.js
45 |
46 | # ignore private packages
47 | packages/*
48 | !packages/core
49 | !packages/binding-file
50 | !packages/binding-http
51 | !packages/binding-coap
52 | !packages/binding-websockets
53 | !packages/binding-mqtt
54 | !packages/binding-modbus
55 | !packages/binding-opcua
56 | !packages/binding-netconf
57 | !packages/binding-modbus
58 | !packages/binding-mbus
59 | !packages/cli
60 | !packages/browser-bundle
61 | !packages/examples
62 |
63 | # JetBrains IDEs
64 | .idea/
65 |
66 | # tsc build info
67 | tsconfig.tsbuildinfo
68 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run format:quick -- --staged
5 |
--------------------------------------------------------------------------------
/.husky/pre-push:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run test
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | **/dist
3 | coverage
4 | .nyc_output
5 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "printWidth": 120,
4 | "singleQuote": false,
5 | "tabWidth": 4,
6 | "endOfLine": "lf"
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "./node_modules/typescript/lib",
3 | "typescript.referencesCodeLens.enabled": true,
4 | "files.exclude": {
5 | "**/.git": true,
6 | "**/.svn": true,
7 | "**/.hg": true,
8 | "**/.DS_Store": true,
9 | "src/**/*.js": true,
10 | "test/**/*.js": true
11 | },
12 | "files.encoding": "utf8",
13 | "files.eol": "\n",
14 | "files.insertFinalNewline": true,
15 | "files.trimFinalNewlines": true,
16 | "files.trimTrailingWhitespace": true,
17 | "editor.tabSize": 4,
18 | "editor.insertSpaces": true
19 | }
20 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "command": "npm",
6 | "args": ["run"],
7 | "echoCommand": true,
8 | "problemMatcher": "$tsc",
9 | "tasks": [
10 | {
11 | "label": "build",
12 | "type": "shell",
13 | "command": "npm",
14 | "args": ["run", "build"],
15 | "group": "build"
16 | },
17 | {
18 | "label": "test",
19 | "type": "shell",
20 | "command": "npm",
21 | "args": ["run", "test"]
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker.io/library/node:18-alpine as BUILD
2 | RUN apk add --no-cache \
3 | gcc \
4 | g++ \
5 | make \
6 | linux-headers \
7 | udev \
8 | python3
9 |
10 | ## change it to maintain all the dev dependencies
11 | ARG BUILD_ENV=production
12 | WORKDIR /app
13 | COPY ./package.json ./
14 | COPY ./package-lock.json ./
15 | COPY ./tsconfig.json ./
16 | COPY ./packages packages/
17 |
18 | RUN npm install && npm run build
19 |
20 | # now remove dev dependencies by reinstalling for production
21 | # this wil reduce the size of the image built in next steps significantly
22 | RUN if [ "${BUILD_ENV}" = "production" ]; then npm prune --production; fi
23 |
24 | FROM docker.io/library/node:18-alpine
25 |
26 | COPY --from=BUILD /app /app
27 |
28 | WORKDIR /app/packages/cli
29 |
30 | EXPOSE 8080/tcp
31 | EXPOSE 5683/udp
32 |
33 | STOPSIGNAL SIGINT
34 |
35 | ENTRYPOINT [ "node", "dist/cli.js" ]
36 | CMD [ "-h" ]
37 |
38 | ## docker build -t wot-servient ./docker/Dockerfile
39 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 Contributors to the Eclipse Foundation
2 |
3 | See the NOTICE file(s) distributed with this work for additional
4 | information regarding copyright ownership.
5 |
6 | This program and the accompanying materials are made available under the
7 | terms of the Eclipse Public License v. 2.0 which is available at
8 | http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
9 | Document License (2015-05-13) which is available at
10 | https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
11 |
12 | SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
13 |
--------------------------------------------------------------------------------
/NOTICE.md:
--------------------------------------------------------------------------------
1 | # Notices for Eclipse Thingweb
2 |
3 | This content is produced and maintained by the Eclipse Thingweb project.
4 |
5 | - Project home: https://projects.eclipse.org/projects/iot.thingweb
6 |
7 | ## Trademarks
8 |
9 | Eclipse Thingweb is a trademark of the Eclipse Foundation.
10 |
11 | ## Copyright
12 |
13 | All content is the property of the respective authors or their employers. For
14 | more information regarding authorship of content, please consult the listed
15 | source code repository logs.
16 |
17 | Note: The {year} in the copyright statements is the year in which the content
18 | was created (e.g. “2004”). A range of years is not used.
19 |
20 | ## Declared Project Licenses
21 |
22 | This program and the accompanying materials are made available under the terms
23 | of the Eclipse Public License v. 2.0 which is available at
24 | http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and Document
25 | License (2015-05-13) which is available at
26 | https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
27 |
28 | SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
29 |
30 | ## Source Code
31 |
32 | The project maintains the following source code repositories:
33 |
34 | ## Third-party Content
35 |
36 | ## Cryptography
37 |
38 | Content may contain encryption software. The country in which you are currently
39 | may have restrictions on the import, possession, and use, and/or re-export to
40 | another country, of encryption software. BEFORE using any encryption software,
41 | please check the country's laws, regulations and policies concerning the import,
42 | possession, or use, and re-export of encryption software, to see if this is
43 | permitted.
44 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | _ISO 27005 defines vulnerability as:
4 | "A weakness of an asset or group of assets that can be exploited by one or more threats."_
5 |
6 | ## Eclipse Foundation Security Team
7 |
8 | The Eclipse Foundation Security Team provides help and advice to Eclipse projects on security issues and is the first point of contact for handling security vulnerabilities. Members of the Security Team are selected from committers on Eclipse Projects, members of the [Eclipse Architecture Council](https://www.eclipse.org/projects/handbook/#roles-ac), and Eclipse Foundation staff.
9 |
10 | ## Reporting a Security Vulnerability
11 |
12 | Vulnerabilities can be reported either via email to [security@eclipse-foundation.org](mailto:security@eclipse-foundation.org) or directly with a project via the Eclipse Foundation’s [issue tracker](https://gitlab.eclipse.org/security/vulnerability-reports/-/issues/new?issuable_template=new_vulnerability).
13 |
14 | The general [security team email address](mailto:security@eclipse-foundation.org) can also be used to report vulnerabilities. Members of the Eclipse Foundation Security Team will receive messages sent to this address. This address should be used only for reporting undisclosed vulnerabilities; regular issue reports and questions unrelated to vulnerabilities in Eclipse Foundation project software will be ignored. Note that this email address is not encrypted.
15 |
16 | ## Disclosure
17 |
18 | Disclosure is initially limited to the reporter, the project team and the Eclipse Foundation Security Team, but is expanded to include other individuals, and the general public. The timing and manner of disclosure is governed by the [Eclipse Foundation Vulnerability Reporting Policy](https://www.eclipse.org/security/policy.php).
19 |
20 | Publicly disclosed issues are listed on the [Known Eclipse Security Vulnerabilities](https://www.eclipse.org/security/known.php) page.
21 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project:
4 | default:
5 | informational: true
6 | patch:
7 | default:
8 | informational: true
9 | # When modifying this file, please validate using
10 | # curl -X POST --data-binary @codecov.yml https://codecov.io/validate
11 |
--------------------------------------------------------------------------------
/examples/browser/smart-coffee-machine.js:
--------------------------------------------------------------------------------
1 | /**
2 | * In the browser, node-wot only works in client mode with limited binding support.
3 | * Supported bindings: HTTP / HTTPS / WebSockets
4 | *
5 | * After adding the following
7 | *
8 | * you can access all node-wot functionality / supported packages through the "WoT" global object.
9 | * Examples:
10 | * var servient = new WoT.Core.Servient();
11 | * var client = new WoT.Http.HttpClient();
12 | *
13 | **/
14 |
15 | // A URL to the smart coffee machine Thing Description
16 | const TD_URL = "http://plugfest.thingweb.io:8083/smart-coffee-machine";
17 | // How often to update the property values (in ms)
18 | const UPDATE_PERIOD = 2000;
19 |
20 | function get_td(addr) {
21 | servient.start().then((thingFactory) => {
22 | helpers
23 | .fetch(addr)
24 | .then((td) => {
25 | thingFactory.consume(td).then((thing) => {
26 | showProperties(thing);
27 | });
28 | })
29 | .catch((error) => {
30 | window.alert("Could not fetch TD.\n" + error);
31 | });
32 | });
33 | }
34 |
35 | function showProperties(thing) {
36 | let td = thing.getThingDescription();
37 | let row = 0;
38 | for (let property in td.properties) {
39 | if (td.properties.hasOwnProperty(property)) {
40 | thing.readProperty(property).then(async (iOutput) => {
41 | const value = await iOutput.value();
42 | const el = document.getElementById(property);
43 | if (!el) {
44 | // Create a property record if not found
45 | const tbody = document.getElementById("properties").getElementsByTagName("tbody")[0];
46 | const tr = document.createElement("tr");
47 | tr.innerHTML = `
${property} | ${JSON.stringify(
48 | value,
49 | null,
50 | 2
51 | )} | `;
52 | if (row % 2 !== 0) {
53 | tr.style.background = "#FFFAF0";
54 | }
55 | tbody.appendChild(tr);
56 | row++;
57 | } else {
58 | // Otherwise just update its value
59 | el.innerHTML = `${JSON.stringify(value, null, 2)}
`;
60 | }
61 | });
62 | }
63 | }
64 | // Update the property values after UPDATE_PERIOD time
65 | setTimeout(function () {
66 | showProperties(thing);
67 | }, UPDATE_PERIOD);
68 | }
69 |
70 | var servient = new WoT.Core.Servient();
71 | servient.addClientFactory(new WoT.Http.HttpClientFactory());
72 | var helpers = new WoT.Core.Helpers(servient);
73 | get_td(TD_URL);
74 |
--------------------------------------------------------------------------------
/examples/browser/styles.css:
--------------------------------------------------------------------------------
1 | /* Base styles */
2 | body {
3 | padding: 20px;
4 | background: #f5f5f5;
5 | font-family: Arial, sans-serif;
6 | }
7 |
8 | /* Top bar */
9 | #topbar {
10 | background: white;
11 | padding: 15px;
12 | margin-bottom: 20px;
13 | border: 1px solid #ddd;
14 | }
15 |
16 | /* Tabs */
17 | .tabs {
18 | margin: 0 0 10px 0;
19 | padding: 0;
20 | list-style: none;
21 | border-bottom: 1px solid #ddd;
22 | }
23 |
24 | .tabs li {
25 | display: inline-block;
26 | margin-right: 5px;
27 | }
28 |
29 | .tabs a {
30 | display: block;
31 | padding: 8px 12px;
32 | text-decoration: none;
33 | color: #333;
34 | background: #f0f0f0;
35 | border: 1px solid #ddd;
36 | border-bottom: none;
37 | }
38 |
39 | .tabs .active a {
40 | background: white;
41 | border-bottom: 1px solid white;
42 | margin-bottom: -1px;
43 | }
44 |
45 | /* Tab content */
46 | .tabs-content {
47 | background: white;
48 | padding: 15px;
49 | border: 1px solid #ddd;
50 | border-top: none;
51 | }
52 |
53 | /* Form elements */
54 | #td_addr,
55 | #exampleUrls {
56 | width: 100%;
57 | padding: 8px;
58 | margin-bottom: 10px;
59 | border: 1px solid #ddd;
60 | }
61 |
62 | #fetch {
63 | background: #0066cc;
64 | color: white;
65 | border: none;
66 | padding: 8px 16px;
67 | cursor: pointer;
68 | }
69 |
70 | /* Interactions */
71 | #interactions {
72 | margin-top: 20px;
73 | background: white;
74 | padding: 15px;
75 | border: 1px solid #ddd;
76 | }
77 |
78 | #interactions h4 {
79 | margin-top: 0;
80 | padding-bottom: 8px;
81 | border-bottom: 1px solid #eee;
82 | }
83 |
84 | /* Navigation */
85 | .side-nav {
86 | margin: 0;
87 | padding: 0;
88 | list-style: none;
89 | }
90 |
91 | .side-nav li {
92 | padding: 8px 0;
93 | border-bottom: 1px solid #f0f0f0;
94 | }
95 |
96 | .side-nav li:last-child {
97 | border-bottom: none;
98 | }
99 |
--------------------------------------------------------------------------------
/examples/quickstart/README.md:
--------------------------------------------------------------------------------
1 | # Quick Start Things
2 |
3 | This set of Things can be used to build mashup applications for a smart home scenario.
4 | These Things are:
5 |
6 | - Simple coffee machine that can take an order to brew a coffee.
7 | - Presence sensor that emits an event when a person is detected.
8 | - Smart clock that runs 60 times faster than real time, where 1 hour happens in 1 minute.
9 |
10 | These Things are hosted on plugfest.thingweb.io but can be also self-hosted.
11 |
--------------------------------------------------------------------------------
/examples/quickstart/presence-sensor.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /********************************************************************************
3 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
4 | *
5 | * See the NOTICE file(s) distributed with this work for additional
6 | * information regarding copyright ownership.
7 | *
8 | * This program and the accompanying materials are made available under the
9 | * terms of the Eclipse Public License v. 2.0 which is available at
10 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
11 | * Document License (2015-05-13) which is available at
12 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
13 | *
14 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
15 | ********************************************************************************/
16 | // This is an example Thing script which is a simple presence detector
17 | // It fires an event when it detects a person (mocked as every 5 second)
18 | const core_1 = require("@node-wot/core");
19 | const binding_mqtt_1 = require("@node-wot/binding-mqtt");
20 | // create Servient add MQTT binding with port configuration
21 | const servient = new core_1.Servient();
22 | servient.addServer(new binding_mqtt_1.MqttBrokerServer({ uri: "mqtt://test.mosquitto.org" }));
23 | servient.start().then((WoT) => {
24 | WoT.produce({
25 | title: "PresenceSensor",
26 | description: "Thing that can detect presence of human nearby",
27 | support: "https://github.com/eclipse-thingweb/node-wot/",
28 | "@context": "https://www.w3.org/2022/wot/td/v1.1",
29 | events: {
30 | presenceDetected: {
31 | title: "Presence Detected",
32 | description:
33 | "An event that is emitted when a person is detected in the room. It is mocked and emitted every 5 seconds",
34 | data: {
35 | type: "number",
36 | title: "Distance",
37 | minimum: 55,
38 | maximum: 1200,
39 | },
40 | },
41 | },
42 | })
43 | .then((thing) => {
44 | console.log("Produced " + thing.getThingDescription().title);
45 | // expose the thing
46 | thing.expose().then(() => {
47 | console.info(thing.getThingDescription().title + " ready");
48 | // mocking the detection with an event sent every 5 seconds, with a random distance
49 | setInterval(() => {
50 | const distance = Math.random() * (1200 - 55) + 55;
51 | thing.emitEvent("presenceDetected", distance);
52 | console.info("Emitted presence with distance ", distance);
53 | }, 5000);
54 | });
55 | })
56 | .catch((e) => {
57 | console.log(e);
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/examples/scripts/$DO_NOT_EDIT_JS_FILES.md:
--------------------------------------------------------------------------------
1 | # Note
2 |
3 | The JavaScript files in this folder are generated by the workflow described [here](https://github.com/eclipse-thingweb/node-wot/tree/master/packages/examples#workflow).
4 |
--------------------------------------------------------------------------------
/examples/scripts/counter-client.js:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | function getFormIndexForDecrementWithCoAP(thing) {
17 | const forms = thing.getThingDescription().actions?.decrement.forms;
18 | if (forms !== undefined) {
19 | for (let i = 0; i < forms.length; i++) {
20 | if (/^coaps?:\/\/.*/.test(forms[i].href)) {
21 | return i;
22 | }
23 | }
24 | }
25 | // return formIndex: 0 if no CoAP target IRI found
26 | return 0;
27 | }
28 | WoT.requestThingDescription("coap://localhost:5683/counter")
29 | .then(async (td) => {
30 | try {
31 | const thing = await WoT.consume(td);
32 | console.info("=== TD ===");
33 | console.info(td);
34 | console.info("==========");
35 | // read property #1
36 | const read1 = await thing.readProperty("count");
37 | console.log("count value is", await read1.value());
38 | // increment property #1 (without step)
39 | await thing.invokeAction("increment");
40 | const inc1 = await thing.readProperty("count");
41 | console.info("count value after increment #1 is", await inc1.value());
42 | // increment property #2 (with step)
43 | await thing.invokeAction("increment", undefined, { uriVariables: { step: 3 } });
44 | const inc2 = await thing.readProperty("count");
45 | console.info("count value after increment #2 (with step 3) is", await inc2.value());
46 | // look for the first form for decrement with CoAP binding
47 | await thing.invokeAction("decrement", undefined, {
48 | formIndex: getFormIndexForDecrementWithCoAP(thing),
49 | });
50 | const dec1 = await thing.readProperty("count");
51 | console.info("count value after decrement is", await dec1.value());
52 | } catch (err) {
53 | console.error("Script error:", err);
54 | }
55 | })
56 | .catch((err) => {
57 | console.error("Fetch error:", err);
58 | });
59 |
--------------------------------------------------------------------------------
/examples/scripts/smart-coffee-machine-client.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "http": {
3 | "allowSelfSigned": true
4 | },
5 | "credentials": {
6 | "urn:dev:wot:example:smart-coffee-machine": {
7 | "clientId": "node-wot",
8 | "clientSecret": "isgreat!"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/scripts/wot-servient.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {
3 | "_staticAddress": "plugfest.thingweb.io",
4 | "scriptDir": ".",
5 | "scriptAction": true
6 | },
7 | "http": {
8 | "port": 8080,
9 | "allowSelfSigned": true
10 | },
11 | "coap": {
12 | "port": 5683
13 | },
14 | "mqtt": {
15 | "broker": "mqtt://test.mosquitto.org",
16 | "_username": "username",
17 | "_password": "password",
18 | "_clientId": "uniqueId",
19 | "protocolVersion": 5
20 | },
21 | "opcua": {
22 | "subscriptionOptions": {
23 | "requestedPublishingInterval": 1000,
24 | "requestedLifetimeCount": 100,
25 | "requestedMaxKeepAliveCount": 10,
26 | "maxNotificationsPerPublish": 100,
27 | "publishingEnabled": true,
28 | "priority": 10
29 | }
30 | },
31 | "log": {
32 | "level": "info"
33 | },
34 | "credentials": {
35 | "urn:dev:wot:org:eclipse:leshan": {
36 | "identity": "node-wot",
37 | "psk": "hello"
38 | },
39 | "urn:dev:wot:org:eclipse:cf-secure": {
40 | "identity": "password",
41 | "psk": "sesame"
42 | },
43 | "urn:dev:wot:org:eclipse:netconf-example": {
44 | "username": "root",
45 | "password": "root"
46 | },
47 | "urn:dev:wot:org:eclipse:opcua-example-certificate": {
48 | "clientCertificate": "~/certificates/client_cert.pem",
49 | "clientPrivateKey": "~/certificates/client_private_key.pem",
50 | "serverCertificate": "~/certificates/server_cert.pem"
51 | },
52 | "urn:dev:wot:org:eclipse:opcua-example-password": {
53 | "username": "root",
54 | "password": "root"
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/examples/security/README.md:
--------------------------------------------------------------------------------
1 | # How to create .pem files
2 |
3 | 1. `openssl genrsa -out privatekey.pem 1024`
4 | 2. `openssl req -new -key privatekey.pem -out certrequest.csr`
5 | 3. `openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem`
6 |
7 | # Secure Example
8 |
9 | see `example-server-secure.js` in https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-http#server-example
10 |
--------------------------------------------------------------------------------
/examples/security/certificate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICYzCCAcwCCQD3LJYj+TYO2TANBgkqhkiG9w0BAQsFADB2MRkwFwYDVQQKDBBF
3 | Y2xpcHNlIFRoaW5nd2ViMREwDwYDVQQLDAhub2RlLXdvdDEdMBsGA1UEAwwUcGx1
4 | Z2Zlc3QudGhpbmd3ZWIuaW8xJzAlBgkqhkiG9w0BCQEWGGRldi10aGluZ3dlYkBl
5 | Y2xpcHNlLm9yZzAeFw0xODEwMjExMTU0MjNaFw0xODExMjAxMTU0MjNaMHYxGTAX
6 | BgNVBAoMEEVjbGlwc2UgVGhpbmd3ZWIxETAPBgNVBAsMCG5vZGUtd290MR0wGwYD
7 | VQQDDBRwbHVnZmVzdC50aGluZ3dlYi5pbzEnMCUGCSqGSIb3DQEJARYYZGV2LXRo
8 | aW5nd2ViQGVjbGlwc2Uub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY
9 | 05qXs2BFbdtsS9dQAxIEz94vO2/VsGmJbq5eLWU+vUSt+jW5xrenfWKlqATPAiYu
10 | wH5zYa4x0Qf1HwpC4H2CP+PJOE7s+Gbt3eN9Gv3z/6LgOLrK1NlREOS9hGukEdSH
11 | bXiz4Aftz0K5NR8sAeWGaNn/OK8UlBPX7ekV6tWQ/wIDAQABMA0GCSqGSIb3DQEB
12 | CwUAA4GBAMQ8QzKoDbG6niS3lDV7oYkaJQJsk9v4dfNvg0AP8pE6Id1juw+PVLU+
13 | wSaJh9GOKHTEvGQ/wJie6ZsdGzlKhRE4suar/gn8bh448DEpP50tLTj7PJiat1CE
14 | zt7Ng3PMPaSF2GAqD3ewdZqWbmmAkzelGaNDlp+TQUuO8aaYJFui
15 | -----END CERTIFICATE-----
16 |
--------------------------------------------------------------------------------
/examples/security/oauth/README.md:
--------------------------------------------------------------------------------
1 | # oAuth JavaScript example
2 |
3 | This is example is composed by two actors: one Thing that expose an action with oAuth2.0 client credential security constraint and a client who want to use that function. In the example, we are using an utility server to generate tokens and validate client credentials. Therefore, the **wot-consumer** force the action `href` to be the same as the utility server with the goal to validate the obtained oAuth2.0 token. In the feature the exposing servient could also play this role.
4 |
5 | ## run the example
6 |
7 | Set the current working directory to this folder. Then execute:
8 |
9 | ```bash
10 | npm install
11 | ```
12 |
13 | Now you are ready to run the example.
14 |
15 | ```bash
16 | # start the server
17 | npm run server
18 | ```
19 |
20 | in a different terminal
21 |
22 | ```bash
23 | # start the exposer
24 | npm run start:exposer
25 | ```
26 |
27 | Finally, in other terminal
28 |
29 | ```bash
30 | npm run start:consumer
31 | ```
32 |
33 | you should see the following line at the end of consumer log:
34 |
35 | ```bash
36 | oAuth token was Ok!
37 | ```
38 |
39 | This confirms that the oAuth flow was completed successfully. Now you can have fun revoking the access to the consumer script. Go
40 | to `./exposer.js` and try to remove the string `"user"` from the grants. Run again the example and you will see that the action is not executed and an error is returned by the client.
41 |
42 | ## Where is a TS version?
43 |
44 | See [here](../../../packages/examples/src/security/oauth)
45 |
--------------------------------------------------------------------------------
/examples/security/oauth/consumer.js:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | WoT.requestThingDescription("https://localhost:8080/oauth").then((td) => {
16 | WoT.consume(td).then(async (thing) => {
17 | try {
18 | const resp = await thing.invokeAction("sayOk");
19 | const result = await resp?.value();
20 | console.log("oAuth token was", result);
21 | } catch (error) {
22 | console.log("It seems that I couldn't access the resource");
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/examples/security/oauth/exposer.js:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 - 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | const td = {
16 | "@context": "https://www.w3.org/2019/wot/td/v1",
17 | title: "OAuth",
18 | id: "urn:dev:wot:oauth:test",
19 | securityDefinitions: {
20 | oauth2_sc: {
21 | scheme: "oauth2",
22 | flow: "client",
23 | token: "https://localhost:3000/token",
24 | scopes: ["user", "admin"],
25 | },
26 | },
27 | security: ["oauth2_sc"],
28 | actions: {
29 | sayOk: {
30 | description: "A simple action protected with oauth",
31 | idempotent: true,
32 | },
33 | },
34 | };
35 | try {
36 | WoT.produce(td).then((thing) => {
37 | thing.setActionHandler("sayOk", async () => "Ok!");
38 | thing.expose();
39 | });
40 | } catch (err) {
41 | console.error("Script error: " + err);
42 | }
43 |
--------------------------------------------------------------------------------
/examples/security/oauth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oauth-test",
3 | "version": "1.0.0",
4 | "description": "Simple project setup to test oauth functionalities",
5 | "main": "index.js",
6 | "scripts": {
7 | "server": "node server.js",
8 | "start:exposer": "node ../../../packages/cli/dist/cli.js -f ./wot-server-servient-conf.json exposer.js",
9 | "start:consumer": "node ../../../packages/cli/dist/cli.js -f ./wot-client-servient-conf.json consumer.js"
10 | },
11 | "author": "Eclipse Thingweb (https://thingweb.io/)",
12 | "license": "EPL-2.0 OR W3C-20150513",
13 | "devDependencies": {
14 | "@node-oauth/express-oauth-server": "^3.0.1",
15 | "cors": "^2.8.5"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/security/oauth/server.js:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 - 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | /**
16 | * A simple oAuth test server
17 | */
18 | const OAuthServer = require("@node-oauth/express-oauth-server");
19 | const bodyParser = require("body-parser");
20 | const cors = require("cors");
21 | const https = require("https");
22 | const fs = require("fs");
23 | const express = require("express");
24 | const Memory = require("./memory-model");
25 |
26 | var app = express();
27 | app.use(cors());
28 | app.options("*", cors());
29 |
30 | const model = new Memory();
31 |
32 | app.oauth = new OAuthServer({
33 | model: model,
34 | });
35 |
36 | app.use(bodyParser.json());
37 | app.use("/introspect", bodyParser.urlencoded({ extended: false }));
38 | app.use("/introspect", (req, res, next) => {
39 | if (req.method !== "POST" || !req.is("application/x-www-form-urlencoded")) {
40 | return res.status(400).end();
41 | }
42 |
43 | // rewrite body authenticate method is not compliant to https://tools.ietf.org/html/rfc7662
44 | const token = req.body.token;
45 | delete req.body.token;
46 | req.body.access_token = token;
47 | console.log("Body changed,");
48 | next();
49 | });
50 |
51 | app.use("/introspect", async (req, res, next) => {
52 | return app.oauth.authenticate()(req, res, next);
53 | });
54 | app.use("/introspect", (req, res) => {
55 | const token = res.locals.oauth.token;
56 | console.log("Token was", token ? "Ok" : "not Ok");
57 | res.json({
58 | active: !!token,
59 | scope: token.client.scopes.join(" "),
60 | client_id: token.client.clientId,
61 | }).end();
62 | });
63 |
64 | app.use("/token", bodyParser.urlencoded({ extended: false }));
65 | app.use("/token", app.oauth.token());
66 |
67 | app.use("/resource", (req, res) => {
68 | console.log("qui?");
69 | res.send("Ok!");
70 | });
71 |
72 | https
73 | .createServer(
74 | {
75 | key: fs.readFileSync("../privatekey.pem"),
76 | cert: fs.readFileSync("../certificate.pem"),
77 | },
78 | app
79 | )
80 | .listen(3000, "localhost", () => {
81 | console.log("listening");
82 | });
83 |
--------------------------------------------------------------------------------
/examples/security/oauth/wot-client-servient-conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {
3 | "clientOnly": true
4 | },
5 | "http": {
6 | "allowSelfSigned": true
7 | },
8 | "credentials": {
9 | "urn:dev:wot:oauth:test": {
10 | "clientId": "node-wot",
11 | "clientSecret": "isgreat!"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/security/oauth/wot-server-servient-conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {},
3 | "http": {
4 | "allowSelfSigned": true,
5 | "serverKey": "../privatekey.pem",
6 | "serverCert": "../certificate.pem",
7 | "security": [
8 | {
9 | "scheme": "oauth2",
10 | "method": {
11 | "name": "introspection_endpoint",
12 | "endpoint": "https://localhost:3000/introspect",
13 | "allowSelfSigned": true
14 | }
15 | }
16 | ]
17 | },
18 | "credentials": {
19 | "urn:dev:wot:oauth:test": {
20 | "clientId": "node-wot",
21 | "clientSecret": "isgreat!"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/security/privatekey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXQIBAAKBgQDY05qXs2BFbdtsS9dQAxIEz94vO2/VsGmJbq5eLWU+vUSt+jW5
3 | xrenfWKlqATPAiYuwH5zYa4x0Qf1HwpC4H2CP+PJOE7s+Gbt3eN9Gv3z/6LgOLrK
4 | 1NlREOS9hGukEdSHbXiz4Aftz0K5NR8sAeWGaNn/OK8UlBPX7ekV6tWQ/wIDAQAB
5 | AoGAQeoZ/fH+2zxpTwPDQcSdLq9OeQdVmR2XB7uI8IJWW/tHrKf6uy4o2JbqbTel
6 | tpSNrPrBtivEu8oy5BZ6lRgPrwChkxTPCKSTBxlofN17Xdt7U4+WfKsEuGUO1goc
7 | xqc21Gn6Ug6Dh4KcpD5zpmnSGj9cLUe8dy/PQlO0XoLyekECQQDugAfqleAsYPLk
8 | h87yksPDMdSwcOhk1oEjJXz/JiTgfmCN+eAtOLtq98VWRXPzhHfAeolIVNhNBtnW
9 | NxMAxCehAkEA6Lx1bCyzx+clVUneD6RWqHBjoSONH5gQ/Qj0kWqlzjWidjKKCNrP
10 | /RwNzK7D0frgnLM7JAyWTCInZCdTA4x0nwJBAIT/PGrifQoCXjB2Uz8N/MCizxo9
11 | PDrPK2AwDY4y9SmDD9DcYNiW5Fx4IsFDJa/MVQMu0dNWDPCXO26rc5tfx0ECQQDS
12 | oTzkGdDbKiZvedqu7VxANPb17ubZoRY+6svsj0hfx8qwjiy+tsllmO4kQEaY0yRU
13 | rSDpDzs2y/I6ghxvKb6hAkAYOTzDSxOrjBiOi3lnybzfBBPT5j2v9kvZGE2JhLKW
14 | 7pTaU5hb6qkNVvMINAYAIZMiiriovPQOpJbWTLo0QbH4
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/examples/security/wot-servient.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {
3 | "scriptDir": ".",
4 | "scriptAction": true
5 | },
6 | "http": {
7 | "port": 8080,
8 | "allowSelfSigned": true,
9 | "serverKey": "privatekey.pem",
10 | "serverCert": "certificate.pem",
11 | "security": {
12 | "scheme": "basic"
13 | }
14 | },
15 | "_coap": {
16 | "port": 5683
17 | },
18 | "_mqtt": {
19 | "broker": "mqtt://test.mosquitto.org",
20 | "port": 1883
21 | },
22 | "log": {
23 | "level": "info"
24 | },
25 | "credentials": {
26 | "urn:dev:wot:org:eclipse:thingweb:security-example": {
27 | "username": "node-wot",
28 | "password": "hello",
29 | "token": "1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/examples/templates/exposed-thing/index.js:
--------------------------------------------------------------------------------
1 | //Where your concrete implementation is included
2 | WotDevice = require("./dist/base.js").WotDevice;
3 |
4 | /*
5 | This project supports the registration of the generated TD to a TD directory
6 | Fill in the directory URI where the HTTP POST request to send the TD will be made
7 | If you leave it empty, registration thread will never execute, otherwise it will try to register every 10 seconds
8 | */
9 | const TD_DIRECTORY = "";
10 |
11 | Servient = require("@node-wot/core").Servient;
12 | //Importing the required bindings
13 | HttpServer = require("@node-wot/binding-http").HttpServer;
14 | //CoapServer = require("@node-wot/binding-coap").CoapServer
15 | //MqttBrokerServer = require("@node-wot/binding-mqtt").MqttBrokerServer
16 |
17 | //Creating the instances of the binding servers
18 | var httpServer = new HttpServer({ port: 8080 });
19 | //var coapServer = new CoapServer({port: 5683});
20 | //var mqttServer = new MqttBrokerServer("test.mosquitto.org"); //change it according to the broker address
21 |
22 | //Building the servient object
23 | var servient = new Servient();
24 | //Adding different bindings to the server
25 | servient.addServer(httpServer);
26 | //servient.addServer(coapServer);
27 | //servient.addServer(mqttServer);
28 |
29 | servient.start().then((WoT) => {
30 | wotDevice = new WotDevice(WoT, TD_DIRECTORY); // you can change the wotDevice to something that makes more sense
31 | });
32 |
--------------------------------------------------------------------------------
/examples/templates/exposed-thing/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wot-default-change-here-",
3 | "version": "1.0.0",
4 | "description": "W3C WoT interface for base (!change here!)",
5 | "main": "index.js",
6 | "keywords": [
7 | "wot",
8 | "w3c"
9 | ],
10 | "author": "tumeiesi",
11 | "license": "MIT",
12 | "devDependencies": {
13 | "typescript": "4.7.4",
14 | "wot-typescript-definitions": "0.8.0-SNAPSHOT.30",
15 | "@types/node": "16.18.35",
16 | "tslint": "5.12.1"
17 | },
18 | "dependencies": {
19 | "@node-wot/binding-http": "0.8.x",
20 | "@node-wot/core": "0.8.x",
21 | "request": "2.88.0",
22 | "ajv": "^6.12.6"
23 | },
24 | "optionalDependencies": {},
25 | "scripts": {
26 | "build": "tsc -b",
27 | "buildAll": "npm install; tsc;",
28 | "start": "node index.js",
29 | "clean": "rm -rf node_modules; rm -rf dist; rm -rf package-lock.json"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/templates/exposed-thing/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2021",
4 | "lib": ["ES2021", "dom"],
5 | "module": "commonjs",
6 | "outDir": "dist",
7 | "alwaysStrict": true,
8 | "sourceMap": true,
9 | "noLib": false,
10 | "forceConsistentCasingInFileNames": true,
11 | "noImplicitReturns": true,
12 | "noUnusedLocals": true
13 | },
14 | "exclude": ["node_modules"],
15 | "include": ["src/**/*"]
16 | }
17 |
--------------------------------------------------------------------------------
/examples/testthing/$DO_NOT_EDIT_JS_FILES.md:
--------------------------------------------------------------------------------
1 | # Note
2 |
3 | The JavaScript files in this folder are generated by the workflow described [here](https://github.com/eclipse-thingweb/node-wot/tree/master/packages/examples#workflow).
4 |
--------------------------------------------------------------------------------
/license.template.txt:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) <%= YEAR %> Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
--------------------------------------------------------------------------------
/packages/binding-coap/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-coap/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-coap",
3 | "version": "0.9.2",
4 | "description": "CoAP client & server protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-coap",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/coap.js",
15 | "types": "dist/coap.d.ts",
16 | "dependencies": {
17 | "@node-wot/core": "0.9.2",
18 | "coap": "^1.4.1",
19 | "dns-packet": "^5.2.2",
20 | "multicast-dns": "^7.2.5",
21 | "node-coap-client": "1.0.8",
22 | "rxjs": "5.5.11",
23 | "slugify": "^1.4.5",
24 | "wot-typescript-definitions": "0.8.0-SNAPSHOT.30"
25 | },
26 | "scripts": {
27 | "build": "tsc -b",
28 | "test": "mocha --require ts-node/register --extension ts",
29 | "lint": "eslint .",
30 | "lint:fix": "eslint . --fix",
31 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
32 | },
33 | "bugs": {
34 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
35 | },
36 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-coap#readme",
37 | "directories": {
38 | "test": "test"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/binding-coap/src/coap-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * CoAP client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
21 | import CoapClient from "./coap-client";
22 | import CoapServer from "./coap-server";
23 |
24 | const { debug } = createLoggers("binding-coap", "coap-client-factory");
25 |
26 | export default class CoapClientFactory implements ProtocolClientFactory {
27 | public readonly scheme: string = "coap";
28 |
29 | private readonly server?: CoapServer;
30 |
31 | constructor(server?: CoapServer) {
32 | this.server = server;
33 | }
34 |
35 | public getClient(): ProtocolClient {
36 | debug(`CoapClientFactory creating client for '${this.scheme}'`);
37 | return new CoapClient(this.server);
38 | }
39 |
40 | public init(): boolean {
41 | // info(`CoapClientFactory for '${this.scheme}' initializing`);
42 | // TODO uncomment info if something is executed here
43 | return true;
44 | }
45 |
46 | public destroy(): boolean {
47 | // info(`CoapClientFactory for '${this.scheme}' destroyed`);
48 | // TODO uncomment info if something is executed here
49 | return true;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/packages/binding-coap/src/coaps-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * CoAPS client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
21 | import CoapsClient from "./coaps-client";
22 |
23 | const { debug } = createLoggers("binding-coap", "coaps-client-factory");
24 |
25 | export default class CoapsClientFactory implements ProtocolClientFactory {
26 | public readonly scheme: string = "coaps";
27 |
28 | public getClient(): ProtocolClient {
29 | debug(`CoapsClientFactory creating client for '${this.scheme}'`);
30 | return new CoapsClient();
31 | }
32 |
33 | public init(): boolean {
34 | // info(`CoapsClientFactory for '${this.scheme}' initializing`);
35 | // TODO uncomment info if something is executed here
36 | return true;
37 | }
38 |
39 | public destroy(): boolean {
40 | // info(`CoapsClientFactory for '${this.scheme}' destroyed`);
41 | // TODO uncomment info if something is executed here
42 | return true;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/binding-coap/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-coap/test/coap-types-test.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Protocol test suite for CoAP binding definitions
18 | */
19 |
20 | import { suite, test } from "@testdeck/mocha";
21 | import { expect } from "chai";
22 | import { blockSizeToOptionValue } from "../src/coap";
23 |
24 | @suite("CoAP Binding Definitions")
25 | class CoapDefinitionsTest {
26 | @test "should map raw blocksizes to the correct option value"() {
27 | expect(blockSizeToOptionValue(16)).to.eq(0);
28 | expect(blockSizeToOptionValue(32)).to.eq(1);
29 | expect(blockSizeToOptionValue(64)).to.eq(2);
30 | expect(blockSizeToOptionValue(128)).to.eq(3);
31 | expect(blockSizeToOptionValue(256)).to.eq(4);
32 | expect(blockSizeToOptionValue(512)).to.eq(5);
33 | expect(blockSizeToOptionValue(1024)).to.eq(6);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/binding-coap/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-coap/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-file/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-file/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-file",
3 | "version": "0.9.2",
4 | "description": "File client protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-file",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/file.js",
15 | "types": "dist/file.d.ts",
16 | "dependencies": {
17 | "@node-wot/core": "0.9.2",
18 | "rxjs": "5.5.11"
19 | },
20 | "scripts": {
21 | "build": "tsc -b",
22 | "test": "mocha --require ts-node/register --extension ts",
23 | "lint": "eslint .",
24 | "lint:fix": "eslint . --fix",
25 | "format": "prettier --write \"src/**/*.ts\" \"**/*.json\""
26 | },
27 | "bugs": {
28 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
29 | },
30 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-file#readme",
31 | "directories": {
32 | "test": "test"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/binding-file/src/file-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * File protocol binding
18 | */
19 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
20 | import FileClient from "./file-client";
21 |
22 | const { debug } = createLoggers("binding-file", "file-client-factory");
23 |
24 | export default class FileClientFactory implements ProtocolClientFactory {
25 | public readonly scheme: string = "file";
26 |
27 | public getClient(): ProtocolClient {
28 | debug(`FileClientFactory creating client for '${this.scheme}'`);
29 | return new FileClient();
30 | }
31 |
32 | public init = (): boolean => true;
33 | public destroy = (): boolean => true;
34 | }
35 |
--------------------------------------------------------------------------------
/packages/binding-file/src/file.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | export { default as FileClient } from "./file-client";
17 | export { default as FileClientFactory } from "./file-client-factory";
18 | export * from "./file-client";
19 | export * from "./file-client-factory";
20 |
--------------------------------------------------------------------------------
/packages/binding-file/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-file/test/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore auxiliary files created by the FileClient implementation tests
2 | test*.json
3 | test*.txt
4 |
--------------------------------------------------------------------------------
/packages/binding-file/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-http/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-http/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-http",
3 | "version": "0.9.2",
4 | "description": "HTTP client & server protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-http",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/http.js",
15 | "types": "dist/http.d.ts",
16 | "browser": {
17 | "./dist/http.js": "./dist/http-browser.js",
18 | "./dist/http-client.js": "./dist/http-client-browser.js"
19 | },
20 | "devDependencies": {
21 | "@node-oauth/express-oauth-server": "^3.0.1",
22 | "@node-oauth/oauth2-server": "^4.3.0",
23 | "@types/accept-language-parser": "^1.5.2",
24 | "@types/basic-auth": "1.1.3",
25 | "@types/eventsource": "^1.1.15",
26 | "@types/express": "^4.17.3",
27 | "@types/node-fetch": "^2.6.12",
28 | "body-parser": "^1.20.3",
29 | "express": "^4.20.0",
30 | "ssestream": "^1.1.0",
31 | "timekeeper": "^2.2.0"
32 | },
33 | "dependencies": {
34 | "@node-wot/core": "0.9.2",
35 | "accept-language-parser": "1.5.0",
36 | "basic-auth": "2.0.1",
37 | "client-oauth2": "^4.2.5",
38 | "eventsource": "^2.0.2",
39 | "find-my-way": "^8.2.2",
40 | "node-fetch": "^2.7.0",
41 | "query-string": "^7.1.1",
42 | "rxjs": "^5.5.11",
43 | "slugify": "^1.4.5"
44 | },
45 | "scripts": {
46 | "build": "tsc -b",
47 | "test": "mocha --require ts-node/register --extension ts",
48 | "lint": "eslint .",
49 | "lint:fix": "eslint . --fix",
50 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
51 | },
52 | "bugs": {
53 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
54 | },
55 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-http#readme"
56 | }
57 |
--------------------------------------------------------------------------------
/packages/binding-http/src/codecs/tuya-codec.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ContentCodec, DataSchema } from "@node-wot/core";
17 | import { DataSchemaValue } from "wot-typescript-definitions";
18 |
19 | interface TuyaOutput {
20 | success?: boolean;
21 | msg?: string;
22 | result?: {
23 | code?: string;
24 | }[];
25 | }
26 |
27 | export default class HttpTuyaCodec implements ContentCodec {
28 | getMediaType(): string {
29 | return "application/json+tuya";
30 | }
31 |
32 | bytesToValue(bytes: Buffer, schema: DataSchema, parameters: { [key: string]: string }): DataSchemaValue {
33 | const parsedBody: TuyaOutput = JSON.parse(bytes.toString());
34 | const success = parsedBody.success ?? false;
35 |
36 | if (!success) {
37 | throw new Error(parsedBody.msg ?? JSON.stringify(parsedBody));
38 | }
39 |
40 | for (const value of Object.values(parsedBody.result ?? {})) {
41 | if (value.code === schema["tuya:PropertyName"]) {
42 | return value;
43 | }
44 | }
45 | throw new Error("Property not found");
46 | }
47 |
48 | valueToBytes(value: unknown, schema: DataSchema, parameters?: { [key: string]: string }): Buffer {
49 | const obj = {
50 | commands: [
51 | {
52 | code: schema["tuya:PropertyName"],
53 | value,
54 | },
55 | ],
56 | };
57 | const body = JSON.stringify(obj);
58 | return Buffer.from(body);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http-browser.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2019 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Form, SecurityScheme } from "@node-wot/core";
17 |
18 | import { Headers, Response } from "node-fetch";
19 |
20 | export { default as HttpClient } from "./http-client";
21 | export { default as HttpClientFactory } from "./http-client-factory";
22 | export { default as HttpsClientFactory } from "./https-client-factory";
23 | export * from "./http-client";
24 | export * from "./http-client-factory";
25 | export * from "./https-client-factory";
26 |
27 | export interface HttpProxyConfig {
28 | href: string;
29 | scheme?: string;
30 | token?: string;
31 | username?: string;
32 | password?: string;
33 | }
34 |
35 | export interface HttpConfig {
36 | port?: number;
37 | address?: string;
38 | proxy?: HttpProxyConfig;
39 | allowSelfSigned?: boolean;
40 | serverKey?: string;
41 | serverCert?: string;
42 | security?: SecurityScheme;
43 | }
44 |
45 | export class HttpHeader {
46 | public "http:fieldName": number;
47 | public "http:fieldValue": unknown;
48 | }
49 |
50 | export class HttpForm extends Form {
51 | public "http:methodName"?: string; // "GET", "PUT", "POST", "DELETE"
52 | public "http:headers"?: Array | HttpHeader;
53 | }
54 |
55 | Headers.prototype.raw = function () {
56 | const result: { [key: string]: string[] } = {};
57 | for (const [headerKey, headerValue] of this.entries()) {
58 | result[headerKey] = headerValue.split(",");
59 | }
60 | return result;
61 | };
62 |
63 | Response.prototype.buffer = async function () {
64 | return Buffer.from(await this.arrayBuffer());
65 | };
66 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http-client-browser.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { ProtocolHelpers } from "@node-wot/core";
16 | import fetch, { RequestInit, Request } from "node-fetch";
17 | import { Readable } from "stream";
18 | import { HttpForm, HTTPMethodName } from "./http";
19 | import HttpClient from "./http-client-impl";
20 |
21 | export default class BrowserHttpClient extends HttpClient {
22 | protected async generateFetchRequest(
23 | form: HttpForm,
24 | defaultMethod: HTTPMethodName,
25 | additionalOptions?: RequestInit
26 | ): Promise {
27 | // See https://github.com/eclipse-thingweb/node-wot/issues/790
28 | if (additionalOptions?.body instanceof Readable) {
29 | const buffer = await ProtocolHelpers.readStreamFully(additionalOptions.body);
30 | additionalOptions.body = buffer;
31 | }
32 | return super.generateFetchRequest(form, defaultMethod, additionalOptions);
33 | }
34 |
35 | protected async _fetch(request: Request) {
36 | return fetch(request);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * HTTP client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
21 | import { HttpConfig } from "./http";
22 | import HttpClient from "./http-client";
23 | import OAuthManager from "./oauth-manager";
24 |
25 | const { debug, warn } = createLoggers("binding-http", "http-client-factory");
26 |
27 | export default class HttpClientFactory implements ProtocolClientFactory {
28 | public readonly scheme: string = "http";
29 | private config: HttpConfig | null = null;
30 | private oAuthManager: OAuthManager = new OAuthManager();
31 |
32 | constructor(config: HttpConfig | null = null) {
33 | this.config = config;
34 | }
35 |
36 | public getClient(): ProtocolClient {
37 | // HTTP over HTTPS proxy requires HttpsClient
38 | if (this.config && this.config.proxy && this.config.proxy.href && this.config.proxy.href.startsWith("https:")) {
39 | warn("HttpClientFactory creating client for 'https' due to secure proxy configuration");
40 | return new HttpClient(this.config, true, this.oAuthManager);
41 | } else {
42 | debug(`HttpClientFactory creating client for '${this.scheme}'`);
43 | return new HttpClient(this.config);
44 | }
45 | }
46 |
47 | public init(): boolean {
48 | // info(`HttpClientFactory for '${HttpClientFactory.scheme}' initializing`);
49 | // TODO uncomment info if something is executed here
50 | return true;
51 | }
52 |
53 | public destroy(): boolean {
54 | // info(`HttpClientFactory for '${HttpClientFactory.scheme}' destroyed`);
55 | // TODO uncomment info if something is executed here
56 | return true;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http-client.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | export { default } from "./http-client-impl";
17 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http-server-middleware.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * HTTP Middleware for the HTTP Server
18 | */
19 |
20 | import * as http from "http";
21 |
22 | /**
23 | * A middleware function for the HTTP server, which can be used to intercept requests before they are handled by the WoT Servient.
24 | *
25 | * Example:
26 | * ```javascript
27 | * import { Servient } from "@node-wot/core";
28 | * import { HttpServer, MiddlewareRequestHandler } from "@node-wot/binding-http";
29 | *
30 | * const servient = new Servient();
31 | *
32 | * const middleware: MiddlewareRequestHandler = async (req, res, next) => {
33 | * // For example, reject requests in which the X-Custom-Header header is missing
34 | * // by replying with 400 Bad Request
35 | * if (!req.headers["x-custom-header"]) {
36 | * res.statusCode = 400;
37 | * res.end("Bad Request");
38 | * return;
39 | * }
40 | * // Pass all other requests to the WoT Servient
41 | * next();
42 | * };
43 |
44 | * const httpServer = new HttpServer({
45 | * middleware,
46 | * });
47 | *
48 | * servient.addServer(httpServer);
49 | *
50 | * servient.start().then(async (WoT) => {
51 | * // ...
52 | * });
53 | * ```
54 | * @param req The HTTP request.
55 | * @param res The HTTP response.
56 | * @param next Call this function to pass the request to the WoT Servient.
57 | */
58 | export type MiddlewareRequestHandler = (
59 | req: http.IncomingMessage,
60 | res: http.ServerResponse,
61 | next: () => void
62 | ) => Promise;
63 |
--------------------------------------------------------------------------------
/packages/binding-http/src/http.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { SecurityScheme, Form } from "@node-wot/core";
17 | import { Method } from "./oauth-token-validation";
18 | import { MiddlewareRequestHandler } from "./http-server-middleware";
19 |
20 | export { default as HttpServer } from "./http-server";
21 | export { default as HttpClient } from "./http-client";
22 | export { default as HttpClientFactory } from "./http-client-factory";
23 | export { default as HttpsClientFactory } from "./https-client-factory";
24 | export { MiddlewareRequestHandler } from "./http-server-middleware";
25 | export * from "./http-server";
26 | export * from "./http-client";
27 | export * from "./http-client-factory";
28 | export * from "./https-client-factory";
29 |
30 | export interface HttpProxyConfig {
31 | href: string;
32 | scheme?: "basic" | "bearer";
33 | token?: string;
34 | username?: string;
35 | password?: string;
36 | }
37 |
38 | export interface HttpConfig {
39 | port?: number;
40 | address?: string;
41 | baseUri?: string;
42 | urlRewrite?: Record;
43 | proxy?: HttpProxyConfig;
44 | allowSelfSigned?: boolean;
45 | serverKey?: string;
46 | serverCert?: string;
47 | security?: SecurityScheme[];
48 | middleware?: MiddlewareRequestHandler;
49 | }
50 |
51 | export interface OAuth2ServerConfig extends SecurityScheme {
52 | method: Method;
53 | /**
54 | * Regex to select the valid clients ids. Default: .*
55 | */
56 | allowedClients?: string;
57 | }
58 |
59 | export interface TuyaCustomBearerSecurityScheme extends SecurityScheme {
60 | /**
61 | * This scheme is necessary because of the Tuya binding.
62 | * The Tuya Apis are implementing a custom security protocol that needs a custom handling
63 | */
64 | scheme: "TuyaCustomBearer";
65 | baseUri: string;
66 | }
67 |
68 | export type HTTPMethodName = "GET" | "PUT" | "POST" | "DELETE" | "PATCH" | "HEAD";
69 |
70 | export class HttpHeader {
71 | public "htv:fieldName": string;
72 | public "htv:fieldValue": string;
73 | }
74 |
75 | export class HttpForm extends Form {
76 | public "htv:methodName"?: HTTPMethodName;
77 | public "htv:headers"?: Array | HttpHeader;
78 | }
79 |
--------------------------------------------------------------------------------
/packages/binding-http/src/https-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * HTTPS client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
21 | import { HttpConfig } from "./http";
22 | import HttpClient from "./http-client";
23 |
24 | const { debug, warn } = createLoggers("binding-http", "https-client-factory");
25 |
26 | export default class HttpsClientFactory implements ProtocolClientFactory {
27 | public readonly scheme: string = "https";
28 | private config: HttpConfig | null = null;
29 |
30 | constructor(config: HttpConfig | null = null) {
31 | this.config = config;
32 | }
33 |
34 | public getClient(): ProtocolClient {
35 | // HTTPS over HTTP proxy requires HttpClient
36 | if (this.config && this.config.proxy && this.config.proxy.href && this.config.proxy.href.startsWith("http:")) {
37 | warn("HttpsClientFactory creating client for 'http' due to insecure proxy configuration");
38 | return new HttpClient(this.config);
39 | } else {
40 | debug(`HttpsClientFactory creating client for '${this.scheme}'`);
41 | return new HttpClient(this.config, true);
42 | }
43 | }
44 |
45 | public init(): boolean {
46 | // info(`HttpsClientFactory for '${HttpsClientFactory.scheme}' initializing`);
47 | // TODO uncomment info if something is executed here
48 | return true;
49 | }
50 |
51 | public destroy(): boolean {
52 | // info(`HttpsClientFactory for '${HttpsClientFactory.scheme}' destroyed`);
53 | // TODO uncomment info if something is executed here
54 | return true;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/binding-http/src/routes/things.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { ContentSerdes, Helpers } from "@node-wot/core";
16 | import { IncomingMessage, ServerResponse } from "http";
17 | import HttpServer from "../http-server";
18 |
19 | export default function thingsRoute(
20 | this: HttpServer,
21 | req: IncomingMessage,
22 | res: ServerResponse,
23 | _params: unknown
24 | ): void {
25 | res.setHeader("Access-Control-Allow-Origin", "*");
26 | res.setHeader("Content-Type", ContentSerdes.DEFAULT);
27 | res.writeHead(200);
28 | const list = [];
29 | for (const address of Helpers.getAddresses()) {
30 | for (const name in this.getThings()) {
31 | // FIXME the undefined check should NOT be necessary (however there seems to be null in it)
32 | if (name) {
33 | list.push(
34 | this.scheme +
35 | "://" +
36 | Helpers.toUriLiteral(address) +
37 | ":" +
38 | this.getPort() +
39 | "/" +
40 | encodeURIComponent(name)
41 | );
42 | }
43 | }
44 | }
45 | res.end(JSON.stringify(list));
46 | }
47 |
--------------------------------------------------------------------------------
/packages/binding-http/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-http/test/server.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDXTCCAkWgAwIBAgIJAMsp9gVwegP9MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
3 | BAYTAklUMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
4 | aWRnaXRzIFB0eSBMdGQwHhcNMjAwNDE0MDkxMTQzWhcNMjAwNTE0MDkxMTQzWjBF
5 | MQswCQYDVQQGEwJJVDETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
7 | CgKCAQEA3ToVq2J/9We8lYG0EWRGn0s488mp+H/8Z6GJUOabhRpdrapPS8NyFqzK
8 | wh5t/kAq3R5GH5BTTc75pF9ksIK4FfUbKtOPcubvJEpt+eCZzeD0v5oH73dwPaoY
9 | oZp8WfUkILhdMSyFBUyNLzVMrbjyCyH/J6z0QUy6Llg9nCmGh5xF0DHNApVnRpDK
10 | efVO9SVJQAi5U2DTswHYzV6H/Pi199yevepnc3qNnlGLDxr1uPzx7iZrR5GrSsjQ
11 | TtjGAMRnlF2tEinx6BEgIf1m+6PriYtCZ9FKvBCKjVwp/tvvXWQcyNDuJum8u2TE
12 | rD3T/LABP53XXnfEPdfsl7YFfWNcTQIDAQABo1AwTjAdBgNVHQ4EFgQUqQ3t0q3h
13 | J/KjeYdzwGHIAa8U0UAwHwYDVR0jBBgwFoAUqQ3t0q3hJ/KjeYdzwGHIAa8U0UAw
14 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAny9MlmTVQdhDW3xV1Iwi
15 | 3fwUPEJ1Y5ACPenhbQBwet3DiwGbgrEYNp/pOgDWfQbJd7szKf4xOmC68TLnztrJ
16 | 0n7x5l3DeRJjM4d3mHZG/MwdEQe0EZr5eI3tEyHqBX9ll9ntIScbiTkPJbl/YytX
17 | PzkDar4krEKAgw9QQerYtcv85TIg0XfXcOjud6RILBYkF1B5QAFFKybj+z527FlG
18 | +mDoYKyPk0fG2q945Tzc8AU/Z3pfpRCUQAahH7uUXS4Ytk2WGCrmqW/OV93zOCfK
19 | 4KuVPJqvnTPMOZgROmNwqIgIakN6y1tUxco0fKcWz7MGYlnfB+U7bvn3cP8A9bRz
20 | Fg==
21 | -----END CERTIFICATE-----
22 |
--------------------------------------------------------------------------------
/packages/binding-http/test/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdOhWrYn/1Z7yV
3 | gbQRZEafSzjzyan4f/xnoYlQ5puFGl2tqk9Lw3IWrMrCHm3+QCrdHkYfkFNNzvmk
4 | X2SwgrgV9Rsq049y5u8kSm354JnN4PS/mgfvd3A9qhihmnxZ9SQguF0xLIUFTI0v
5 | NUytuPILIf8nrPRBTLouWD2cKYaHnEXQMc0ClWdGkMp59U71JUlACLlTYNOzAdjN
6 | Xof8+LX33J696mdzeo2eUYsPGvW4/PHuJmtHkatKyNBO2MYAxGeUXa0SKfHoESAh
7 | /Wb7o+uJi0Jn0Uq8EIqNXCn+2+9dZBzI0O4m6by7ZMSsPdP8sAE/ndded8Q91+yX
8 | tgV9Y1xNAgMBAAECggEAZd2WFsmPRA/VTT5hDNUQk87OVasZQdyk+47tLLxTBjIC
9 | yrGuO6OuR/SelE3wte8UDacgAO6y/RP97YsjUQeP/kRTkx/BYNYnbZ18EGA0UhFw
10 | gT1KxCBKJYrKNrds5Ps0/IAIIVlvkuYR6JfxS9jqUuf/lmRUQDE1VZu6GssgMBaQ
11 | uNN1eSl1abNkv+FzSpeRf64sbOjAKMYMqeVRT/OXoQ+Fed/sMR5uCRKnzf+HEOTo
12 | rRcStdqjTZfrhGsLU9PmUr5NSVojk057zg8EpMeE+AOZJg705enN17g0Lnk16wXC
13 | PTjZqlNfku4XHpAPW6Chgjy6Yq0O2plgd/VUy6BZYQKBgQD6Z1+JhoTeY3ew8pne
14 | rMrqEq0HhYx15BCvgbBi/LlLQVCk1SlEFB3Kyow9ePyJyS0gMo0s0PPg+UgTRiP6
15 | F4KKeyq+ebarQQ6cazOBkppmS+46201UjVUtWPKGxYEzXTL4eW4bNvZvPYVbZYH1
16 | sZyIqHP7IN23t5GyzKq2VdIKNQKBgQDiK8hYF/8SPRLIyoArdRhUI2j6fPLNyq6B
17 | I/Yw9/Xad17ZXSz1yp6kEjF9zMG/7RjsYPlNSMUO3qvZeb/rlr0MUcTGvnXUf2Ac
18 | D4ilL2In64hnvmVymXZsKjCdIsKXhUn2MfTut/Oxm9r/390zJ3jJJhrUxZxGiT3T
19 | pKIx55GMuQKBgQCyHEWAdQadiPLiEi4Qjafnx1D8QKogURDtRbpJLqo+NT8/f7/S
20 | hNyMGnaWYzB+cXJ/rHVuo1JVe/sgeousoHxiNCm7QqgEOEpESJxiVf0tNmVFyCfB
21 | NKaZkuMvqdy0xF41D2qaQQYZKhFpaVJ/iM5nBis5Pa93tkMUgzAKchDs4QKBgQDe
22 | 6conUVdcUYd/EV8r9dgJrXDdWWMyA27k513Ru8K8FOUOFXCnvJGJIklXNQVNNdFX
23 | wOhWDL/0PPFhgkbvWv1u8/Se8b9OtlAyt/i03jO/Jryli5mPTsPSLe8GIOlrz7or
24 | BefjlLiCOBusD6eDsIaysnTFexLgzol6XIxj5VmmOQKBgEjgJIVpdpuquIdM3a0q
25 | nUgppPhWyCxACIfWEyLWZZNi68PdM1lr3C1pm4tBJrP17poLOWKd2iQTqu5+zZaq
26 | TeC7S1quBgaBgJWPmrcG6qTzMF7gt8HMafikF2gmsOAcrhsBiPvcbl6jd9qe5toW
27 | 4uu1Qsft3nPMgpjM15neMof+
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/packages/binding-http/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-http/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-mbus/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-mbus/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-mbus",
3 | "version": "0.9.2",
4 | "description": "M-Bus TCP client protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/thingweb/node-wot/tree/master/packages/binding-mbus",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/mbus.js",
15 | "types": "dist/mbus.d.ts",
16 | "dependencies": {
17 | "@node-wot/core": "0.9.2",
18 | "node-mbus": "^2.2.4",
19 | "rxjs": "5.5.11"
20 | },
21 | "scripts": {
22 | "build": "tsc -b",
23 | "test": "mocha --require ts-node/register --extension ts",
24 | "lint": "eslint .",
25 | "lint:fix": "eslint . --fix",
26 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
27 | },
28 | "bugs": {
29 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
30 | },
31 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-mbus#readme",
32 | "directories": {
33 | "test": "test"
34 | },
35 | "eslintConfig": {
36 | "extends": "../../.eslintrc.js"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/binding-mbus/src/mbus-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ProtocolClientFactory, ProtocolClient, createInfoLogger } from "@node-wot/core";
17 | import MBusClient from "./mbus-client";
18 |
19 | const info = createInfoLogger("binding-mbus", "mbus-client-factory");
20 |
21 | export default class MBusClientFactory implements ProtocolClientFactory {
22 | public readonly scheme: string = "mbus+tcp";
23 |
24 | public getClient(): ProtocolClient {
25 | info(`MBusClientFactory creating client for '${this.scheme}'`);
26 | return new MBusClient();
27 | }
28 |
29 | public init(): boolean {
30 | return true;
31 | }
32 |
33 | public destroy(): boolean {
34 | return true;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/binding-mbus/src/mbus.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Form } from "@node-wot/core";
17 | export { default as MBusClientFactory } from "./mbus-client-factory";
18 | export { default as MBusClient } from "./mbus-client";
19 | export * from "./mbus-client";
20 | export * from "./mbus-client-factory";
21 |
22 | export class MBusForm extends Form {
23 | /**
24 | * Physical address of the unit connected to the bus.
25 | */
26 | public "mbus:unitID": number;
27 | /**
28 | * Defines the starting address of registers or coils that are
29 | * meant to be written.
30 | */
31 | public "mbus:offset"?: number;
32 | /**
33 | * Timeout in milliseconds of the mbus request. Default to 1000 milliseconds
34 | */
35 | public "mbus:timeout"?: number;
36 | }
37 |
--------------------------------------------------------------------------------
/packages/binding-mbus/src/node-mbus.d.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | declare module "node-mbus";
17 |
--------------------------------------------------------------------------------
/packages/binding-mbus/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-mbus/test/mbus-connection-test.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { should } from "chai";
16 | import * as chai from "chai";
17 | import { MBusForm } from "../src/mbus";
18 | import chaiAsPromised from "chai-as-promised";
19 | import { MBusConnection, PropertyOperation } from "../src/mbus-connection";
20 |
21 | // should must be called to augment all variables
22 | should();
23 | chai.use(chaiAsPromised);
24 |
25 | describe("mbus connection test", () => {
26 | before(() => {
27 | /* nothing */
28 | });
29 |
30 | after(() => {
31 | /* nothing */
32 | });
33 |
34 | it("should throw for timeout", function () {
35 | if (process.platform === "win32") {
36 | this.skip();
37 | }
38 |
39 | const connection = new MBusConnection("127.0.0.1", 806, {
40 | connectionTimeout: 200,
41 | connectionRetryTime: 10,
42 | maxRetries: 1,
43 | });
44 | return connection.connect().should.eventually.be.rejectedWith("Max connection retries");
45 | }).timeout(10000);
46 |
47 | describe("Operation", () => {
48 | it("should throw with timeout", async function () {
49 | if (process.platform === "win32") {
50 | this.skip();
51 | }
52 |
53 | const form: MBusForm = {
54 | href: "mbus+tcp://127.0.0.1:806",
55 | "mbus:offset": 0,
56 | "mbus:unitID": 1,
57 | };
58 | const connection = new MBusConnection("127.0.0.1", 806, {
59 | connectionTimeout: 1000,
60 | connectionRetryTime: 10,
61 | maxRetries: 1,
62 | });
63 | const op = new PropertyOperation(form);
64 | connection.enqueue(op);
65 |
66 | await connection.execute(op).should.eventually.be.rejected;
67 |
68 | connection.close();
69 | }).timeout(10000);
70 | });
71 | });
72 |
--------------------------------------------------------------------------------
/packages/binding-mbus/test/test-servient.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | // global W3C WoT Scripting API definitions
17 | import * as WoT from "wot-typescript-definitions";
18 | // node-wot implementation of W3C WoT Servient
19 | import { Servient } from "@node-wot/core";
20 |
21 | import { MBusClientFactory } from "../src/mbus";
22 |
23 | export default class DefaultServient extends Servient {
24 | public constructor() {
25 | super();
26 | this.addClientFactory(new MBusClientFactory());
27 | }
28 |
29 | /**
30 | * start
31 | */
32 | public start(): Promise {
33 | return super.start();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/binding-mbus/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-mbus/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-modbus/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-modbus/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-modbus",
3 | "version": "0.9.2",
4 | "description": "Modbus TCP client protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "contributors": [
7 | "Siemens AG"
8 | ],
9 | "license": "EPL-2.0 OR W3C-20150513",
10 | "repository": "https://github.com/thingweb/node-wot/tree/master/packages/binding-modbus",
11 | "publishConfig": {
12 | "access": "public"
13 | },
14 | "files": [
15 | "dist/"
16 | ],
17 | "main": "dist/modbus.js",
18 | "types": "dist/modbus.d.ts",
19 | "dependencies": {
20 | "@node-wot/core": "0.9.2",
21 | "modbus-serial": "8.0.17",
22 | "rxjs": "5.5.11",
23 | "wot-typescript-definitions": "0.8.0-SNAPSHOT.30"
24 | },
25 | "scripts": {
26 | "build": "tsc -b",
27 | "test": "mocha --require ts-node/register --extension ts",
28 | "lint": "eslint .",
29 | "lint:fix": "eslint . --fix",
30 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
31 | },
32 | "bugs": {
33 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
34 | },
35 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-modbus#readme",
36 | "directories": {
37 | "test": "test"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/binding-modbus/src/modbus-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { ProtocolClientFactory, ProtocolClient, createDebugLogger, createWarnLogger } from "@node-wot/core";
16 | import ModbusClient from "./modbus-client";
17 |
18 | const debug = createDebugLogger("binding-modbus", "modbus-client-factory");
19 | const warn = createWarnLogger("binding-modbus", "modbus-client-factory");
20 |
21 | export default class ModbusClientFactory implements ProtocolClientFactory {
22 | public readonly scheme: string = "modbus+tcp";
23 | private singleton?: ModbusClient;
24 |
25 | public getClient(): ProtocolClient {
26 | debug(`Get client for '${this.scheme}'`);
27 | this.init();
28 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- singleton is initialized in init()
29 | return this.singleton!;
30 | }
31 |
32 | public init(): boolean {
33 | if (!this.singleton) {
34 | debug(`Initializing client for '${this.scheme}'`);
35 | this.singleton = new ModbusClient();
36 | }
37 | return true;
38 | }
39 |
40 | public destroy(): boolean {
41 | debug(`Destroying client for '${this.scheme}'`);
42 | if (!this.singleton) {
43 | warn(`Destroying a not initialized client factory for '${this.scheme}'`);
44 | return true; // do not cause an error
45 | }
46 | this.singleton.stop();
47 | this.singleton = undefined;
48 | return true;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/binding-modbus/src/utils.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { ModbusFunction, ModbusEntity } from "./modbus";
16 |
17 | export function modbusFunctionToEntity(modbusFun: ModbusFunction): ModbusEntity {
18 | switch (modbusFun) {
19 | case ModbusFunction.readCoil:
20 | return "Coil";
21 | case ModbusFunction.readDiscreteInput:
22 | return "DiscreteInput";
23 | case ModbusFunction.readInputRegister:
24 | return "InputRegister";
25 | case ModbusFunction.readHoldingRegisters:
26 | return "HoldingRegister";
27 | case ModbusFunction.writeMultipleCoils:
28 | return "Coil";
29 | case ModbusFunction.writeMultipleHoldingRegisters:
30 | return "HoldingRegister";
31 | case ModbusFunction.writeSingleCoil:
32 | return "Coil";
33 | case ModbusFunction.writeSingleHoldingRegister:
34 | return "HoldingRegister";
35 | default:
36 | throw new Error("Cannot convert " + modbusFun + " to ModbusEntity");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/binding-modbus/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-modbus/test/test-servient.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | // global W3C WoT Scripting API definitions
17 | import * as WoT from "wot-typescript-definitions";
18 | // node-wot implementation of W3C WoT Servient
19 | import { Servient } from "@node-wot/core";
20 |
21 | import { ModbusClientFactory } from "../src/modbus";
22 |
23 | export default class DefaultServient extends Servient {
24 | public constructor() {
25 | super();
26 | this.addClientFactory(new ModbusClientFactory());
27 | }
28 |
29 | /**
30 | * start
31 | */
32 | public start(): Promise {
33 | return super.start();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/binding-modbus/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-modbus/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-mqtt",
3 | "version": "0.9.2",
4 | "description": "MQTT binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-mqtt",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/mqtt.js",
15 | "types": "dist/mqtt.d.ts",
16 | "dependencies": {
17 | "@node-wot/core": "0.9.2",
18 | "aedes": "^0.46.2",
19 | "mqtt": "^5.3.2",
20 | "rxjs": "5.5.11"
21 | },
22 | "scripts": {
23 | "build": "tsc -b",
24 | "test": "mocha --require ts-node/register --extension ts",
25 | "lint": "eslint .",
26 | "lint:fix": "eslint . --fix",
27 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
28 | },
29 | "bugs": {
30 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
31 | },
32 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-mqtt#readme",
33 | "directories": {
34 | "test": "test"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/src/mqtt-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Protocol test suite to test protocol implementations
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createDebugLogger } from "@node-wot/core";
21 | import MqttClient from "./mqtt-client";
22 |
23 | const debug = createDebugLogger("binding-mqtt", "mqtt-client-factory");
24 |
25 | export default class MqttClientFactory implements ProtocolClientFactory {
26 | public readonly scheme: string = "mqtt";
27 | private readonly clients: Array = [];
28 |
29 | getClient(): ProtocolClient {
30 | const client = new MqttClient();
31 | this.clients.push(client);
32 | return client;
33 | }
34 |
35 | init(): boolean {
36 | return true;
37 | }
38 |
39 | destroy(): boolean {
40 | debug(`MqttClientFactory stopping all clients for '${this.scheme}'`);
41 | this.clients.forEach((client) => client.stop());
42 | return true;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/src/mqtt.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Protocol test suite to test protocol implementations
18 | */
19 |
20 | import { Form } from "@node-wot/core";
21 |
22 | export { default as MqttClient } from "./mqtt-client";
23 | export { default as MqttClientFactory } from "./mqtt-client-factory";
24 | export { default as MqttsClientFactory } from "./mqtts-client-factory";
25 | export { default as MqttBrokerServer } from "./mqtt-broker-server";
26 |
27 | export * from "./mqtt-client";
28 | export * from "./mqtt-client-factory";
29 | export * from "./mqtts-client-factory";
30 | export * from "./mqtt-broker-server";
31 |
32 | export type MqttQoS = "0" | "1" | "2";
33 | export class MqttForm extends Form {
34 | public "mqv:qos"?: MqttQoS = "0";
35 | public "mqv:retain"?: boolean;
36 |
37 | public "mqv:topic"?: string;
38 |
39 | public "mqv:filter"?: string | string[];
40 |
41 | public "mqv:controlPacket"?: "publish" | "subscribe" | "unsubscribe";
42 | }
43 |
44 | export interface MqttClientConfig {
45 | // username & password are redundant here (also find them in MqttClientSecurityParameters)
46 | // because MqttClient.setSecurity() method can inject authentication credentials into this interface
47 | // which will be then passed to mqtt.connect() once for all
48 | username?: string;
49 | password?: string;
50 | rejectUnauthorized?: boolean;
51 | }
52 |
53 | export interface MqttBrokerServerConfig {
54 | uri: string;
55 | user?: string;
56 | psw?: string;
57 | clientId?: string;
58 | protocolVersion?: 3 | 4 | 5;
59 | rejectUnauthorized?: boolean;
60 | selfHost?: boolean;
61 | key?: Buffer;
62 | cert?: Buffer | undefined;
63 | selfHostAuthentication?: MqttClientConfig[];
64 | }
65 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/src/mqtts-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Protocol test suite to test protocol implementations
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createDebugLogger } from "@node-wot/core";
21 | import { MqttClientConfig } from "./mqtt";
22 | import MqttClient from "./mqtt-client";
23 |
24 | const debug = createDebugLogger("binding-mqtt", "mqtts-client-factory");
25 |
26 | export default class MqttsClientFactory implements ProtocolClientFactory {
27 | public readonly scheme: string = "mqtts";
28 | private readonly clients: Array = [];
29 |
30 | // eslint-disable-next-line no-useless-constructor
31 | constructor(private readonly config: MqttClientConfig) {}
32 | getClient(): ProtocolClient {
33 | const client = new MqttClient(this.config, true);
34 | this.clients.push(client);
35 | return client;
36 | }
37 |
38 | init(): boolean {
39 | return true;
40 | }
41 |
42 | destroy(): boolean {
43 | debug(`MqttClientFactory stopping all clients for '${this.scheme}'`);
44 | this.clients.forEach((client) => client.stop());
45 | return true;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/src/util.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { createLoggers } from "@node-wot/core";
16 | import { MqttQoS } from "./mqtt";
17 | import { IClientPublishOptions } from "mqtt";
18 |
19 | const { warn } = createLoggers("binding-mqtt", "mqtt-util");
20 |
21 | export function mapQoS(qos: MqttQoS | undefined): Required["qos"] {
22 | switch (qos) {
23 | case "0":
24 | return 0;
25 | case "1":
26 | return 1;
27 | case "2":
28 | return 2;
29 | case undefined:
30 | return 0;
31 | default:
32 | warn(`MqttClient received unsupported QoS level '${qos}'`);
33 | warn(`MqttClient falling back to QoS level '0'`);
34 | return 0;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-mqtt/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-netconf/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-netconf/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-netconf",
3 | "version": "0.9.2",
4 | "description": "NetConf client protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/thingweb/node-wot/tree/master/packages/binding-netconf",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/netconf.js",
15 | "types": "dist/netconf.d.ts",
16 | "dependencies": {
17 | "@node-wot/core": "0.9.2",
18 | "case-1.5.3": "npm:case@^1.5.3",
19 | "node-netconf": "^1.1.2",
20 | "rxjs": "5.5.11",
21 | "url-parse": "^1.5.8"
22 | },
23 | "scripts": {
24 | "build": "tsc -b",
25 | "test": "mocha --require ts-node/register test/netconf-client-test.ts",
26 | "lint": "eslint .",
27 | "lint:fix": "eslint . --fix",
28 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
29 | },
30 | "bugs": {
31 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
32 | },
33 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-netconf#readme",
34 | "directories": {
35 | "test": "test"
36 | },
37 | "keywords": [],
38 | "devDependencies": {
39 | "@types/node-netconf": "npm:@types/netconf@^2.0.0",
40 | "@types/url-parse": "^1.4.3"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/binding-netconf/src/netconf-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2019 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Netconf protocol binding
18 | */
19 | import { ProtocolClientFactory, ProtocolClient, ContentSerdes, createDebugLogger } from "@node-wot/core";
20 | import NetconfClient from "./netconf-client";
21 | import NetconfCodec from "./codecs/netconf-codec";
22 |
23 | const debug = createDebugLogger("binding-netconf", "netconf-client-factory");
24 |
25 | export default class NetconfClientFactory implements ProtocolClientFactory {
26 | public readonly scheme: string = "netconf";
27 | public contentSerdes: ContentSerdes = ContentSerdes.get();
28 |
29 | public getClient(): ProtocolClient {
30 | this.contentSerdes.addCodec(new NetconfCodec()); // add custom codec for NetConf
31 | debug(`NetconfClientFactory creating client for '${this.scheme}'`);
32 | return new NetconfClient();
33 | }
34 |
35 | public init = (): boolean => true;
36 | public destroy = (): boolean => true;
37 | }
38 |
--------------------------------------------------------------------------------
/packages/binding-netconf/src/netconf.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2019 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Form } from "@node-wot/core";
17 | export { default as NetconfClient } from "./netconf-client";
18 | export { default as NetconfClientFactory } from "./netconf-client-factory";
19 | export * from "./netconf";
20 | export * from "./netconf-client-factory";
21 | export class NetconfForm extends Form {
22 | public "nc:NSs"?: Record;
23 | public "nc:method"?: string;
24 | public "nc:target"?: string;
25 | }
26 |
27 | export type RpcMethod = "GET-CONFIG" | "EDIT-CONFIG" | "COMMIT" | "RPC";
28 |
29 | export interface NetConfCredentials {
30 | username: string;
31 | password?: string;
32 |
33 | privateKey?: string;
34 | }
35 |
36 | export function isRpcMethod(method?: string): method is RpcMethod {
37 | if (method == null) {
38 | return false;
39 | }
40 | return ["GET-CONFIG", "EDIT-CONFIG", "COMMIT", "RPC"].includes(method);
41 | }
42 |
--------------------------------------------------------------------------------
/packages/binding-netconf/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-netconf/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-netconf/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/binding-opcua/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-opcua/.mocharc.yml:
--------------------------------------------------------------------------------
1 | recursive: false
2 | require:
3 | - ts-node/register
4 | timeout: 100000
5 | enable-source-maps: true
6 | spec: "test/*-test.ts"
7 | bail: true
8 | parallel: false
9 |
--------------------------------------------------------------------------------
/packages/binding-opcua/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-opcua",
3 | "version": "0.9.2",
4 | "description": "opcua client protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/thingweb/node-wot/tree/master/packages/binding-opcua",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist",
13 | "src"
14 | ],
15 | "main": "dist/index.js",
16 | "types": "dist/index.d.ts",
17 | "devDependencies": {
18 | "should": "^13.2.3"
19 | },
20 | "dependencies": {
21 | "@node-wot/core": "0.9.2",
22 | "ajv": "^8.11.0",
23 | "ajv-formats": "^2.1.1",
24 | "node-opcua": "2.143.0",
25 | "node-opcua-address-space": "2.143.0",
26 | "node-opcua-basic-types": "2.139.0",
27 | "node-opcua-binary-stream": "2.139.0",
28 | "node-opcua-buffer-utils": "2.139.0",
29 | "node-opcua-client": "2.143.0",
30 | "node-opcua-constants": "2.139.0",
31 | "node-opcua-data-model": "2.139.0",
32 | "node-opcua-data-value": "2.142.0",
33 | "node-opcua-date-time": "2.139.0",
34 | "node-opcua-debug": "2.139.0",
35 | "node-opcua-extension-object": "2.139.0",
36 | "node-opcua-factory": "2.139.0",
37 | "node-opcua-json": "0.50.0",
38 | "node-opcua-nodeid": "2.139.0",
39 | "node-opcua-numeric-range": "2.139.0",
40 | "node-opcua-pseudo-session": "2.143.0",
41 | "node-opcua-service-browse": "2.143.0",
42 | "node-opcua-service-translate-browse-path": "2.143.0",
43 | "node-opcua-status-code": "2.139.0",
44 | "node-opcua-types": "2.143.0",
45 | "node-opcua-variant": "2.142.0",
46 | "rxjs": "5.5.11",
47 | "url": "^0.11.4"
48 | },
49 | "scripts": {
50 | "build": "tsc -b",
51 | "lint": "eslint .",
52 | "lint:fix": "eslint . --fix",
53 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\"",
54 | "ncu:opcua": "npx -y npm-check-updates -u -f \"node-opcua*\" -t newest",
55 | "test": "mocha"
56 | },
57 | "bugs": {
58 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
59 | },
60 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-opcua#readme",
61 | "directories": {
62 | "test": "test"
63 | },
64 | "keywords": []
65 | }
66 |
--------------------------------------------------------------------------------
/packages/binding-opcua/src/factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ProtocolClientFactory, ProtocolClient, ContentSerdes, createLoggers } from "@node-wot/core";
17 | import { OpcuaJSONCodec, OpcuaBinaryCodec } from "./codec";
18 | import { OPCUAProtocolClient } from "./opcua-protocol-client";
19 |
20 | const { debug } = createLoggers("binding-opcua", "factory");
21 |
22 | export class OPCUAClientFactory implements ProtocolClientFactory {
23 | readonly scheme: string = "opc.tcp";
24 |
25 | private _clients: OPCUAProtocolClient[] = [];
26 |
27 | public contentSerdes: ContentSerdes = ContentSerdes.get();
28 |
29 | constructor() {
30 | this.contentSerdes.addCodec(new OpcuaJSONCodec());
31 | this.contentSerdes.addCodec(new OpcuaBinaryCodec());
32 | }
33 |
34 | getClient(): ProtocolClient {
35 | debug(`OpcuaClientFactory creating client for '${this.scheme}'`);
36 | if (this._clients[0] != null) {
37 | return this._clients[0];
38 | }
39 | this._clients[0] = new OPCUAProtocolClient();
40 | return this._clients[0];
41 | }
42 |
43 | init(): boolean {
44 | debug("init");
45 | return true;
46 | }
47 |
48 | destroy(): boolean {
49 | debug("destroy");
50 |
51 | const clients = this._clients;
52 | this._clients = [];
53 | (async () => {
54 | for (const client of clients) {
55 | await client.stop();
56 | }
57 | })();
58 | return true;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/packages/binding-opcua/src/index.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | export * from "./factory";
17 | export * from "./codec";
18 | export * from "./opcua-protocol-client";
19 | // no protocol_client here => get access from factor
20 |
--------------------------------------------------------------------------------
/packages/binding-opcua/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-opcua/test/opcua-href-test.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2025 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { expect } from "chai";
17 |
18 | import { OPCUAProtocolClient } from "../src/opcua-protocol-client";
19 |
20 | describe("OPCUA Hrefs", () => {
21 | it("Example-1", () => {
22 | const form = { href: "opc.tcp://192.168.120.237:4840/?id=ns=10;i=12345" };
23 | const nodeId = OPCUAProtocolClient.getNodeId(form);
24 | expect(nodeId).equal("ns=10;i=12345");
25 | });
26 | it("Example-2", () => {
27 | const form = { href: "opc.tcp://192.168.120.237:4840/?id=nsu=http://widgets.com/schemas/hello;s=水 World" };
28 | const nodeId = OPCUAProtocolClient.getNodeId(form);
29 | expect(nodeId).equal("nsu=http://widgets.com/schemas/hello;s=水 World");
30 | });
31 | it("Example-3 #", () => {
32 | const form = { href: "opc.tcp://192.168.120.237:4840/?id=nsu=http://example.com/hello%23;s=temperature" };
33 | const nodeId = OPCUAProtocolClient.getNodeId(form);
34 | expect(nodeId).equal("nsu=http://example.com/hello#;s=temperature"); // %23 -> #
35 | });
36 | it("Example-4 &", () => {
37 | const form = { href: "opc.tcp://192.168.120.237:4840/?id=nsu=http://example.com/a%26b" };
38 | const nodeId = OPCUAProtocolClient.getNodeId(form);
39 | expect(nodeId).equal("nsu=http://example.com/a&b"); // %26 -> &
40 | });
41 | it("Example-5 relative", () => {
42 | const form = { href: "/?id=ns=10;i=12345" };
43 | expect(() => OPCUAProtocolClient.getNodeId(form)).to.throw(Error, "Invalid URL");
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/packages/binding-opcua/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src",
6 | "skipLibCheck": true
7 | },
8 | "include": ["./src/**/*"],
9 | "references": [{ "path": "../core" }]
10 | }
11 |
--------------------------------------------------------------------------------
/packages/binding-websockets/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/binding-websockets/README.md:
--------------------------------------------------------------------------------
1 | # Websocket Protocol Binding of node-wot
2 |
3 | Current Maintainer(s): [@miguelrk](https://github.com/miguelrk)
4 |
--------------------------------------------------------------------------------
/packages/binding-websockets/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/binding-websockets",
3 | "version": "0.9.2",
4 | "description": "WebSockets client & server protocol binding for node-wot",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-websockets",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "dist/ws.js",
15 | "types": "dist/ws.d.ts",
16 | "browser": "dist/ws-browser.js",
17 | "dependencies": {
18 | "@node-wot/binding-http": "0.9.2",
19 | "@node-wot/core": "0.9.2",
20 | "rxjs": "^5.5.11",
21 | "slugify": "^1.4.5",
22 | "ws": "^7.5.10"
23 | },
24 | "scripts": {
25 | "build": "tsc -b",
26 | "test": "mocha --require ts-node/register --extension ts",
27 | "lint": "eslint .",
28 | "lint:fix": "eslint . --fix",
29 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\""
30 | },
31 | "bugs": {
32 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
33 | },
34 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/binding-websockets#readme",
35 | "directories": {
36 | "test": "test"
37 | },
38 | "keywords": []
39 | }
40 |
--------------------------------------------------------------------------------
/packages/binding-websockets/src/ws-browser.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2019 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | export { default as WebSocketClient } from "./ws-client";
17 | export { default as WebSocketClientFactory } from "./ws-client-factory";
18 | export { default as WebSocketSecureClientFactory } from "./wss-client-factory";
19 | export * from "./ws-client";
20 | export * from "./ws-client-factory";
21 | export * from "./wss-client-factory";
22 |
--------------------------------------------------------------------------------
/packages/binding-websockets/src/ws-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * HTTP client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient, createLoggers } from "@node-wot/core";
21 | import WebSocketClient from "./ws-client";
22 |
23 | const { debug } = createLoggers("binding-websockets", "ws-client-factory");
24 |
25 | export default class WebSocketClientFactory implements ProtocolClientFactory {
26 | public readonly scheme: string = "ws";
27 | private clientSideProxy: unknown = null;
28 |
29 | constructor(proxy: unknown = null) {
30 | this.clientSideProxy = proxy;
31 | }
32 |
33 | public getClient(): ProtocolClient {
34 | debug(`HttpClientFactory creating client for '${this.scheme}'`);
35 | return new WebSocketClient();
36 | }
37 |
38 | public init(): boolean {
39 | // info(`HttpClientFactory for '${HttpClientFactory.scheme}' initializing`);
40 | // TODO uncomment info if something is executed here
41 | return true;
42 | }
43 |
44 | public destroy(): boolean {
45 | // info(`HttpClientFactory for '${HttpClientFactory.scheme}' destroyed`);
46 | // TODO uncomment info if something is executed here
47 | return true;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/packages/binding-websockets/src/ws.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | export { default as WebSocketServer } from "./ws-server";
17 | export { default as WebSocketClient } from "./ws-client";
18 | export { default as WebSocketClientFactory } from "./ws-client-factory";
19 | export { default as WebSocketSecureClientFactory } from "./wss-client-factory";
20 | export * from "./ws-server";
21 | export * from "./ws-client";
22 | export * from "./ws-client-factory";
23 | export * from "./wss-client-factory";
24 |
--------------------------------------------------------------------------------
/packages/binding-websockets/src/wss-client-factory.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * HTTPS client Factory
18 | */
19 |
20 | import { ProtocolClientFactory, ProtocolClient } from "@node-wot/core";
21 |
22 | export default class WssClientFactory implements ProtocolClientFactory {
23 | public readonly scheme: string = "wss";
24 |
25 | // eslint-disable-next-line no-useless-constructor
26 | constructor() {
27 | // TODO: implement and remove eslint-ignore-useless-constructor
28 | }
29 |
30 | public getClient(): ProtocolClient {
31 | throw new Error("WssClientFactory for 'wss' is not implemented");
32 | }
33 |
34 | public init(): boolean {
35 | // info(`HttpsClientFactory for '${HttpsClientFactory.scheme}' initializing`);
36 | // TODO uncomment info if something is executed here
37 | return true;
38 | }
39 |
40 | public destroy(): boolean {
41 | // info(`HttpsClientFactory for '${HttpsClientFactory.scheme}' destroyed`);
42 | // TODO uncomment info if something is executed here
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/binding-websockets/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/binding-websockets/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/binding-websockets/test/ws-tests.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /**
17 | * Protocol test suite to test protocol implementations
18 | */
19 |
20 | import Servient, { createLoggers } from "@node-wot/core";
21 | import { suite, test } from "@testdeck/mocha";
22 | import { expect, should } from "chai";
23 | import WebSocketServer from "../src/ws-server";
24 |
25 | const { info } = createLoggers("binding-websockets", "ws-tests");
26 |
27 | // should must be called to augment all variables
28 | should();
29 |
30 | const port = 31080;
31 | @suite("WebSockets binding")
32 | class WebSocketsTest {
33 | @test async "should start and stop own server"() {
34 | const wsServer = new WebSocketServer({ port });
35 |
36 | await wsServer.start(new Servient());
37 | expect(wsServer.getPort()).to.eq(port); // from test
38 |
39 | info("Test stopping WebSocket server");
40 |
41 | await wsServer.stop();
42 | expect(wsServer.getPort()).to.eq(-1); // from getPort() when not listening
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/binding-websockets/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src"
6 | },
7 | "include": ["src/**/*"],
8 | "references": [{ "path": "../core" }]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/browser-bundle/.gitignore:
--------------------------------------------------------------------------------
1 | types/
2 |
--------------------------------------------------------------------------------
/packages/browser-bundle/README.md:
--------------------------------------------------------------------------------
1 | # Browser Bundle of node-wot
2 |
3 | Bundle to run node-wot as browser-side library. Note, this will only include the node-wot in client mode with limited binding support.
4 |
5 | Current Maintainer(s): [@relu91](https://github.com/relu91) [@danielpeintner](https://github.com/danielpeintner)
6 |
7 | ## Supported bindings
8 |
9 | HTTP / HTTPS / WebSockets
10 |
11 | ## Embedding node-wot library in HTML
12 |
13 | Include the following script tag in your html
14 |
15 | ```js
16 |
17 | ```
18 |
19 | You can access all node-wot functionality through the "WoT" global object:
20 |
21 | ```js
22 | var servient = new WoT.Core.Servient();
23 | var client = new WoT.Http.HttpClient();
24 | ```
25 |
26 | ## Using node-wot browser bundle library in web frameworks (e.g., Angular)
27 |
28 | Install browser-bundle in your project by running
29 |
30 | - `npm install @node-wot/browser-bundle`
31 |
32 | ## Example and live demo
33 |
34 | An example of how to use node-wot as a browser-side library can be found under `https://github.com/eclipse-thingweb/node-wot/blob/master/examples/browser/index.html`.
35 | To run it live, open [`examples/browser/index.html`](http://plugfest.thingweb.io/webui/) in a modern browser,
36 | and consume the test Thing available under `http://plugfest.thingweb.io:8083/testthing` to interact with it.
37 |
38 | ## More Details
39 |
40 | See
41 |
--------------------------------------------------------------------------------
/packages/browser-bundle/esbuild.js:
--------------------------------------------------------------------------------
1 | const { build } = require("esbuild");
2 | const { polyfillNode } = require("esbuild-plugin-polyfill-node");
3 | const { rimraf } = require("rimraf");
4 | const fs = require("fs");
5 |
6 | const outdir = "dist";
7 |
8 | /**
9 | * @type {import('esbuild').BuildOptions}
10 | */
11 | const options = {
12 | entryPoints: ["index.ts"],
13 | bundle: true,
14 | outfile: `${outdir}/wot-bundle.js`,
15 | format: "iife",
16 | platform: "browser",
17 | globalName: "WoT",
18 | sourcemap: true,
19 | plugins: [
20 | polyfillNode({
21 | globals: {
22 | global: false,
23 | __dirname: false,
24 | __filename: false,
25 | buffer: true,
26 | process: false,
27 | },
28 | }),
29 | ],
30 | };
31 |
32 | async function run() {
33 | const start = Date.now();
34 | await rimraf(outdir);
35 | await build(options);
36 |
37 | options.minify = true;
38 | options.outfile = `${outdir}/wot-bundle.min.js`;
39 | await build(options);
40 |
41 | options.minify = false;
42 | options.entryPoints = ["index.ts", "../binding-http", "../core", "../binding-websockets"];
43 | options.splitting = true;
44 | options.outfile = undefined;
45 | options.outdir = `${outdir}/esm`;
46 | options.format = "esm";
47 | options.treeShaking = true;
48 |
49 | await build(options);
50 |
51 | console.log(`Build time: ${Date.now() - start}ms`);
52 |
53 | console.log("Build output:");
54 | await displaySizes(`${outdir}`);
55 | }
56 |
57 | async function displaySizes(path) {
58 | // log generated files with their size in KB
59 | const files = fs.readdirSync(path);
60 | for (const file of files) {
61 | const stat = fs.statSync(`${path}/${file}`);
62 | if (stat.isDirectory()) {
63 | displaySizes(`${path}/${file}`);
64 | continue;
65 | }
66 | console.log(`- ${path}/${file} ${Math.round((stat.size / 1024) * 100) / 100} KB`);
67 | }
68 | }
69 |
70 | run().catch((e) => {
71 | console.error(e);
72 | process.exit(1);
73 | });
74 |
--------------------------------------------------------------------------------
/packages/browser-bundle/index.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2024 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | "use strict";
16 | export * as Core from "@node-wot/core";
17 | export * as Http from "@node-wot/binding-http";
18 | export * as WebSocket from "@node-wot/binding-websockets";
19 |
--------------------------------------------------------------------------------
/packages/browser-bundle/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/browser-bundle",
3 | "version": "0.9.2",
4 | "description": "A node-wot bundle that can run in a web browser",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/browser-bundle",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "module": "./dist/esm/browser-bundle/index.js",
12 | "types": "types/index.d.ts",
13 | "files": [
14 | "dist/"
15 | ],
16 | "main": "dist/wot-bundle.min.js",
17 | "devDependencies": {
18 | "@esm-bundle/chai": "^4.3.4-fix.0",
19 | "@esm-bundle/chai-as-promised": "^7.1.1",
20 | "@jspm/core": "^2.1.0",
21 | "@web/test-runner": "^0.19.0",
22 | "@web/test-runner-commands": "^0.9.0",
23 | "@web/test-runner-playwright": "^0.11.0",
24 | "esbuild": "^0.25.0",
25 | "esbuild-plugin-polyfill-node": "^0.3.0",
26 | "json-schema-faker": "^0.5.6",
27 | "rimraf": "^6.0.1"
28 | },
29 | "scripts": {
30 | "build": "node esbuild.js",
31 | "test:browser": "wtr \"test/**/*.js\" --node-resolve",
32 | "format": "prettier --write *.js test/*.js *.ts \"**/*.json\""
33 | },
34 | "bugs": {
35 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
36 | },
37 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/browser-bundle#readme",
38 | "keywords": [],
39 | "dependencies": {
40 | "@node-wot/binding-http": "0.9.2",
41 | "@node-wot/binding-websockets": "0.9.2",
42 | "@node-wot/core": "0.9.2"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/browser-bundle/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "resolveJsonModule": true,
5 | "outDir": "types",
6 | "emitDeclarationOnly": true
7 | },
8 | "include": ["index.ts"],
9 | "references": [
10 | {
11 | "path": "../core"
12 | },
13 | {
14 | "path": "../binding-http"
15 | },
16 | {
17 | "path": "../binding-websockets"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/cli/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/cli/bin/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | // WARNING: this is a workaround for issue https://github.com/npm/cli/issues/2632
3 | require("../dist/cli.js");
4 |
--------------------------------------------------------------------------------
/packages/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/cli",
3 | "version": "0.9.2",
4 | "description": "servient command line interface",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/cli",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/"
13 | ],
14 | "main": "bin/index.js",
15 | "types": "dist/cli.d.ts",
16 | "bin": {
17 | "wot-servient": "bin/index.js"
18 | },
19 | "optionalDependencies": {
20 | "ts-node": "10.9.1"
21 | },
22 | "dependencies": {
23 | "@node-wot/binding-coap": "0.9.2",
24 | "@node-wot/binding-file": "0.9.2",
25 | "@node-wot/binding-http": "0.9.2",
26 | "@node-wot/binding-mqtt": "0.9.2",
27 | "@node-wot/core": "0.9.2",
28 | "@thingweb/thing-model": "^1.0.4",
29 | "ajv": "^8.11.0",
30 | "commander": "^9.1.0",
31 | "dotenv": "^16.4.7",
32 | "lodash": "^4.17.21",
33 | "vm2": "3.9.18"
34 | },
35 | "scripts": {
36 | "build": "tsc -b",
37 | "start": "ts-node src/cli.ts",
38 | "debug": "node -r ts-node/register --inspect-brk=9229 src/cli.ts",
39 | "lint": "eslint .",
40 | "lint:fix": "eslint . --fix",
41 | "format": "prettier --write \"src/**/*.ts\" \"**/*.json\"",
42 | "test": "mocha --require ts-node/register --extension ts"
43 | },
44 | "bugs": {
45 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
46 | },
47 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/cli#readme",
48 | "keywords": [],
49 | "devDependencies": {
50 | "@types/lodash": "^4.14.199"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/packages/cli/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/cli/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src",
6 | "resolveJsonModule": true,
7 | "esModuleInterop": true
8 | },
9 | "include": ["src/**/*", "src/*.json"],
10 | "references": [
11 | { "path": "../core" },
12 | { "path": "../binding-http" },
13 | { "path": "../binding-file" },
14 | { "path": "../binding-websockets" },
15 | { "path": "../binding-coap" },
16 | { "path": "../binding-mqtt" }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/packages/cli/wot-servient.conf.json.md:
--------------------------------------------------------------------------------
1 | # Configuration of WoT Servient
2 |
3 | File "wot-servient.conf.json"
4 |
5 | ```
6 | {
7 | "servient": {
8 | "clientOnly": CLIENTONLY,
9 | "staticAddress": STATIC,
10 | "scriptAction": RUNSCRIPT
11 | },
12 | "http": {
13 | "port": HPORT,
14 | "proxy": PROXY,
15 | "allowSelfSigned": ALLOW
16 | },
17 | "mqtt" : {
18 | "broker": BROKER-URL,
19 | "username": BROKER-USERNAME,
20 | "password": BROKER-PASSWORD,
21 | "clientId": BROKER-UNIQUEID,
22 | "protocolVersion": MQTT_VERSION
23 | },
24 | "log": {
25 | "level": LEVEL
26 | },
27 | "credentials": {
28 | THING_ID1: {
29 | "token": TOKEN
30 | },
31 | THING_ID2: {
32 | "username": USERNAME,
33 | "password": PASSWORD
34 | }
35 | }
36 | }
37 | ```
38 |
39 | CLIENTONLY is a boolean telling whether to start server part or not
40 |
41 | STATIC is a string indicating a static hostname / IP address
42 |
43 | RUNSCRIPT is a boolean indicating whether to provide the 'runScript' Action
44 |
45 | HPORT is a number defining the HTTP listening port
46 |
47 | PROXY is an object with `"href"` for the proxy URI, `"authorization"` for `"Basic"` or `"Bearer"`, and then corresponding credential fields `"username"`/`"password"` or `"token"` as defined below
48 |
49 | ALLOW is a boolean indicating whether self-signed certificates should be allowed
50 |
51 | BROKER-URL is a string indicating the MQTT broker URL with optional port number (default :1883)
52 |
53 | BROKER-USERNAME is a string indicating the MQTT broker username
54 |
55 | BROKER-PASSWORD is a string indicating the MQTT broker password
56 |
57 | BROKER-UNIQUEID is a string indicating an optional MQTT broker unique ID
58 |
59 | MQTT_VERSION is a number indicating the MQTT protocol version to be used (3, 4, or 5)
60 |
61 | LEVEL is a string or number to set the logging level: `{ error: 0, warn: 1, info: 2, debug: 3 }` (default `info`)
62 |
63 | THING_IDx is a TD @id for which credentials should be configured
64 |
65 | TOKEN is an OAuth (Bearer) token
66 |
67 | USERNAME is an HTTP Basic Auth username
68 |
69 | PASSWORD is an HTTP Basic Auth password
70 |
--------------------------------------------------------------------------------
/packages/core/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/core/README.md:
--------------------------------------------------------------------------------
1 | # Core of node-wot
2 |
3 | The core of node-wot is the entry point allowing to attach dedicated bindings such as:
4 |
5 | - [HTTP](https://github.com/eclipse-thingweb/node-wot/blob/master/packages/binding-http)
6 | - [CoAP](https://github.com/eclipse-thingweb/node-wot/blob/master/packages/binding-coap)
7 | - ...
8 |
9 | or to create user-specific bindings.
10 |
11 | Current Maintainer(s): [@danielpeintner](https://github.com/danielpeintner) [@relu91](https://github.com/relu91) [@JKRhb](https://github.com/JKRhb)
12 |
13 | ### Prerequisites
14 |
15 | - `npm install @node-wot/core`
16 |
17 | ### Examples
18 |
19 | see binding examples such as
20 |
21 | - https://github.com/eclipse-thingweb/node-wot/blob/master/packages/binding-http
22 | - https://github.com/eclipse-thingweb/node-wot/blob/master/packages/binding-coap
23 |
24 | ## Codecs
25 |
26 | ### Octet-Stream
27 |
28 | The octet-stream codec enables deserialization and serialization of binary data. To encode and decode sequences of bytes, the octet-stream codec uses the following content type parameters:
29 | | Parameter | Description | Default |
30 | | --- | --- | --- |
31 | | `length` | Number of bytes produced during serialization or consumed during deserialization | |
32 | | `signed` | Signedness of the data type, `true` or `false` | `true` |
33 | | `byteSeq` | Endianness, enum of `BIG_ENDIAN`, `LITTLE_ENDIAN`, `BIG_ENDIAN_BYTE_SWAP`, `LITTLE_ENDIAN_BYTE_SWAP` | `BIG_ENDIAN` |
34 |
35 | Additionally, the octet-stream codec supports the data schema terms below for addressing bit-fields:
36 | | Term | Description | Default |
37 | | --- | --- | --- |
38 | | `ex:bitLength` | Number of bits produced during serialization or consumed during deserialization | |
39 | | `ex:bitOffset` | Offset in bits from the beginning of the byte sequence | `0` |
40 |
41 | With the help of the terms and parameters above, the octet-stream codec can be used to serialize and deserialize objects containing bit-fields and sequences of bytes, like in the following example.
42 |
43 | #### Example
44 |
45 | To serialize the object `{ flag1: true, numberProperty: 99, stringProperty: "Web" }` to a sequence of bytes, the content type `application/octet-stream;length=4;signed=false;`, along with the following data schema can be used:
46 |
47 | ```json
48 | {
49 | "type": "object",
50 | "properties": {
51 | "flag1": { "type": "boolean", "ex:bitOffset": 0, "ex:bitLength": 1 },
52 | "numberProperty": { "type": "integer", "ex:bitOffset": 1, "ex:bitLength": 7 },
53 | "stringProperty": { "type": "string", "ex:bitOffset": 8, "ex:bitLength": 24 }
54 | }
55 | }
56 | ```
57 |
58 | ## More Details
59 |
60 | See
61 |
--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/core",
3 | "version": "0.9.2",
4 | "description": "W3C Web of Things (WoT) Servient framework",
5 | "author": "Eclipse Thingweb (https://thingweb.io/)",
6 | "license": "EPL-2.0 OR W3C-20150513",
7 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/core",
8 | "publishConfig": {
9 | "access": "public"
10 | },
11 | "files": [
12 | "dist/",
13 | "src/"
14 | ],
15 | "main": "dist/core.js",
16 | "types": "dist/core.d.ts",
17 | "devDependencies": {
18 | "@types/content-type": "^1.1.8",
19 | "@types/debug": "^4.1.7",
20 | "@types/uritemplate": "^0.3.4",
21 | "@types/uuid": "^8.3.1",
22 | "wot-thing-description-types": "^1.1.0-12-March-2025"
23 | },
24 | "dependencies": {
25 | "@petamoriken/float16": "^3.1.1",
26 | "@thingweb/thing-model": "^1.0.4",
27 | "ajv": "^8.11.0",
28 | "ajv-formats": "^2.1.1",
29 | "cbor": "^8.1.0",
30 | "content-type": "^1.0.5",
31 | "debug": "^4.3.4",
32 | "is-absolute-url": "3.0.3",
33 | "rxjs": "^5.5.11",
34 | "uritemplate": "0.3.4",
35 | "url-toolkit": "2.1.6",
36 | "uuid": "^7.0.3",
37 | "web-streams-polyfill": "^4.0.0"
38 | },
39 | "scripts": {
40 | "build": "tsc -b",
41 | "lint": "eslint .",
42 | "lint:fix": "eslint . --fix",
43 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"**/*.json\"",
44 | "test": "mocha --require ts-node/register --extension ts"
45 | },
46 | "bugs": {
47 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
48 | },
49 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/core#readme",
50 | "directories": {
51 | "test": "test"
52 | },
53 | "keywords": [],
54 | "eslintConfig": {
55 | "extends": "../../.eslintrc.js"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/core/src/codecs/base64-codec.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ContentCodec } from "../content-serdes";
17 | import { DataSchema } from "wot-typescript-definitions";
18 |
19 | export default class Base64Codec implements ContentCodec {
20 | private subMediaType: string;
21 |
22 | constructor(subMediaType: string) {
23 | this.subMediaType = subMediaType;
24 | }
25 |
26 | getMediaType(): string {
27 | return this.subMediaType;
28 | }
29 |
30 | bytesToValue(bytes: Buffer, schema?: DataSchema, parameters?: { [key: string]: string }): string {
31 | const parsed = bytes.toString("ascii");
32 | return parsed;
33 | }
34 |
35 | valueToBytes(value: unknown, schema?: DataSchema, parameters?: { [key: string]: string }): Buffer {
36 | let body = "";
37 | if (value !== undefined) {
38 | body = JSON.stringify(value);
39 | }
40 | return Buffer.from(body, "base64");
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/core/src/codecs/cbor-codec.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ContentCodec } from "../content-serdes";
17 | import { DataSchema, DataSchemaValue } from "wot-typescript-definitions";
18 | import { createLoggers } from "../logger";
19 | import { decode, encode } from "cbor";
20 |
21 | const { debug } = createLoggers("core", "cbor-codec");
22 |
23 | // TODO: Add support for custom tag encoding/decoding
24 |
25 | /** Codec for CBOR de-/serialisation. */
26 | export default class CborCodec implements ContentCodec {
27 | private subMediaType: string;
28 |
29 | constructor(subMediaType?: string) {
30 | this.subMediaType = subMediaType ?? "application/cbor";
31 | }
32 |
33 | getMediaType(): string {
34 | return this.subMediaType;
35 | }
36 |
37 | bytesToValue(bytes: Buffer, schema?: DataSchema, parameters?: { [key: string]: string }): DataSchemaValue {
38 | debug(`CborCodec parsing '${bytes.toString()}'`);
39 |
40 | try {
41 | return decode(bytes);
42 | } catch (err) {
43 | if (bytes.byteLength === 0) {
44 | return null;
45 | }
46 |
47 | throw err;
48 | }
49 | }
50 |
51 | valueToBytes(value: unknown, schema?: DataSchema, parameters?: { [key: string]: string }): Buffer {
52 | debug("CborCodec serializing", value);
53 |
54 | if (value === undefined) {
55 | return Buffer.alloc(0);
56 | }
57 |
58 | return encode(value);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/packages/core/src/codecs/json-codec.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ContentSerdes, ContentCodec } from "../content-serdes";
17 | import { DataSchema, DataSchemaValue } from "wot-typescript-definitions";
18 | import { createLoggers } from "../logger";
19 |
20 | const { debug } = createLoggers("core", "json-codec");
21 |
22 | /** default implementation offering JSON de-/serialisation */
23 | export default class JsonCodec implements ContentCodec {
24 | private subMediaType: string;
25 |
26 | constructor(subMediaType?: string) {
27 | this.subMediaType = subMediaType ?? ContentSerdes.DEFAULT;
28 | }
29 |
30 | getMediaType(): string {
31 | return this.subMediaType;
32 | }
33 |
34 | bytesToValue(bytes: Buffer, schema?: DataSchema, parameters?: { [key: string]: string }): DataSchemaValue {
35 | debug(`JsonCodec parsing '${bytes.toString()}'`);
36 |
37 | let parsed;
38 | try {
39 | parsed = JSON.parse(bytes.toString());
40 | } catch (err) {
41 | if (err instanceof SyntaxError) {
42 | if (bytes.byteLength === 0) {
43 | // empty payload -> void/undefined
44 | parsed = undefined;
45 | } else {
46 | // be relaxed about what is received -> string without quotes
47 | parsed = bytes.toString();
48 | }
49 | } else {
50 | throw err;
51 | }
52 | }
53 |
54 | return parsed;
55 | }
56 |
57 | valueToBytes(value: unknown, schema?: DataSchema, parameters?: { [key: string]: string }): Buffer {
58 | debug("JsonCodec serializing", value);
59 | let body = "";
60 | if (value !== undefined) {
61 | body = JSON.stringify(value);
62 | }
63 | return Buffer.from(body);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/packages/core/src/content.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ContentSerdes } from "./content-serdes";
17 | import ProtocolHelpers from "./protocol-helpers";
18 |
19 | export class Content {
20 | type: string;
21 | body: NodeJS.ReadableStream;
22 |
23 | constructor(type: string, body: NodeJS.ReadableStream) {
24 | this.type = type;
25 | this.body = body;
26 | }
27 |
28 | toBuffer(): Promise {
29 | return ProtocolHelpers.readStreamFully(this.body);
30 | }
31 | }
32 |
33 | /**
34 | * Content object with the default content type (`application/json`).
35 | */
36 | export class DefaultContent extends Content {
37 | constructor(body: NodeJS.ReadableStream) {
38 | super(ContentSerdes.DEFAULT, body);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/core/src/core.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | /** Exports of this module */
17 |
18 | // Servient is also the default export
19 | import Servient from "./servient";
20 |
21 | export default Servient;
22 | export { Servient };
23 |
24 | // TD definitions
25 | export * from "./thing-description";
26 |
27 | // SerDes functionality
28 | export * from "./serdes";
29 |
30 | // ContentSerdes + built-in codecs
31 | export * from "./content-serdes";
32 | export { default as JsonCodec } from "./codecs/json-codec";
33 | export { default as CborCodec } from "./codecs/cbor-codec";
34 | export { default as TextCodec } from "./codecs/text-codec";
35 | export { default as Base64Codec } from "./codecs/base64-codec";
36 | export { default as NetconfOctetstreamCodecCodec } from "./codecs/octetstream-codec";
37 |
38 | // Protocols & Content
39 | export * from "./protocol-interfaces";
40 | export { PropertyContentMap, ContentListener } from "./protocol-interfaces";
41 | export { Content, DefaultContent } from "./content";
42 |
43 | // Scripting API objects
44 | export { default as ConsumedThing } from "./consumed-thing";
45 | export { default as ExposedThing } from "./exposed-thing";
46 |
47 | // Helper Implementations
48 | export { default as Helpers } from "./helpers";
49 | export { default as ProtocolHelpers } from "./protocol-helpers";
50 |
51 | // Logger Functions
52 | export { createLoggers, createDebugLogger, createErrorLogger, createInfoLogger, createWarnLogger } from "./logger";
53 |
--------------------------------------------------------------------------------
/packages/core/src/errors.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2021 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { DataSchemaValue } from "wot-typescript-definitions";
17 |
18 | export class NotReadableError extends Error {
19 | constructor(message: string) {
20 | super(message);
21 |
22 | // Set the prototype explicitly.
23 | // TS limitation see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
24 | Object.setPrototypeOf(this, NotReadableError.prototype);
25 | }
26 | }
27 |
28 | export class NotSupportedError extends Error {
29 | constructor(message: string) {
30 | super(message);
31 |
32 | // Set the prototype explicitly.
33 | // TS limitation see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
34 | Object.setPrototypeOf(this, NotSupportedError.prototype);
35 | }
36 | }
37 |
38 | export class DataSchemaError extends Error {
39 | value: DataSchemaValue;
40 | constructor(message: string, value: DataSchemaValue) {
41 | super(message);
42 | this.value = value;
43 | // Set the prototype explicitly.
44 | // TS limitation see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
45 | Object.setPrototypeOf(this, NotSupportedError.prototype);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/packages/core/src/validation.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ErrorObject } from "ajv";
17 | import Helpers from "./helpers";
18 |
19 | export function isThingDescription(input: unknown): input is WoT.ThingDescription {
20 | return Helpers.tsSchemaValidator(input);
21 | }
22 |
23 | export function getLastValidationErrors() {
24 | const errors = Helpers.tsSchemaValidator.errors?.map((o: ErrorObject) => o.message).join("\n");
25 | return new Error(errors);
26 | }
27 |
--------------------------------------------------------------------------------
/packages/core/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../.eslintrc.json",
3 | "rules": {
4 | "import/no-extraneous-dependencies": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/core/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": ".."
5 | },
6 | "include": ["*.ts", "**/*.ts", "../src/**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "resolveJsonModule": true,
5 | "outDir": "dist",
6 | "rootDir": "src"
7 | },
8 | "include": ["src/**/*"],
9 | "references": []
10 | }
11 |
--------------------------------------------------------------------------------
/packages/examples/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../.eslintrc.js"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/examples/README.md:
--------------------------------------------------------------------------------
1 | # node-wot Examples
2 |
3 | ## Script Examples
4 |
5 | Script examples are located in
6 |
7 | - `src\scripts`
8 | - `src\testthing`
9 |
10 | The idea of these folders is to use TypeScript to work on the examples which offers support in being up-to-date with the current API.
11 |
12 | see https://github.com/eclipse-thingweb/node-wot/issues/171.
13 |
14 | ### Workflow
15 |
16 | 1. Run `npm run build`
17 | 2. Remove the following 3/4 lines in JS files of folder `dist/`
18 |
19 | ```
20 | Object.defineProperty(exports, "__esModule", { value: true });
21 | require("wot-typescript-definitions");
22 | let WoT;
23 | let WoTHelpers;
24 | ```
25 |
26 | 3. Copy the according JS file(s) to
27 |
28 | - `/examples/scripts`
29 | - `/examples/testthing`
30 |
31 | ## Test Thing
32 |
33 | Test thing and client is located in `src\testthing`.
34 |
--------------------------------------------------------------------------------
/packages/examples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@node-wot/examples",
3 | "version": "0.9.2",
4 | "private": true,
5 | "description": "Examples for node-wot (not published)",
6 | "author": "Eclipse Thingweb (https://thingweb.io/)",
7 | "license": "EPL-2.0 OR W3C-20150513",
8 | "repository": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/examples",
9 | "dependencies": {
10 | "@node-wot/binding-coap": "0.9.2",
11 | "@node-wot/binding-http": "0.9.2",
12 | "@node-wot/binding-mqtt": "0.9.2",
13 | "@node-wot/binding-opcua": "0.9.2",
14 | "@node-wot/core": "0.9.2"
15 | },
16 | "scripts": {
17 | "build": "tsc -b",
18 | "lint": "eslint .",
19 | "lint:fix": "eslint . --fix",
20 | "format": "prettier --write \"src/**/*.ts\" \"**/*.json\""
21 | },
22 | "bugs": {
23 | "url": "https://github.com/eclipse-thingweb/node-wot/issues"
24 | },
25 | "homepage": "https://github.com/eclipse-thingweb/node-wot/tree/master/packages/examples#readme",
26 | "main": "index.js",
27 | "keywords": []
28 | }
29 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/coap/example-client.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { CoapClientFactory } from "@node-wot/binding-coap";
18 |
19 | // create Servient and add CoAP binding
20 | const servient = new Servient();
21 | servient.addClientFactory(new CoapClientFactory());
22 |
23 | servient
24 | .start()
25 | .then(async (WoT) => {
26 | try {
27 | const td = await WoT.requestThingDescription("coap://plugfest.thingweb.io:5683/testthing");
28 | const thing = await WoT.consume(td);
29 |
30 | // read property
31 | const read1 = await thing.readProperty("string");
32 | console.log("string value is: ", await read1.value());
33 | } catch (err) {
34 | console.error("Script error:", err);
35 | }
36 | })
37 | .catch((err) => {
38 | console.error("Start error:", err);
39 | });
40 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/coap/example-server.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { CoapServer } from "@node-wot/binding-coap";
18 |
19 | // create Servient add HTTP binding
20 | const servient = new Servient();
21 | servient.addServer(new CoapServer());
22 |
23 | servient.start().then((WoT) => {
24 | WoT.produce({
25 | title: "MyCounter",
26 | properties: {
27 | count: {
28 | type: "integer",
29 | },
30 | },
31 | }).then((thing) => {
32 | let count = 0;
33 |
34 | console.log("Produced " + thing.getThingDescription().title);
35 |
36 | // set property handlers (using async-await)
37 | thing.setPropertyReadHandler("count", async () => count);
38 | thing.setPropertyWriteHandler("count", async (intOutput) => {
39 | const value = await intOutput.value();
40 | if (typeof value === "number") {
41 | count = value;
42 | }
43 | });
44 |
45 | thing.expose().then(() => {
46 | console.info(thing.getThingDescription().title + " ready");
47 | console.info("TD : " + JSON.stringify(thing.getThingDescription()));
48 | });
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/http/example-client.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { HttpClientFactory } from "@node-wot/binding-http";
18 |
19 | // create Servient and add HTTP binding
20 | const servient = new Servient();
21 | servient.addClientFactory(new HttpClientFactory());
22 |
23 | servient
24 | .start()
25 | .then(async (WoT) => {
26 | try {
27 | const td = await WoT.requestThingDescription("http://plugfest.thingweb.io:8083/testthing");
28 | const thing = await WoT.consume(td);
29 |
30 | // read property
31 | const read1 = await thing.readProperty("string");
32 | console.log("string value is: ", await read1.value());
33 | } catch (err) {
34 | console.error("Script error:", err);
35 | }
36 | })
37 | .catch((err) => {
38 | console.error("Start error:", err);
39 | });
40 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/http/example-server-secure.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { HttpServer } from "@node-wot/binding-http";
18 |
19 | // create secure Servient with username & password credentials
20 | const servient = new Servient();
21 | servient.addCredentials({
22 | "urn:dev:wot:org:eclipse:thingweb:my-example-secure": {
23 | username: "node-wot",
24 | password: "hello",
25 | // token: "1/mZ1edKKACtPAb7zGlwSzvs72PvhAbGmB8K1ZrGxpcNM"
26 | },
27 | });
28 | const httpConfig = {
29 | allowSelfSigned: true, // client configuration
30 | serverKey: "privatekey.pem",
31 | serverCert: "certificate.pem",
32 | security: [
33 | {
34 | scheme: "basic", // (username & password)
35 | },
36 | ],
37 | };
38 | // add HTTPS binding with configuration
39 | servient.addServer(new HttpServer(httpConfig));
40 |
41 | servient.start().then((WoT) => {
42 | WoT.produce({
43 | title: "MyCounter",
44 | properties: {
45 | count: {
46 | type: "integer",
47 | },
48 | },
49 | }).then((thing) => {
50 | // init property value
51 | let count = 0;
52 |
53 | console.log("Produced " + thing.getThingDescription().title);
54 |
55 | // set property handlers (using async-await)
56 | thing.setPropertyReadHandler("count", async () => count);
57 | thing.setPropertyWriteHandler("count", async (intOutput) => {
58 | const value = await intOutput.value();
59 | if (typeof value === "number") {
60 | count = value;
61 | }
62 | });
63 |
64 | thing.expose().then(() => {
65 | console.info(thing.getThingDescription().title + " ready");
66 | console.info("TD : " + JSON.stringify(thing.getThingDescription()));
67 | });
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/http/example-server.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { HttpServer } from "@node-wot/binding-http";
18 |
19 | // create Servient add HTTP binding with port configuration
20 | const servient = new Servient();
21 | servient.addServer(
22 | new HttpServer({
23 | port: 8081, // (default 8080)
24 | urlRewrite: {
25 | "/myroot/foo/cnt": "/mycounter/properties/count",
26 | "/mysecondURL/for/the/same/resource": "/mycounter/properties/count",
27 | },
28 | })
29 | );
30 |
31 | servient.start().then((WoT) => {
32 | WoT.produce({
33 | title: "MyCounter",
34 | properties: {
35 | count: {
36 | type: "integer",
37 | },
38 | },
39 | }).then((thing) => {
40 | // init property value
41 | let count = 0;
42 |
43 | console.log("Produced " + thing.getThingDescription().title);
44 |
45 | // set property handlers (using async-await)
46 | thing.setPropertyReadHandler("count", async () => count);
47 | thing.setPropertyWriteHandler("count", async (intOutput) => {
48 | const value = await intOutput.value();
49 | if (typeof value === "number") {
50 | count = value;
51 | }
52 | });
53 |
54 | thing.expose().then(() => {
55 | console.info(thing.getThingDescription().title + " ready");
56 | console.info("TD : " + JSON.stringify(thing.getThingDescription()));
57 | });
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/opcua/demo-opcua-thing-description.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | const endpointUrl = "opc.tcp://opcuademo.sterfive.com:26543";
17 | export const thingDescription: WoT.ThingDescription = {
18 | "@context": "https://www.w3.org/2019/wot/td/v1",
19 | "@type": ["Thing"],
20 | securityDefinitions: {
21 | nosec_sc: {
22 | scheme: "nosec",
23 | },
24 | },
25 | security: "nosec_sc",
26 | title: "servient",
27 | description: "node-wot CLI Servient",
28 | properties: {
29 | pumpSpeed: {
30 | description: "the pump speed",
31 | observable: true,
32 | readOnly: true,
33 | unit: "m/s",
34 | type: "number",
35 | forms: [
36 | {
37 | href: endpointUrl + "?id=ns=1;s=PumpSpeed",
38 | op: ["readproperty", "observeproperty"],
39 | },
40 | ],
41 | },
42 | temperature: {
43 | description: "the temperature",
44 | observable: true,
45 | readOnly: true,
46 | unit: "m/s",
47 | type: "number",
48 | forms: [
49 | {
50 | href: endpointUrl + "?id=ns=1;s=Temperature",
51 | op: ["readproperty", "observeproperty"],
52 | },
53 | ],
54 | },
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/opcua/demo-opcua1.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { Servient } from "@node-wot/core";
17 | import { OPCUAClientFactory } from "@node-wot/binding-opcua";
18 |
19 | import { thingDescription } from "./demo-opcua-thing-description";
20 | (async () => {
21 | const servient = new Servient();
22 | servient.addClientFactory(new OPCUAClientFactory());
23 |
24 | const wot = await servient.start();
25 | const thing = await wot.consume(thingDescription);
26 |
27 | const content = await thing.readProperty("pumpSpeed");
28 | const pumpSpeed = await content.value();
29 |
30 | console.log("------------------------------");
31 | console.log("Pump Speed is : ", pumpSpeed, "m/s");
32 | console.log("------------------------------");
33 |
34 | await servient.shutdown();
35 | })();
36 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/opcua/demo-opcua2.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { Servient } from "@node-wot/core";
16 | import { OPCUAClientFactory } from "@node-wot/binding-opcua";
17 | import { thingDescription } from "./demo-opcua-thing-description";
18 |
19 | (async () => {
20 | const servient = new Servient();
21 | servient.addClientFactory(new OPCUAClientFactory());
22 |
23 | const wot = await servient.start();
24 | const thing = await wot.consume(thingDescription);
25 |
26 | thing.observeProperty("temperature", async (data) => {
27 | const temperature = await data.value();
28 | console.log("------------------------------");
29 | console.log("temperature : ", temperature, "m/s");
30 | console.log("------------------------------");
31 | });
32 |
33 | await new Promise((resolve) => setTimeout(resolve, 10000));
34 |
35 | await servient.shutdown();
36 | })();
37 |
--------------------------------------------------------------------------------
/packages/examples/src/bindings/opcua/opcua-coffee-machine-demo.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | import { Servient } from "@node-wot/core";
16 | import { OPCUAClientFactory } from "@node-wot/binding-opcua";
17 | import { thingDescription } from "./opcua-coffee-machine-thing-description";
18 |
19 | const pause = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
20 | (async () => {
21 | const servient = new Servient();
22 | servient.addClientFactory(new OPCUAClientFactory());
23 |
24 | const wot = await servient.start();
25 | const thing = await wot.consume(thingDescription);
26 |
27 | try {
28 | thing.observeProperty("waterTankLevel", async (data) => {
29 | const waterTankLevel = await data.value();
30 | console.log("------------------------------");
31 | console.log("tankLevel : ", waterTankLevel, "ml");
32 | console.log("------------------------------");
33 | });
34 | thing.observeProperty("coffeeBeanLevel", async (data) => {
35 | const coffeBeanLevel = await data.value();
36 | console.log("------------------------------");
37 | console.log("bean level : ", coffeBeanLevel, "g");
38 | console.log("------------------------------");
39 | });
40 | await thing.invokeAction("brewCoffee", { CoffeeType: 1 });
41 | await pause(5000);
42 | await thing.invokeAction("brewCoffee", { CoffeeType: 0 });
43 | await pause(5000);
44 |
45 | await thing.invokeAction("fillTank");
46 | await pause(5000);
47 | } finally {
48 | await servient.shutdown();
49 | }
50 | })();
51 |
--------------------------------------------------------------------------------
/packages/examples/src/quickstart/README.md:
--------------------------------------------------------------------------------
1 | # Quick Start Things
2 |
3 | This set of Things can be used to build mashup applications for a smart home scenario.
4 | These Things are:
5 |
6 | - Simple coffee machine that can take an order to brew a coffee.
7 | - Presence sensor that emits an event when a person is detected.
8 | - Smart clock that runs 60 times faster than real time, where 1 hour happens in 1 minute.
9 |
10 | These Things are hosted on plugfest.thingweb.io but can be also self-hosted.
11 |
--------------------------------------------------------------------------------
/packages/examples/src/quickstart/presence-sensor.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | // This is an example Thing script which is a simple presence detector
17 | // It fires an event when it detects a person (mocked as every 5 second)
18 |
19 | import { Servient } from "@node-wot/core";
20 | import { MqttBrokerServer } from "@node-wot/binding-mqtt";
21 |
22 | // create Servient add MQTT binding with port configuration
23 | const servient = new Servient();
24 | servient.addServer(new MqttBrokerServer({ uri: "mqtt://test.mosquitto.org" }));
25 |
26 | servient.start().then((WoT) => {
27 | WoT.produce({
28 | title: "PresenceSensor",
29 | description: "Thing that can detect presence of human nearby",
30 | support: "https://github.com/eclipse-thingweb/node-wot/",
31 | "@context": "https://www.w3.org/2022/wot/td/v1.1",
32 | events: {
33 | presenceDetected: {
34 | title: "Presence Detected",
35 | description:
36 | "An event that is emitted when a person is detected in the room. It is mocked and emitted every 5 seconds",
37 | data: {
38 | type: "number",
39 | title: "Distance",
40 | minimum: 55,
41 | maximum: 1200,
42 | },
43 | },
44 | },
45 | })
46 | .then((thing) => {
47 | console.log("Produced " + thing.getThingDescription().title);
48 |
49 | // expose the thing
50 | thing.expose().then(() => {
51 | console.info(thing.getThingDescription().title + " ready");
52 |
53 | // mocking the detection with an event sent every 5 seconds, with a random distance
54 | setInterval(() => {
55 | const distance: number = Math.random() * (1200 - 55) + 55;
56 | thing.emitEvent("presenceDetected", distance);
57 | console.info("Emitted presence with distance ", distance);
58 | }, 5000);
59 | });
60 | })
61 | .catch((e) => {
62 | console.log(e);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/packages/examples/src/scripts/counter-client.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2020 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | function getFormIndexForDecrementWithCoAP(thing: WoT.ConsumedThing): number {
17 | const forms = thing.getThingDescription().actions?.decrement.forms;
18 | if (forms !== undefined) {
19 | for (let i = 0; i < forms.length; i++) {
20 | if (/^coaps?:\/\/.*/.test(forms[i].href)) {
21 | return i;
22 | }
23 | }
24 | }
25 | // return formIndex: 0 if no CoAP target IRI found
26 | return 0;
27 | }
28 |
29 | WoT.requestThingDescription("coap://localhost:5683/counter")
30 | .then(async (td) => {
31 | try {
32 | const thing = await WoT.consume(td);
33 | console.info("=== TD ===");
34 | console.info(td);
35 | console.info("==========");
36 |
37 | // read property #1
38 | const read1 = await thing.readProperty("count");
39 | console.log("count value is", await read1.value());
40 |
41 | // increment property #1 (without step)
42 | await thing.invokeAction("increment");
43 | const inc1 = await thing.readProperty("count");
44 | console.info("count value after increment #1 is", await inc1.value());
45 |
46 | // increment property #2 (with step)
47 | await thing.invokeAction("increment", undefined, { uriVariables: { step: 3 } });
48 | const inc2 = await thing.readProperty("count");
49 | console.info("count value after increment #2 (with step 3) is", await inc2.value());
50 |
51 | // look for the first form for decrement with CoAP binding
52 | await thing.invokeAction("decrement", undefined, {
53 | formIndex: getFormIndexForDecrementWithCoAP(thing),
54 | });
55 | const dec1 = await thing.readProperty("count");
56 | console.info("count value after decrement is", await dec1.value());
57 | } catch (err) {
58 | console.error("Script error:", err);
59 | }
60 | })
61 | .catch((err) => {
62 | console.error("Fetch error:", err);
63 | });
64 |
--------------------------------------------------------------------------------
/packages/examples/src/security/certificate.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICDDCCAXUCFEcgrATArZXi0508eBk873JbhNT5MA0GCSqGSIb3DQEBCwUAMEUx
3 | CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
4 | cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwNTA3MTcwMzEwWhcNMjAwNjA2MTcw
5 | MzEwWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE
6 | CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GN
7 | ADCBiQKBgQDB4USEKBahhOhznS3oF4C1hGi7K4j2zpJIxIKxJD8zvlV+MazQOsCv
8 | 4FtudE9Lf9JV4Cni8Ci/bLgSENgkMOK6JJrvYSZBmcO/soDoz6szzIuLJbQoZvM6
9 | wRxwKwXYP77qK+zbYhdFTZiESO77RPvnnAxU7e4Ym2bZXjghqB0GDQIDAQABMA0G
10 | CSqGSIb3DQEBCwUAA4GBAJjPDHpmbfd4QMtARLyslQ8LpE+fk/OtF58eOFF/izko
11 | DWRf3dXGGNnhZOESMbRYSgygEZR0dhbaUSdiGMrj+MapOwsmoYnvz44bSeGOHAgq
12 | cutpTJ2oXeeiHsOo18/tNc5RgvRDJivlgrheaC4LSq4eb+hUFV0Zj6cR+GRauSsL
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/README.md:
--------------------------------------------------------------------------------
1 | # oAuth example
2 |
3 | The example is composed by two actors: one Thing that expose an action with oAuth2.0 client credential security constraint and a client who want to use that function. In the example, we are using an utility server to generate tokens and validate client credentials. Therefore, the **wot-consumer** force the action `href` to be the same as the utility server with the goal to validate the obtained oAuth2.0 token. In the feature the exposing servient could also play this role.
4 |
5 | ## run the example
6 |
7 | Set the current working directory to this folder. Then execute:
8 |
9 | ```bash
10 | npm install
11 | npm run build
12 | ```
13 |
14 | After this follow the procedure described in [here](../../README.md) and remove the unwanted line of codes inside the scripts `./dist/consumer.js` and `./dist/exposer.js`.
15 |
16 | Now you are ready to run the example.
17 |
18 | ```bash
19 | # start the server
20 | npm run server
21 | ```
22 |
23 | in a different terminal
24 |
25 | ```bash
26 | # start the exposer
27 | npm run start:exposer
28 | ```
29 |
30 | Finally, in other terminal
31 |
32 | ```bash
33 | npm run start:consumer
34 | ```
35 |
36 | you should see the following line at the end of consumer log:
37 |
38 | ```bash
39 | oAuth token was Ok!
40 | ```
41 |
42 | This confirms that the oAuth flow was completed successfully. Now you can have fun revoking the access to the consumer script. Go
43 | to `./exposer.ts` and try to remove the string `"user"` from the scopes. Run again the example and you will see that the action is not executed and an error is returned by the client.
44 |
45 | ## Where is a JS version?
46 |
47 | See [here](../../../examples/security/oauth)
48 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/consumer.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | WoT.requestThingDescription("https://localhost:8080/oauth").then((td) => {
17 | WoT.consume(td).then(async (thing) => {
18 | try {
19 | const resp = await thing.invokeAction("sayOk");
20 | const result = await resp?.value();
21 | console.log("oAuth token was", result);
22 | } catch (error) {
23 | console.log("It seems that I couldn't access the resource");
24 | }
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/exposer.ts:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 |
16 | import { ExposedThingInit } from "wot-typescript-definitions";
17 |
18 | const td: ExposedThingInit = {
19 | "@context": "https://www.w3.org/2019/wot/td/v1",
20 | title: "OAuth",
21 | id: "urn:dev:wot:oauth:test",
22 | securityDefinitions: {
23 | oauth2_sc: {
24 | scheme: "oauth2",
25 | flow: "client",
26 | token: "https://localhost:3000/token",
27 | scopes: ["user", "admin"],
28 | },
29 | },
30 | security: ["oauth2_sc"],
31 | actions: {
32 | sayOk: {
33 | description: "A simple action protected with oauth",
34 | idempotent: true,
35 | },
36 | },
37 | };
38 | try {
39 | WoT.produce(td).then((thing) => {
40 | thing.setActionHandler("sayOk", async () => "Ok!");
41 | thing.expose();
42 | });
43 | } catch (err) {
44 | console.error("Script error: " + err);
45 | }
46 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oauth-test",
3 | "version": "1.0.0",
4 | "description": "Simple project setup to test oauth functionalities",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "tsc -b",
8 | "server": "node server.js",
9 | "start:exposer": "node ../../../../cli/dist/cli.js -f ./wot-server-servient-conf.json ../../../dist/security/oauth/exposer.js",
10 | "start:consumer": "node ../../../../cli/dist/cli.js -f ./wot-client-servient-conf.json ../../../dist/security/oauth/consumer.js",
11 | "debug:consumer": "node --inspect-brk ../../../../cli/dist/cli.js -f ./wot-client-servient-conf.json ../../../dist/security/oauth/consumer.js"
12 | },
13 | "author": "Eclipse Thingweb (https://thingweb.io/)",
14 | "license": "EPL-2.0 OR W3C-20150513",
15 | "devDependencies": {
16 | "@node-oauth/express-oauth-server": "^3.0.0",
17 | "@types/node": "16.18.35",
18 | "cors": "^2.8.5",
19 | "ts-node": "10.9.1",
20 | "typescript": "4.7.4",
21 | "typescript-standard": "^0.3.36",
22 | "wot-typescript-definitions": "0.8.0-SNAPSHOT.30"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/server.js:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * This program and the accompanying materials are made available under the
8 | * terms of the Eclipse Public License v. 2.0 which is available at
9 | * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
10 | * Document License (2015-05-13) which is available at
11 | * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
12 | *
13 | * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
14 | ********************************************************************************/
15 | /**
16 | * A simple oAuth test server
17 | */
18 | const OAuthServer = require("@node-oauth/express-oauth-server");
19 | const bodyParser = require("body-parser");
20 | const cors = require("cors");
21 | const https = require("https");
22 | const fs = require("fs");
23 | const express = require("express");
24 | const Memory = require("./memory-model");
25 |
26 | var app = express();
27 | app.use(cors());
28 | app.options("*", cors());
29 |
30 | const model = new Memory();
31 |
32 | app.oauth = new OAuthServer({
33 | model: model,
34 | });
35 |
36 | app.use(bodyParser.json());
37 | app.use("/introspect", bodyParser.urlencoded({ extended: false }));
38 | app.use("/introspect", (req, res, next) => {
39 | if (req.method !== "POST" || !req.is("application/x-www-form-urlencoded")) {
40 | return res.status(400).end();
41 | }
42 |
43 | // rewrite body authenticate method is not compliant to https://tools.ietf.org/html/rfc7662
44 | const token = req.body.token;
45 | delete req.body.token;
46 | req.body.access_token = token;
47 | console.log("Body changed,");
48 | next();
49 | });
50 |
51 | app.use("/introspect", async (req, res, next) => {
52 | return app.oauth.authenticate()(req, res, next);
53 | });
54 | app.use("/introspect", (req, res) => {
55 | const token = res.locals.oauth.token;
56 | console.log("Token was", token ? "Ok" : "not Ok");
57 | res.json({
58 | active: !!token,
59 | scope: token.client.scopes.join(" "),
60 | client_id: token.client.clientId,
61 | }).end();
62 | });
63 |
64 | app.use("/token", bodyParser.urlencoded({ extended: false }));
65 | app.use("/token", app.oauth.token());
66 |
67 | app.use("/resource", (req, res) => {
68 | console.log("qui?");
69 | res.send("Ok!");
70 | });
71 |
72 | https
73 | .createServer(
74 | {
75 | key: fs.readFileSync("../privatekey.pem"),
76 | cert: fs.readFileSync("../certificate.pem"),
77 | },
78 | app
79 | )
80 | .listen(3000, "localhost", () => {
81 | console.log("listening");
82 | });
83 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "../../../dist"
4 | },
5 | "extends": "../../../tsconfig.json",
6 | "include": [],
7 | "files": ["consumer.ts", "exposer.ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/wot-client-servient-conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {
3 | "clientOnly": true
4 | },
5 | "http": {
6 | "allowSelfSigned": true
7 | },
8 | "credentials": {
9 | "urn:dev:wot:oauth:test": {
10 | "clientId": "node-wot",
11 | "clientSecret": "isgreat!"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/examples/src/security/oauth/wot-server-servient-conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "servient": {},
3 | "http": {
4 | "allowSelfSigned": true,
5 | "serverKey": "../privatekey.pem",
6 | "serverCert": "../certificate.pem",
7 | "security": [
8 | {
9 | "scheme": "oauth2",
10 | "method": {
11 | "name": "introspection_endpoint",
12 | "endpoint": "https://localhost:3000/introspect",
13 | "allowSelfSigned": true
14 | }
15 | }
16 | ]
17 | },
18 | "credentials": {
19 | "urn:dev:wot:oauth:test": {
20 | "clientId": "node-wot",
21 | "clientSecret": "isgreat!"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/examples/src/security/privatekey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXQIBAAKBgQDB4USEKBahhOhznS3oF4C1hGi7K4j2zpJIxIKxJD8zvlV+MazQ
3 | OsCv4FtudE9Lf9JV4Cni8Ci/bLgSENgkMOK6JJrvYSZBmcO/soDoz6szzIuLJbQo
4 | ZvM6wRxwKwXYP77qK+zbYhdFTZiESO77RPvnnAxU7e4Ym2bZXjghqB0GDQIDAQAB
5 | AoGBAIZCwXfjawifSXoGtuuqmu8Yqo4zL736f0L1EqwpNbtXa0zgiZQJm7Yv4CE1
6 | WlQmSDo/6cHGHfGyECYyk/s7/0VDdfS6jf5AMzpkCXP+32FZZegN7JxasgYsddZC
7 | LlpYhxjUd1vnYEIvvAefJ7N3Y0jdp1gR1Iri9+7vJjuFXJoBAkEA6foaD4sFDJhO
8 | /zYPPOJljtwtQz+ik4nXJCIvzLYAIKBcOgFirqLqcHfRnHh17DrumqVB3IhtjyoX
9 | XAQ0+uFZnQJBANQg/Xpijb5NuK43cg1q/MLyR8vdp1AxvmpS0YnsObxJAqp79oT/
10 | EEU+WXEJKmxBWtVbwryraAnUamyUtG3rqzECQQCqUGSR9dcKEQBH47j5z66va/QC
11 | pJqaHNcfNUdoEv9KwJABpSqJBovyrDVHWaQ0/bzbkvm7Jw/hC3mPgHx0Nn89AkBj
12 | E+2QhguSQRbrODZrEfdwzly+WY7WJAW9/2SjONRWnvtByZiA0ek1jkOUSiWoXnYg
13 | hTVVjfGP9cinYmVLmfFhAkA+L4iyT0uKjXoqugJU2wYDdLDNh3zPg4xu+Pg2Ua62
14 | SFr28bvOWI7g2DV6KX/gS1wKbSHbctUylJHQRxFaHSlX
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/packages/examples/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "module": "Node16",
6 | "rootDir": "src",
7 | "target": "ES2021",
8 | "sourceMap": false,
9 | "removeComments": false
10 | },
11 | "include": ["src/**/*"],
12 | "references": []
13 | }
14 |
--------------------------------------------------------------------------------
/tsconfig.eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["**/*.ts"],
4 | "compilerOptions": {
5 | "experimentalDecorators": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2021",
4 | "skipLibCheck": false,
5 | "module": "Node16",
6 | "moduleResolution": "Node16",
7 | "outDir": "dist",
8 | "strict": true,
9 | "composite": true,
10 | "incremental": true,
11 | "sourceMap": true,
12 | "noImplicitReturns": true,
13 | "removeComments": true,
14 | "noLib": false,
15 | "preserveConstEnums": true,
16 | "experimentalDecorators": true,
17 | "declaration": true,
18 | "esModuleInterop": true,
19 | "resolveJsonModule": false,
20 | "skipDefaultLibCheck": false,
21 | "allowJs": false,
22 | "strictNullChecks": true
23 | },
24 | "references": [
25 | { "path": "./packages/binding-coap" },
26 | { "path": "./packages/binding-file" },
27 | { "path": "./packages/binding-http" },
28 | { "path": "./packages/binding-mbus" },
29 | { "path": "./packages/binding-modbus" },
30 | { "path": "./packages/binding-mqtt" },
31 | { "path": "./packages/binding-netconf" },
32 | { "path": "./packages/binding-opcua" },
33 | { "path": "./packages/binding-websockets" },
34 | { "path": "./packages/cli" },
35 | { "path": "./packages/core" },
36 | { "path": "./packages/browser-bundle" },
37 | { "path": "./packages/examples" }
38 | ],
39 | "include": [
40 | /** specifically nothing here */
41 | ],
42 | "exclude": []
43 | }
44 |
--------------------------------------------------------------------------------
/utils/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["eslint:recommended", "standard", "prettier"],
3 | "env": {
4 | "es6": true,
5 | "node": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------