@matter/create
Advanced tools
Comparing version 0.11.0 to 0.11.1-alpha.0-20241031-2da1ad763
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
import { cp, mkdir, readFile, writeFile } from "fs/promises"; | ||
import { mkdir, readFile, writeFile } from "fs/promises"; | ||
import { basename, dirname } from "path"; | ||
@@ -13,2 +13,3 @@ async function before({ project }) { | ||
await mkdir(createPkg.resolve("dist/templates"), { recursive: true }); | ||
const matterJsVersion = `~${await readFile(project.pkg.workspace.resolve("version.txt"), "utf-8")}`; | ||
const readmes = await examplesPkg.glob("src/*/README.md"); | ||
@@ -22,2 +23,3 @@ const templates = Array(); | ||
} | ||
const dependencies = {}; | ||
const baseLength = examplesPkg.resolve(`src/${name}`).length + 1; | ||
@@ -31,3 +33,19 @@ const sources = await examplesPkg.glob(`src/${name}/**/*.ts`); | ||
} | ||
await cp(file, createPkg.resolve("dist/templates/", name, filename)); | ||
const source = await readFile(file, "utf-8"); | ||
for (const [, pkgName] of source.matchAll(/import .* from "(@[^/"]+\/[^/"]+|[^/"]+)[^"]*";/g)) { | ||
if (dependencies[pkgName]) { | ||
continue; | ||
} | ||
if (pkgName.startsWith("@matter/") || pkgName.startsWith("@project-chip/")) { | ||
dependencies[pkgName] = matterJsVersion; | ||
continue; | ||
} | ||
const version = examplesPkg.json.dependencies[pkgName]; | ||
if (version !== void 0) { | ||
dependencies[pkgName] = version; | ||
} | ||
} | ||
const outFilename = createPkg.resolve("dist/templates", name, filename); | ||
await mkdir(dirname(outFilename), { recursive: true }); | ||
await writeFile(outFilename, source); | ||
} | ||
@@ -39,2 +57,3 @@ if (!entrypoint) { | ||
name, | ||
dependencies, | ||
description: match[1], | ||
@@ -44,7 +63,8 @@ entrypoint | ||
} | ||
const matterJsVersion = `~${await readFile(project.pkg.workspace.resolve("version.txt"), "utf-8")}`; | ||
const typescriptVersion = project.pkg.findPackage("@matter/tools").json.dependencies.typescript; | ||
const tools = project.pkg.findPackage("@matter/tools").json; | ||
const typescriptVersion = tools.dependencies.typescript; | ||
const nodeTypesVersion = tools.devDependencies["@types/node"]; | ||
const config = { | ||
matterJsVersion, | ||
typescriptVersion, | ||
nodeTypesVersion, | ||
templates | ||
@@ -51,0 +71,0 @@ }; |
@@ -9,8 +9,10 @@ /** | ||
name: string; | ||
dependencies: Record<string, string>; | ||
description: string; | ||
entrypoint: string; | ||
matterJsPackages?: string[]; | ||
} | ||
export interface Config { | ||
matterJsVersion: string; | ||
typescriptVersion: string; | ||
nodeTypesVersion: string; | ||
templates: Template[]; | ||
@@ -17,0 +19,0 @@ } |
@@ -17,3 +17,9 @@ /** | ||
if (packageJson.version !== "0.0.0-git") { | ||
config.matterJsVersion = `^${packageJson.version}`; | ||
for (const template of config.templates) { | ||
for (const name in template.dependencies) { | ||
if (name.startsWith("@matter/") || name.startsWith("@project-chip/")) { | ||
template.dependencies[name] = packageJson.version; | ||
} | ||
} | ||
} | ||
} | ||
@@ -20,0 +26,0 @@ return config; |
@@ -11,7 +11,6 @@ /** | ||
const PACKAGE_JSON = { | ||
dependencies: { | ||
"@matter/main": "*" | ||
}, | ||
dependencies: {}, | ||
devDependencies: { | ||
typescript: "*" | ||
typescript: "*", | ||
"@types/node": "*" | ||
}, | ||
@@ -42,2 +41,24 @@ name: "matter-app", | ||
}; | ||
const VS_CODE_LAUNCH = { | ||
version: "0.2.0", | ||
configurations: [ | ||
{ | ||
type: "node", | ||
request: "launch", | ||
name: "Launch Program", | ||
skipFiles: ["<node_internals>/**"], | ||
program: "", | ||
// Never gotten it to work without this | ||
console: "integratedTerminal", | ||
// Doesn't seem to work | ||
//sourceMaps: true, | ||
env: { | ||
NODE_OPTIONS: "--enable-source-maps" | ||
}, | ||
preLaunchTask: "tsc: build - tsconfig.json", | ||
outFiles: ["${workspaceFolder}/dist/**/*.js"] | ||
} | ||
] | ||
}; | ||
const GITIGNORE = "node_modules/\ndist/\n"; | ||
class TemplateNotFoundError extends Error { | ||
@@ -74,11 +95,16 @@ } | ||
await createTsconfig(this); | ||
await createGitignore(this); | ||
await createVsCodeProject(this); | ||
await installSources(this); | ||
} | ||
function entrypointFor(project) { | ||
return "dist/" + project.template.entrypoint.replace(/\.ts$/, ".js"); | ||
} | ||
async function createPackageJson(project) { | ||
const pkg = PACKAGE_JSON; | ||
const config = await Config(); | ||
const entrypoint = `dist/${project.template.entrypoint.replace(/\.ts$/, ".js")}`; | ||
pkg.scripts.app = `node --enable-source-maps ${entrypoint}`; | ||
pkg.dependencies["@matter/main"] = config.matterJsVersion; | ||
pkg.scripts.app = `node --enable-source-maps ${entrypointFor(project)}`; | ||
pkg.dependencies = project.template.dependencies; | ||
pkg.devDependencies["typescript"] = config.typescriptVersion; | ||
pkg.devDependencies["@types/node"] = config.nodeTypesVersion; | ||
pkg.description = project.template.description; | ||
@@ -111,2 +137,11 @@ let author, authorEmail; | ||
} | ||
async function createGitignore(project) { | ||
await writeFile(resolve(project.dest, ".gitignore"), GITIGNORE); | ||
} | ||
async function createVsCodeProject(project) { | ||
const root = resolve(project.dest, ".vscode"); | ||
await mkdir(root); | ||
VS_CODE_LAUNCH.configurations[0].program = `\${workspaceFolder}/${entrypointFor(project)}`; | ||
await writeFile(resolve(root, "launch.json"), JSON.stringify(VS_CODE_LAUNCH, void 0, 4)); | ||
} | ||
async function installSources(project) { | ||
@@ -113,0 +148,0 @@ await cp(project.source, resolve(project.dest, "src"), { |
{ | ||
"matterJsVersion": "~0.11.0", | ||
"typescriptVersion": "~5.6.2", | ||
"nodeTypesVersion": "^22.8.1", | ||
"templates": [ | ||
{ | ||
"name": "controller-cli", | ||
"name": "controller", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763", | ||
"@matter/nodejs-ble": "~0.11.1-alpha.0-20241031-2da1ad763", | ||
"@project-chip/matter.js": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Controller example to commission and connect devices", | ||
@@ -11,8 +16,6 @@ "entrypoint": "ControllerNode.ts" | ||
{ | ||
"name": "device-onoff-advanced-cli", | ||
"description": "OnOff light/socket device with BLE support and advanced API usage", | ||
"entrypoint": "DeviceNodeFull.ts" | ||
}, | ||
{ | ||
"name": "device-onoff-bridge-cli", | ||
"name": "device-bridge-onoff", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Bridge for multiple OnOff light/sockets with a CLI command execution interface", | ||
@@ -22,8 +25,6 @@ "entrypoint": "BridgedDevicesNode.ts" | ||
{ | ||
"name": "device-onoff-cli", | ||
"description": "OnOff light/socket device with a CLI command execution interface", | ||
"entrypoint": "DeviceNode.ts" | ||
}, | ||
{ | ||
"name": "device-onoff-composed-cli", | ||
"name": "device-composed-onoff", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Composed device for multiple OnOff light/sockets with a CLI command execution interface", | ||
@@ -33,8 +34,22 @@ "entrypoint": "ComposedDeviceNode.ts" | ||
{ | ||
"name": "device-onoff-light", | ||
"description": "OnOff light example which logs the state changes to the console", | ||
"entrypoint": "LightDevice.ts" | ||
"name": "device-composed-wc-light", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Composed device with Window covering and a light endpoint that logs changes", | ||
"entrypoint": "IlluminatedRollerShade.ts" | ||
}, | ||
{ | ||
"name": "device-onoff-multiple-devices-cli", | ||
"name": "device-measuring-socket", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Socket device that reports random Energy and Power measurements", | ||
"entrypoint": "MeasuredSocketDevice.ts" | ||
}, | ||
{ | ||
"name": "device-multiple-onoff", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Multiple OnOff light/socket nodes in one process with a CLI command execution interface", | ||
@@ -44,13 +59,32 @@ "entrypoint": "MultiDeviceNode.ts" | ||
{ | ||
"name": "device-simple", | ||
"description": "A simple on/off device", | ||
"entrypoint": "main.ts" | ||
"name": "device-onoff", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "OnOff light/socket device with a CLI command execution interface", | ||
"entrypoint": "DeviceNode.ts" | ||
}, | ||
{ | ||
"name": "device-socket-with-measurement", | ||
"description": "Socket device that reports random Energy and Power measurements", | ||
"entrypoint": "MeasuredSocketDevice.ts" | ||
"name": "device-onoff-advanced", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763", | ||
"@matter/nodejs": "~0.11.1-alpha.0-20241031-2da1ad763", | ||
"@matter/nodejs-ble": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "OnOff light/socket device with BLE support and advanced API usage", | ||
"entrypoint": "DeviceNodeFull.ts" | ||
}, | ||
{ | ||
"name": "device-temperature-humidity-sensor-cli", | ||
"name": "device-onoff-light", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "OnOff light example which logs the state changes to the console", | ||
"entrypoint": "LightDevice.ts" | ||
}, | ||
{ | ||
"name": "device-sensor", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "Temperature/Humidity sensor with a CLI command interface to get the value", | ||
@@ -60,7 +94,10 @@ "entrypoint": "SensorDeviceNode.ts" | ||
{ | ||
"name": "device-window-covering-light-composed", | ||
"description": "Composed device with Window covering and a light endpoint that logs changes", | ||
"entrypoint": "IlluminatedRollerShade.ts" | ||
"name": "device-simple", | ||
"dependencies": { | ||
"@matter/main": "~0.11.1-alpha.0-20241031-2da1ad763" | ||
}, | ||
"description": "A simple on/off device", | ||
"entrypoint": "main.ts" | ||
} | ||
] | ||
} |
{ | ||
"name": "@matter/create", | ||
"version": "0.11.0", | ||
"version": "0.11.1-alpha.0-20241031-2da1ad763", | ||
"description": "Matter.js skeleton project generator", | ||
@@ -35,3 +35,3 @@ "type": "module", | ||
"devDependencies": { | ||
"@matter/tools": "0.11.0", | ||
"@matter/tools": "0.11.1-alpha.0-20241031-2da1ad763", | ||
"@types/node": "^22.8.1", | ||
@@ -38,0 +38,0 @@ "@types/tar-stream": "^3.1.3" |
@@ -8,3 +8,3 @@ /** | ||
import { Project } from "@matter/tools"; | ||
import { cp, mkdir, readFile, writeFile } from "fs/promises"; | ||
import { mkdir, readFile, writeFile } from "fs/promises"; | ||
import { basename, dirname } from "path"; | ||
@@ -22,2 +22,6 @@ import { Config, Template } from "./config.js"; | ||
// We set the version after build so we don't know actual version here. This placeholder is just used in dev. We | ||
// then replace with the "create" package version on init if it's not a git build | ||
const matterJsVersion = `~${await readFile(project.pkg.workspace.resolve("version.txt"), "utf-8")}`; | ||
const readmes = await examplesPkg.glob("src/*/README.md"); | ||
@@ -32,2 +36,4 @@ const templates = Array<Template>(); | ||
const dependencies = {} as Record<string, string>; | ||
const baseLength = examplesPkg.resolve(`src/${name}`).length + 1; | ||
@@ -41,3 +47,25 @@ const sources = await examplesPkg.glob(`src/${name}/**/*.ts`); | ||
} | ||
await cp(file, createPkg.resolve("dist/templates/", name, filename)); | ||
const source = await readFile(file, "utf-8"); | ||
// Quick hack to pull out imports, assumes modules formatted by prettier. More than sufficient for current | ||
// needs | ||
for (const [, pkgName] of source.matchAll(/import .* from "(@[^/"]+\/[^/"]+|[^/"]+)[^"]*";/g)) { | ||
if (dependencies[pkgName]) { | ||
continue; | ||
} | ||
if (pkgName.startsWith("@matter/") || pkgName.startsWith("@project-chip/")) { | ||
dependencies[pkgName] = matterJsVersion; | ||
continue; | ||
} | ||
const version = examplesPkg.json.dependencies[pkgName]; | ||
if (version !== undefined) { | ||
dependencies[pkgName] = version; | ||
} | ||
} | ||
const outFilename = createPkg.resolve("dist/templates", name, filename); | ||
await mkdir(dirname(outFilename), { recursive: true }); | ||
await writeFile(outFilename, source); | ||
} | ||
@@ -51,2 +79,3 @@ | ||
name, | ||
dependencies, | ||
description: match[1], | ||
@@ -57,11 +86,9 @@ entrypoint, | ||
// We set the version after build so we don't know actual version here. This placeholder is just used in dev. We | ||
// then replace with the "create" package version on init if it's not a git build | ||
const matterJsVersion = `~${await readFile(project.pkg.workspace.resolve("version.txt"), "utf-8")}`; | ||
const tools = project.pkg.findPackage("@matter/tools").json; | ||
const typescriptVersion = tools.dependencies.typescript; | ||
const nodeTypesVersion = tools.devDependencies["@types/node"]; | ||
const typescriptVersion = project.pkg.findPackage("@matter/tools").json.dependencies.typescript; | ||
const config: Config = { | ||
matterJsVersion, | ||
typescriptVersion, | ||
nodeTypesVersion, | ||
templates, | ||
@@ -68,0 +95,0 @@ }; |
@@ -15,9 +15,11 @@ /** | ||
name: string; | ||
dependencies: Record<string, string>; | ||
description: string; | ||
entrypoint: string; | ||
matterJsPackages?: string[]; | ||
} | ||
export interface Config { | ||
matterJsVersion: string; | ||
typescriptVersion: string; | ||
nodeTypesVersion: string; | ||
templates: Template[]; | ||
@@ -35,3 +37,9 @@ } | ||
if (packageJson.version !== "0.0.0-git") { | ||
config.matterJsVersion = `^${packageJson.version}`; | ||
for (const template of config.templates) { | ||
for (const name in template.dependencies) { | ||
if (name.startsWith("@matter/") || name.startsWith("@project-chip/")) { | ||
template.dependencies[name] = packageJson.version; | ||
} | ||
} | ||
} | ||
} | ||
@@ -38,0 +46,0 @@ |
@@ -13,7 +13,6 @@ /** | ||
const PACKAGE_JSON = { | ||
dependencies: { | ||
"@matter/main": "*", | ||
}, | ||
dependencies: {} as Record<string, string>, | ||
devDependencies: { | ||
typescript: "*", | ||
"@types/node": "*", | ||
}, | ||
@@ -46,2 +45,29 @@ name: "matter-app", | ||
const VS_CODE_LAUNCH = { | ||
version: "0.2.0", | ||
configurations: [ | ||
{ | ||
type: "node", | ||
request: "launch", | ||
name: "Launch Program", | ||
skipFiles: ["<node_internals>/**"], | ||
program: "", | ||
// Never gotten it to work without this | ||
console: "integratedTerminal", | ||
// Doesn't seem to work | ||
//sourceMaps: true, | ||
env: { | ||
NODE_OPTIONS: "--enable-source-maps", | ||
}, | ||
preLaunchTask: "tsc: build - tsconfig.json", | ||
outFiles: ["${workspaceFolder}/dist/**/*.js"], | ||
}, | ||
], | ||
}; | ||
const GITIGNORE = "node_modules/\ndist/\n"; | ||
export class TemplateNotFoundError extends Error {} | ||
@@ -92,5 +118,11 @@ | ||
await createTsconfig(this); | ||
await createGitignore(this); | ||
await createVsCodeProject(this); | ||
await installSources(this); | ||
} | ||
function entrypointFor(project: NewProject) { | ||
return "dist/" + project.template.entrypoint.replace(/\.ts$/, ".js"); | ||
} | ||
async function createPackageJson(project: NewProject) { | ||
@@ -101,7 +133,7 @@ const pkg = PACKAGE_JSON; | ||
const entrypoint = `dist/${project.template.entrypoint.replace(/\.ts$/, ".js")}`; | ||
pkg.scripts.app = `node --enable-source-maps ${entrypoint}`; | ||
pkg.scripts.app = `node --enable-source-maps ${entrypointFor(project)}`; | ||
pkg.dependencies["@matter/main"] = config.matterJsVersion; | ||
pkg.dependencies = project.template.dependencies; | ||
pkg.devDependencies["typescript"] = config.typescriptVersion; | ||
pkg.devDependencies["@types/node"] = config.nodeTypesVersion; | ||
@@ -142,2 +174,13 @@ (pkg as any).description = project.template.description; | ||
async function createGitignore(project: NewProject) { | ||
await writeFile(resolve(project.dest, ".gitignore"), GITIGNORE); | ||
} | ||
async function createVsCodeProject(project: NewProject) { | ||
const root = resolve(project.dest, ".vscode"); | ||
await mkdir(root); | ||
VS_CODE_LAUNCH.configurations[0].program = `\${workspaceFolder}/${entrypointFor(project)}`; | ||
await writeFile(resolve(root, "launch.json"), JSON.stringify(VS_CODE_LAUNCH, undefined, 4)); | ||
} | ||
async function installSources(project: NewProject) { | ||
@@ -144,0 +187,0 @@ await cp(project.source, resolve(project.dest, "src"), { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
174534
3519
2