@platformos/platformos-graph 0.0.19 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/bin/platformos-graph +21 -81
- package/dist/cli.d.ts +46 -0
- package/dist/cli.js +126 -0
- package/dist/cli.js.map +1 -0
- package/dist/graph/augment.js +0 -1
- package/dist/graph/augment.js.map +1 -1
- package/dist/graph/module.d.ts +16 -1
- package/dist/graph/module.js +39 -0
- package/dist/graph/module.js.map +1 -1
- package/dist/graph/test-helpers.d.ts +2 -3
- package/dist/graph/test-helpers.js +2 -6
- package/dist/graph/test-helpers.js.map +1 -1
- package/dist/graph/traverse.d.ts +31 -3
- package/dist/graph/traverse.js +146 -41
- package/dist/graph/traverse.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +14 -19
- package/dist/types.js.map +1 -1
- package/fixtures/background-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/background-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/background-edges/app/views/partials/jobs/notify.liquid +3 -0
- package/fixtures/function-edges/app/lib/queries/list.liquid +3 -0
- package/fixtures/function-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/function-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/graphql-edges/app/graphql/blog_posts/find.graphql +10 -0
- package/fixtures/graphql-edges/app/views/pages/broken.liquid +3 -0
- package/fixtures/graphql-edges/app/views/pages/index.liquid +3 -0
- package/fixtures/include-edges/app/views/pages/index.liquid +1 -0
- package/fixtures/include-edges/app/views/partials/shared/header.liquid +1 -0
- package/fixtures/module-edges/app/views/pages/index.liquid +4 -0
- package/fixtures/module-edges/modules/my_module/public/lib/queries/get.liquid +3 -0
- package/fixtures/module-edges/modules/my_module/public/views/partials/card.liquid +1 -0
- package/fixtures/skeleton/app/views/partials/child.liquid +2 -4
- package/fixtures/skeleton/app/views/partials/parent.liquid +2 -4
- package/fixtures/skeleton/assets/app.js +1 -7
- package/package.json +5 -5
- package/src/cli.spec.ts +265 -0
- package/src/cli.ts +151 -0
- package/src/graph/augment.ts +0 -2
- package/src/graph/build.spec.ts +19 -5
- package/src/graph/extract.spec.ts +155 -0
- package/src/graph/module.ts +40 -0
- package/src/graph/test-helpers.ts +2 -9
- package/src/graph/traverse-edges.spec.ts +278 -0
- package/src/graph/traverse.ts +177 -49
- package/src/index.ts +1 -1
- package/src/types.ts +16 -18
- package/bin/jsconfig.json +0 -18
- package/src/getWebComponentMap.ts +0 -81
package/src/types.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Dependencies as CheckDependencies,
|
|
5
5
|
UriString,
|
|
6
6
|
Reference,
|
|
7
|
+
ReferenceKind,
|
|
7
8
|
Location,
|
|
8
9
|
Range,
|
|
9
10
|
GraphQLSourceCode,
|
|
@@ -15,11 +16,6 @@ export interface IDependencies {
|
|
|
15
16
|
|
|
16
17
|
/** Optional perf improvement if you somehow have access to pre-computed source code info */
|
|
17
18
|
getSourceCode?: (uri: UriString) => Promise<FileSourceCode>;
|
|
18
|
-
|
|
19
|
-
/** A way to link <custom-element> to its window.customElements.define statement */
|
|
20
|
-
getWebComponentDefinitionReference: (
|
|
21
|
-
customElementName: string,
|
|
22
|
-
) => { assetName: string; range: Range } | undefined;
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
export type Dependencies = Required<IDependencies>;
|
|
@@ -32,7 +28,7 @@ export interface AppGraph {
|
|
|
32
28
|
modules: Record<UriString, AppModule>;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
export type AppModule = LiquidModule | AssetModule;
|
|
31
|
+
export type AppModule = LiquidModule | AssetModule | GraphQLModule;
|
|
36
32
|
|
|
37
33
|
export type FileSourceCode =
|
|
38
34
|
| LiquidSourceCode
|
|
@@ -47,10 +43,9 @@ export interface SerializableGraph {
|
|
|
47
43
|
edges: SerializableEdge[];
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
46
|
+
// Serialized edges are the modules' dependency `Reference`s verbatim, so they
|
|
47
|
+
// carry `type` and `kind` in addition to `source`/`target`.
|
|
48
|
+
export type SerializableEdge = Reference;
|
|
54
49
|
|
|
55
50
|
export type SerializableNode = Pick<AppModule, 'uri' | 'type' | 'kind' | 'exists'>;
|
|
56
51
|
|
|
@@ -62,6 +57,15 @@ export interface AssetModule extends IAppModule<ModuleType.Asset> {
|
|
|
62
57
|
kind: 'unused';
|
|
63
58
|
}
|
|
64
59
|
|
|
60
|
+
/**
|
|
61
|
+
* A `.graphql` operation file (referenced by `{% graphql op = 'name' %}`).
|
|
62
|
+
* A leaf node — GraphQL documents have no outgoing platformOS dependencies —
|
|
63
|
+
* so it is not traversed, only existence-checked (like {@link AssetModule}).
|
|
64
|
+
*/
|
|
65
|
+
export interface GraphQLModule extends IAppModule<ModuleType.GraphQL> {
|
|
66
|
+
kind: 'graphql';
|
|
67
|
+
}
|
|
68
|
+
|
|
65
69
|
export interface IAppModule<T extends ModuleType> {
|
|
66
70
|
/** Used as a discriminant in the AppModule union */
|
|
67
71
|
type: T;
|
|
@@ -94,6 +98,7 @@ export interface IAppModule<T extends ModuleType> {
|
|
|
94
98
|
export const enum ModuleType {
|
|
95
99
|
Liquid = 'Liquid',
|
|
96
100
|
Asset = 'Asset',
|
|
101
|
+
GraphQL = 'GraphQL',
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
export const enum LiquidModuleKind {
|
|
@@ -124,13 +129,6 @@ export interface AssetSourceCode {
|
|
|
124
129
|
ast: any | Error;
|
|
125
130
|
}
|
|
126
131
|
|
|
127
|
-
export { Reference, Range, Location };
|
|
132
|
+
export { Reference, ReferenceKind, Range, Location };
|
|
128
133
|
|
|
129
134
|
export type Void = void | Void[];
|
|
130
|
-
|
|
131
|
-
export type WebComponentMap = Map<WebComponentName, WebComponentDefinition>;
|
|
132
|
-
export type WebComponentName = string;
|
|
133
|
-
export type WebComponentDefinition = {
|
|
134
|
-
assetName: string; // Relative path to the asset file
|
|
135
|
-
range: [number, number]; // Start and end positions in the file
|
|
136
|
-
};
|
package/bin/jsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"checkJs": true,
|
|
6
|
-
"strict": true,
|
|
7
|
-
"baseUrl": ".",
|
|
8
|
-
"paths": {
|
|
9
|
-
"@platformos/platformos-graph": ["../src"],
|
|
10
|
-
"@platformos/platformos-check-common": ["../../platformos-check-common/src"]
|
|
11
|
-
},
|
|
12
|
-
"allowJs": true,
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
"esModuleInterop": true,
|
|
15
|
-
"skipLibCheck": true
|
|
16
|
-
},
|
|
17
|
-
"files": ["./platformos-graph"]
|
|
18
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { path, recursiveReadDirectory } from '@platformos/platformos-check-common';
|
|
2
|
-
import { ancestor as visit } from 'acorn-walk';
|
|
3
|
-
import { Dependencies, Void, WebComponentMap } from './types';
|
|
4
|
-
import { CallExpression } from 'acorn';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Regular expression for web component names
|
|
8
|
-
*
|
|
9
|
-
* Based on the HTML specification for valid custom element names.
|
|
10
|
-
*
|
|
11
|
-
* https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
|
12
|
-
*/
|
|
13
|
-
const wcre =
|
|
14
|
-
/^[a-z][-.\d_a-z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]*([-][-.\d_a-z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]*)$/u;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Find all the web component definitions from the JavaScript files in the
|
|
18
|
-
* assets directory.
|
|
19
|
-
*
|
|
20
|
-
* From those, we'll be able to map `<custom-element-name>` to the definition in
|
|
21
|
-
* the corresponding asset file.
|
|
22
|
-
*/
|
|
23
|
-
export async function getWebComponentMap(
|
|
24
|
-
rootUri: string,
|
|
25
|
-
{ fs, getSourceCode }: Pick<Dependencies, 'fs' | 'getSourceCode'>,
|
|
26
|
-
): Promise<WebComponentMap> {
|
|
27
|
-
const webComponentDefs: WebComponentMap = new Map();
|
|
28
|
-
const assetRoot = path.join(rootUri, 'assets');
|
|
29
|
-
const jsFiles = await recursiveReadDirectory(fs, assetRoot, ([fileName]) =>
|
|
30
|
-
fileName.endsWith('.js'),
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
await Promise.all(
|
|
34
|
-
jsFiles.map((uri) =>
|
|
35
|
-
findWebComponentReferences(uri, assetRoot, getSourceCode, webComponentDefs),
|
|
36
|
-
),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
return webComponentDefs;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function findWebComponentReferences(
|
|
43
|
-
uri: string,
|
|
44
|
-
assetRoot: string,
|
|
45
|
-
getSourceCode: Dependencies['getSourceCode'],
|
|
46
|
-
result: WebComponentMap,
|
|
47
|
-
): Promise<Void> {
|
|
48
|
-
const sourceCode = await getSourceCode(uri);
|
|
49
|
-
if (!uri.endsWith('.js')) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const ast = sourceCode.ast;
|
|
54
|
-
if (ast instanceof Error) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
for (const node of ast.body) {
|
|
59
|
-
visit(node, {
|
|
60
|
-
Literal(node, _state, ancestors) {
|
|
61
|
-
if (typeof node.value === 'string' && wcre.test(node.value)) {
|
|
62
|
-
// Making sure we're looking at customElements.define calls
|
|
63
|
-
const parentNode = ancestors.at(-2);
|
|
64
|
-
if (!parentNode) return;
|
|
65
|
-
if (parentNode.type !== 'CallExpression') return;
|
|
66
|
-
const callee = (parentNode as CallExpression).callee;
|
|
67
|
-
if (callee.type !== 'MemberExpression') return;
|
|
68
|
-
const property = callee.property;
|
|
69
|
-
if (property.type !== 'Identifier') return;
|
|
70
|
-
if (property.name !== 'define') return;
|
|
71
|
-
|
|
72
|
-
result.set(node.value, {
|
|
73
|
-
assetName: path.relative(uri, assetRoot),
|
|
74
|
-
range: [property.start, node.end],
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|