Skip to content

Commit

Permalink
Add initial tools utilities (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
justinfagnani committed May 4, 2023
1 parent bbcc72f commit ee2b94e
Show file tree
Hide file tree
Showing 15 changed files with 16,704 additions and 6 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Tests

on: [push, pull_request]

jobs:
tests:
runs-on: ubuntu-latest
env:
WIREIT_FAILURES: continue

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 18
cache: npm
cache-dependency-path: package-lock.json

- uses: google/wireit@setup-github-actions-caching/v1

- name: NPM install
run: npm ci

- name: Test
run: npm test
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ node_modules/
.wireit/
.eslintcache

packages/**/lib/
packages/**/tsconfig.tsbuildinfo
packages/*/lib/
packages/*/tsconfig.tsbuildinfo
86 changes: 85 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
],
"scripts": {
"build": "wireit",
"test": "wireit",
"format": "prettier \"./packages/*/src/**/*.ts\" --write",
"check": "wireit"
},
Expand All @@ -24,6 +25,11 @@
"./packages/validator:build"
]
},
"test": {
"dependencies": [
"./packages/tools:test"
]
},
"check": {
"dependencies": [
"check:lint",
Expand Down
4 changes: 3 additions & 1 deletion packages/tools/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/lib/
/test/
/test/*
!/test/test-data/

/index.js
/index.js.map
/index.d.ts
Expand Down
21 changes: 20 additions & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"type": "module",
"main": "index.js",
"scripts": {
"build": "wireit"
"build": "wireit",
"test": "wireit"
},
"wireit": {
"build": {
Expand All @@ -25,9 +26,27 @@
"index.d.ts.map",
"lib/",
"test/",
"!test/test-data/*",
"tsconfig.tsbuildinfo"
],
"clean": "if-file-deleted"
},
"test": {
"command": "NODE_OPTIONS='--enable-source-maps' uvu test \"_test\\.js$\"",
"dependencies": [
"build"
],
"files": [
"test/test-data/*"
],
"output": []
}
},
"dependencies": {
"custom-elements-manifest": "^2.0.0"
},
"devDependencies": {
"@types/node": "^18.16.3",
"uvu": "^0.5.6"
}
}
11 changes: 10 additions & 1 deletion packages/tools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
export {};
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

export * from './lib/get-custom-elements.js';
export * from './lib/resolve-reference.js';
export * from './lib/get-module.js';
export * from './lib/predicates.js';
68 changes: 68 additions & 0 deletions packages/tools/src/lib/get-custom-elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

import type {
CustomElementDeclaration,
CustomElementExport,
Module,
Package,
Reference,
} from 'custom-elements-manifest/schema.js';
import {isCustomElementDeclaration} from './predicates.js';
import {resolveReference} from './resolve-reference.js';

export type CustomElementInfo = {
package: Package;
module: Module;
export: CustomElementExport;
declaration: CustomElementDeclaration;
declarationReference: Reference;
};

/**
* Gets all the custom element exports of a package
*
* @param pkg The package to search
* @param packageName The name of the package
* @param packageVersion The version of the package
*/
export const getCustomElements = (
pkg: Package,
packageName: string,
packageVersion: string
): Array<CustomElementInfo> => {
const customElements: Array<CustomElementInfo> = [];
for (const mod of pkg.modules) {
if (mod.exports) {
for (const e of mod.exports) {
if (e.kind === 'custom-element-definition') {
// TODO (justinfagnani): for large manifests we want to index ahead
// of time to avoid polynomial lookups
const decl = resolveReference(
pkg,
mod,
e.declaration,
packageName,
packageVersion
);
if (decl !== undefined && isCustomElementDeclaration(decl)) {
customElements.push({
package: pkg,
module: mod,
export: e,
declaration: decl,
declarationReference: e.declaration,
});
} else {
// This is some kind of manifest error, should we warn?
// Or assume it was handled in a validation pass?
}
}
}
}
}
return customElements;
};
27 changes: 27 additions & 0 deletions packages/tools/src/lib/get-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

import type {Package} from 'custom-elements-manifest/schema.js';

/**
* Gets a module by path from a package.
*/
export const getModule = (pkg: Package, path: string) => {
path = normalizeModulePath(path);
for (const mod of pkg.modules) {
const modulePath = normalizeModulePath(mod.path);
if (modulePath === path) {
return mod;
}
}
return undefined;
};

/**
* Normalizes a module path by removing leading slashes.
*/
export const normalizeModulePath = (path: string) =>
path.startsWith('/') ? path.substring(1) : path;
42 changes: 42 additions & 0 deletions packages/tools/src/lib/predicates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

import type {
Declaration,
ClassDeclaration,
CustomElementDeclaration,
FunctionDeclaration,
CustomElement,
CustomElementMixinDeclaration,
} from 'custom-elements-manifest/schema.js';

export const isClassDeclaration = (d: Declaration): d is ClassDeclaration =>
d.kind === 'class';

export const isFunctionDeclaration = (
d: Declaration
): d is FunctionDeclaration => d.kind === 'function';

export const isMixinDeclaration = (d: Declaration): d is FunctionDeclaration =>
d.kind === 'mixin';

export const isVariableDeclaration = (
d: Declaration
): d is FunctionDeclaration => d.kind === 'variable';

export const isCustomElement = (
d: Declaration
): d is CustomElementDeclaration | CustomElementMixinDeclaration =>
(d as CustomElement).customElement === true;

export const isCustomElementDeclaration = (
d: Declaration
): d is CustomElementDeclaration => isClassDeclaration(d) && isCustomElement(d);

export const isCustomElementMixinDeclaration = (
d: Declaration
): d is CustomElementMixinDeclaration =>
isMixinDeclaration(d) && isCustomElement(d);
Loading

0 comments on commit ee2b94e

Please sign in to comment.