@oicl-lit/gen-wrapper-svelte 0.0.2

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/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @lit-labs/gen-wrapper-svelte
2
+
3
+ Utility library for generating Svelte wrappers for Lit components.
4
+
5
+ For a command-line interface to using the generator, see `@lit-labs/cli`.
package/index.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import * as path from 'path';
7
+ import { packageJsonTemplate } from './lib/package-json-template.js';
8
+ import { tsconfigTemplate } from './lib/tsconfig-template.js';
9
+ import { wrapperModuleTemplateSFC } from './lib/wrapper-module-template-sfc.js';
10
+ import { viteConfigTemplate } from './lib/vite.config-template.js';
11
+ import { svelteConfigTemplate } from './lib/svelteconf-template.js';
12
+ import { appHtmlTemplate } from './lib/app-html-template.js';
13
+ import { utilTemplate } from './lib/util-template.js';
14
+ export const getCommand = () => {
15
+ return {
16
+ name: 'svelte',
17
+ description: 'Generate Svelte wrapper components from Lit elements',
18
+ kind: 'resolved',
19
+ async generate(options) {
20
+ return generateSvelteWrapper(options.package);
21
+ },
22
+ };
23
+ };
24
+ export const generateSvelteWrapper = async (pkg) => {
25
+ const litModules = pkg.getLitElementModules();
26
+ if (litModules.length > 0) {
27
+ // Base the generated package folder name off the analyzed package folder
28
+ // name, not the npm package name, since that might have an npm org in it
29
+ const sveltePkgName = packageNameToSveltePackageName(path.basename(pkg.rootDir));
30
+ const sfcFiles = wrapperSFCFiles(pkg.packageJson, litModules);
31
+ const moduleNames = Object.keys(sfcFiles).map((f) => {
32
+ // Need to get module name to include sub path.
33
+ const dirname = path.dirname(f);
34
+ const basename = `${path.basename(f, '.vue')}`;
35
+ const moduleName = path
36
+ .join(dirname, basename)
37
+ .replace(/\\/g, '/')
38
+ .replace(/^src\//, '');
39
+ return moduleName;
40
+ });
41
+ return {
42
+ [sveltePkgName]: {
43
+ '.gitignore': gitIgnoreTemplate(moduleNames),
44
+ '.prettierignore': prettierIgnoreTemplate(),
45
+ 'package.json': packageJsonTemplate(pkg.packageJson),
46
+ 'tsconfig.json': tsconfigTemplate(),
47
+ 'vite.config.ts': viteConfigTemplate(pkg.packageJson),
48
+ 'svelte.config.js': svelteConfigTemplate(),
49
+ 'src/app.html': appHtmlTemplate(),
50
+ 'src/lib/util.ts': utilTemplate(),
51
+ ...sfcFiles,
52
+ },
53
+ };
54
+ }
55
+ else {
56
+ throw new Error('No Lit components were found in this package.');
57
+ }
58
+ };
59
+ // TODO(kschaaf): Should this be configurable?
60
+ const packageNameToSveltePackageName = (pkgName) => `${pkgName}-svelte`;
61
+ const gitIgnoreTemplate = (moduleNames) => moduleNames.map((f) => `/${f}.*`).join('\n');
62
+ const prettierIgnoreTemplate = () => ['.svelte-kit/', 'dist/', 'node_modules/'].join('\n');
63
+ const getSvelteFileName = (dir, name) => {
64
+ const dirname = dir.replace(/^src/g, 'src/lib');
65
+ return path.join(dirname, `${name}.svelte`);
66
+ };
67
+ const wrapperSFCFiles = (packageJson, litModules) => {
68
+ const wrapperFiles = {};
69
+ const globalExports = [];
70
+ for (const { module, declarations } of litModules) {
71
+ const { sourcePath, jsPath } = module;
72
+ // Format: [...[name, content]]
73
+ const wrappers = wrapperModuleTemplateSFC(packageJson, jsPath, declarations);
74
+ const dir = path.dirname(sourcePath);
75
+ const exports = [];
76
+ // TODO(sorvell): Throw if component names are re-used in the same folder.
77
+ for (const [name, content] of wrappers) {
78
+ exports.push(`export {default as ${name}} from './${name}.svelte';`);
79
+ wrapperFiles[getSvelteFileName(dir, name)] = content;
80
+ const dirname = dir.replace(/^src/g, '');
81
+ globalExports.push(`export {default as ${name}} from '.${dirname}/${name}.svelte';`);
82
+ }
83
+ // Note, if a given source module includes more than component, the author
84
+ // probably intended to make them available via a single import and this
85
+ // separate module preserves that intent.
86
+ if (wrappers.length > 1) {
87
+ wrapperFiles[sourcePath] = exports.join('/n');
88
+ }
89
+ }
90
+ wrapperFiles['src/lib/index.ts'] = globalExports.join('\n');
91
+ return wrapperFiles;
92
+ };
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,18 @@
1
+ import { html } from '@oicl-lit/gen-utils/lib/str-utils.js';
2
+ export const appHtmlTemplate = () => {
3
+ return html `
4
+ <!doctype html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="utf-8" />
8
+ <link rel="icon" href="%sveltekit.assets%/favicon.svg" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
10
+ %sveltekit.head%
11
+ </head>
12
+ <body data-sveltekit-preload-data="hover">
13
+ <div style="display: contents">%sveltekit.body%</div>
14
+ </body>
15
+ </html>
16
+ `;
17
+ };
18
+ //# sourceMappingURL=app-html-template.js.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export const packageJsonTemplate = (pkgJson) => {
7
+ // Refinement of package.json generation ala the TODOs below tracked in
8
+ // https://github.com/lit/lit/issues/2855
9
+ // TODO(kschaaf): spread in/adapt other relevant fields from source
10
+ // package.json (description, license, keywords, etc.)
11
+ return JSON.stringify({
12
+ name: `${pkgJson.name}-svelte`,
13
+ version: pkgJson.version,
14
+ scripts: {
15
+ dev: 'vite dev',
16
+ build: 'vite build && npm run prepack',
17
+ preview: 'vite preview',
18
+ prepare: "svelte-kit sync || echo ''",
19
+ prepack: 'svelte-kit sync && svelte-package && publint',
20
+ check: 'svelte-kit sync && svelte-check --tsconfig ./tsconfig.json',
21
+ 'check:watch': 'svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch',
22
+ format: 'prettier "**/*.{cjs,html,js,json,md,ts,css,svelte}" --write',
23
+ 'format:check': 'prettier "**/*.{cjs,html,js,json,md,ts,css,svelte}" --check',
24
+ },
25
+ files: ['dist', '!dist/**/*.test.*', '!dist/**/*.spec.*'],
26
+ sideEffects: ['**/*.css'],
27
+ svelte: './dist/index.js',
28
+ types: './dist/index.d.ts',
29
+ type: 'module',
30
+ exports: {
31
+ '.': {
32
+ types: './dist/index.d.ts',
33
+ svelte: './dist/index.js',
34
+ },
35
+ },
36
+ dependencies: {
37
+ [pkgJson.name]: '^' + pkgJson.version,
38
+ },
39
+ peerDependencies: {
40
+ svelte: '^5.0.0',
41
+ },
42
+ devDependencies: {
43
+ '@sveltejs/adapter-auto': '^7.0.0',
44
+ '@sveltejs/kit': '^2.48.5',
45
+ '@sveltejs/package': '^2.5.6',
46
+ '@sveltejs/vite-plugin-svelte': '^6.2.1',
47
+ prettier: '^3.8.1',
48
+ 'prettier-plugin-svelte': '^3.5.0',
49
+ publint: '^0.3.15',
50
+ svelte: '^5.43.8',
51
+ 'svelte-check': '^4.3.4',
52
+ typescript: '^5.9.3',
53
+ vite: '^7.2.2',
54
+ },
55
+ prettier: {
56
+ plugins: ['prettier-plugin-svelte'],
57
+ },
58
+ keywords: ['svelte'],
59
+ }, null, 2);
60
+ };
61
+ //# sourceMappingURL=package-json-template.js.map
@@ -0,0 +1,24 @@
1
+ import { javascript } from '@oicl-lit/gen-utils/lib/str-utils.js';
2
+ export const svelteConfigTemplate = () => {
3
+ return javascript `
4
+ import adapter from '@sveltejs/adapter-auto';
5
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
6
+
7
+ /** @type {import('@sveltejs/kit').Config} */
8
+ const config = {
9
+ // Consult https://svelte.dev/docs/kit/integrations
10
+ // for more information about preprocessors
11
+ preprocess: vitePreprocess(),
12
+
13
+ kit: {
14
+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
15
+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
16
+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
17
+ adapter: adapter()
18
+ }
19
+ };
20
+
21
+ export default config;
22
+ `;
23
+ };
24
+ //# sourceMappingURL=svelteconf-template.js.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ export const tsconfigTemplate = () => {
7
+ return JSON.stringify({
8
+ extends: './.svelte-kit/tsconfig.json',
9
+ compilerOptions: {
10
+ rewriteRelativeImportExtensions: true,
11
+ allowJs: true,
12
+ checkJs: true,
13
+ forceConsistentCasingInFileNames: true,
14
+ resolveJsonModule: true,
15
+ skipLibCheck: true,
16
+ sourceMap: true,
17
+ strict: true,
18
+ module: 'NodeNext',
19
+ moduleResolution: 'NodeNext',
20
+ },
21
+ }, null, 2);
22
+ };
23
+ //# sourceMappingURL=tsconfig-template.js.map
@@ -0,0 +1,32 @@
1
+ import { javascript } from '@oicl-lit/gen-utils/lib/str-utils.js';
2
+ export const utilTemplate = () => javascript `
3
+
4
+ const ignoreProps = ["class", "style", "$$slots", "children"];
5
+
6
+ function updateProperty(node: HTMLElement, props: Record<string, unknown>) {
7
+ Object.entries(props)
8
+ .filter(([key]) => !ignoreProps.includes(key))
9
+ .forEach(([key, value]) => {
10
+ try {
11
+ // @ts-expect-error - prop matches the key of the node
12
+ node[key] = value;
13
+ } catch (error) {
14
+ console.warn(\`Error setting property \${key} on node: \${error}\`);
15
+ }
16
+ });
17
+ }
18
+
19
+ export function setProperties(
20
+ node: HTMLElement,
21
+ props: Record<string, unknown>
22
+ ) {
23
+ updateProperty(node, props);
24
+ return {
25
+ update(props: Record<string, unknown>) {
26
+ updateProperty(node, props);
27
+ },
28
+ };
29
+ }
30
+
31
+ `;
32
+ //# sourceMappingURL=util-template.js.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { javascript } from '@oicl-lit/gen-utils/lib/str-utils.js';
7
+ /**
8
+ * Generates a Vite config.
9
+ *
10
+ * Note, ideally we would be using Vite library mode instead of configuring
11
+ * the `rollupOptions` manually. However, Vite supports only a single entry
12
+ * file in that case, and this generator supports multiple modules.
13
+ *
14
+ * See https://github.com/vitejs/vite/discussions/1736.
15
+ *
16
+ */
17
+ export const viteConfigTemplate = (_pkgJson) => javascript `
18
+ import { sveltekit } from '@sveltejs/kit/vite';
19
+ import { defineConfig } from 'vite';
20
+
21
+ export default defineConfig({
22
+ plugins: [sveltekit()]
23
+ });
24
+ `;
25
+ //# sourceMappingURL=vite.config-template.js.map
@@ -0,0 +1,239 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ import { getImportsStringForReferences, } from '@oicl-lit/analyzer';
7
+ import { javascript, kabobToOnEvent } from '@oicl-lit/gen-utils/lib/str-utils.js';
8
+ const nameToSvelteName = (name) => {
9
+ return name
10
+ .replace(/_[a-z]/g, (match) => match.toUpperCase()[1])
11
+ .replace(/æ/g, 'ae')
12
+ .replace(/ø/g, 'oe')
13
+ .replace(/å/g, 'aa')
14
+ .replace(/Æ/g, 'Ae')
15
+ .replace(/Ø/g, 'Oe')
16
+ .replace(/Å/g, 'Aa');
17
+ };
18
+ const isValidSvelteName = (name) => {
19
+ return !/[_æøåÆØÅ]/.test(name);
20
+ };
21
+ /**
22
+ * Generates a Svelte wrapper component as a Svelte single file component. This
23
+ * approach relies on the Svelte compiler to generate a JavaScript property types
24
+ * object for Svelte runtime type checking from the Typescript property types.
25
+ */
26
+ export const wrapperModuleTemplateSFC = (packageJson, moduleJsPath, elements) => {
27
+ moduleJsPath = moduleJsPath.replace(/\\/g, '/');
28
+ const wcPath = `${packageJson.name}/${moduleJsPath}`;
29
+ return elements
30
+ .filter((element) => isValidSvelteName(element.name))
31
+ .map((element) => {
32
+ return [
33
+ nameToSvelteName(element.name),
34
+ wrapperTemplate(element, wcPath),
35
+ ];
36
+ });
37
+ };
38
+ const defaultEventType = `CustomEvent<unknown>`;
39
+ const getEventInfo = (event) => {
40
+ const { name, type: modelType } = event;
41
+ const onName = kabobToOnEvent(name);
42
+ const type = modelType?.text ?? defaultEventType;
43
+ return { onName, type };
44
+ };
45
+ const renderPropsInterface = (props) => `export interface Props {
46
+ class?: string;
47
+ style?: string;
48
+ ${Array.from(props.values())
49
+ .map((prop) => {
50
+ // @ts-expect-error - jsDoc is not typed
51
+ const comment = prop.node.jsDoc?.map((doc) => doc.comment).join(' ');
52
+ const description = comment ? ` /** ${comment} */\n` : '';
53
+ return `${description}${prop.name}?: ${prop.type?.text || 'any'}`;
54
+ })
55
+ .join(';\n ')}
56
+ }`;
57
+ const renderEventsInterface = (events) => `export interface Events {
58
+ ${Array.from(events.values())
59
+ .map((event) => {
60
+ const { type } = getEventInfo(event);
61
+ return `${kabobToOnEvent(event.name)}?: (event: ${type}) => void`;
62
+ })
63
+ .join(';\n ')}
64
+ }`;
65
+ export const renderEventsMapper = (events) => {
66
+ return Array.from(events.values())
67
+ .map((event) => {
68
+ const { name } = event;
69
+ return `on${name}={${kabobToOnEvent(name)}}`;
70
+ })
71
+ .join('\n ');
72
+ };
73
+ export const renderPropsMapper = (props) => {
74
+ return ('class={props.class}\n style={props.style}\n ' +
75
+ Array.from(props.values())
76
+ .map((prop) => {
77
+ const { name } = prop;
78
+ let defaultValue = '';
79
+ if (prop.default !== undefined) {
80
+ defaultValue = ` ?? ${prop.default}`;
81
+ }
82
+ return `${name}={props.${name}${defaultValue}}`;
83
+ })
84
+ .join('\n '));
85
+ };
86
+ const getTypeReferencesForMap = (map) => Array.from(map.values()).flatMap((e) => e.type?.references ?? []);
87
+ const getElementTypeImports = (declaration) => {
88
+ const { events, reactiveProperties } = declaration;
89
+ const refs = [
90
+ ...getTypeReferencesForMap(events),
91
+ ...getTypeReferencesForMap(reactiveProperties),
92
+ ];
93
+ return getImportsStringForReferences(refs).replace(/(?:^import)/gm, 'import type');
94
+ };
95
+ // TODO(sorvell): add support for getting exports in analyzer.
96
+ const getElementTypeExportsFromImports = (imports) => imports.replace(/(?:^import)/gm, 'export');
97
+ const slotNameToPropName = (name) => {
98
+ // Normalize and map slot names to safe Svelte identifiers
99
+ // Rules:
100
+ // - default/children/"-" map to `children`
101
+ // - Convert sequences of non-alphanumeric chars into camelCase
102
+ // - Remove remaining non-alphanumerics
103
+ const trimmed = name.trim();
104
+ if (/^-+$/.test(trimmed))
105
+ return 'children';
106
+ if (/^(default|children)$/i.test(trimmed))
107
+ return 'children';
108
+ // If the name contains a placeholder like <id>, we clean it up but keep the rest
109
+ // to form a property name for the parameterized snippet.
110
+ // e.g. tab-<id>-icon -> tabIcon
111
+ const cleanName = trimmed.replace(/<[^>]+>/g, '');
112
+ // Build camelCase tokenizing on any non-alphanumeric sequence
113
+ return cleanName
114
+ .split(/[^a-zA-Z0-9]+/)
115
+ .filter((t) => t.length > 0)
116
+ .map((t, i) => (i === 0 ? t : t[0].toUpperCase() + t.slice(1)))
117
+ .join('');
118
+ };
119
+ const createNamingPlan = (slots, props) => {
120
+ const propNames = new Set(Array.from(props.values()).map((prop) => prop.name));
121
+ const snippetNamesBySlotName = new Map();
122
+ const collidingPropNames = new Set();
123
+ for (const slot of slots.values()) {
124
+ const isDefault = slot.name === 'default' || slot.name === '' || slot.name === '-';
125
+ const snippetName = isDefault ? 'children' : slotNameToPropName(slot.name);
126
+ snippetNamesBySlotName.set(slot.name, snippetName);
127
+ if (propNames.has(snippetName)) {
128
+ collidingPropNames.add(snippetName);
129
+ }
130
+ }
131
+ for (const [slotName, snippetName] of snippetNamesBySlotName) {
132
+ if (collidingPropNames.has(snippetName)) {
133
+ snippetNamesBySlotName.set(slotName, `${snippetName}Snippet`);
134
+ }
135
+ }
136
+ return {
137
+ snippetNamesBySlotName,
138
+ };
139
+ };
140
+ const renderSlotsInterface = (slots, namingPlan) => {
141
+ const items = Array.from(slots.values()).map((slot) => {
142
+ const propName = namingPlan.snippetNamesBySlotName.get(slot.name) ?? 'children';
143
+ const isDynamic = slot.name.includes('<');
144
+ return `${propName}?: Snippet${isDynamic ? '<[any]>' : ''}`;
145
+ });
146
+ // Always support a default snippet even if analyzer didn't declare slots
147
+ if (items.length === 0) {
148
+ items.push('children?: Snippet');
149
+ }
150
+ return `export interface Slots {\n ${items.join(';\n ')}\n}`;
151
+ };
152
+ const renderSlotsDestructureList = (slots, namingPlan) => {
153
+ const names = Array.from(slots.values()).map((slot) => namingPlan.snippetNamesBySlotName.get(slot.name) ?? 'children');
154
+ if (names.length === 0) {
155
+ names.push('children');
156
+ }
157
+ return names.join(', ');
158
+ };
159
+ const renderSnippets = (slots, props, namingPlan) => {
160
+ const parts = Array.from(slots.values()).map((slot) => {
161
+ const isDefault = slot.name === 'default' || slot.name === '' || slot.name === '-';
162
+ if (isDefault) {
163
+ return javascript `
164
+ {#if children}
165
+ {@render children()}
166
+ {/if}`;
167
+ }
168
+ const propName = namingPlan.snippetNamesBySlotName.get(slot.name) ?? 'children';
169
+ const placeholderMatch = slot.name.match(/<([^>]+)>/);
170
+ if (placeholderMatch) {
171
+ const placeholder = placeholderMatch[1];
172
+ // Try to find a property that is likely the collection for this slot.
173
+ // Heuristic: property name starts with the prefix of the slot name.
174
+ const prefix = slot.name.split('<')[0].replace(/-$/, '');
175
+ const collectionProp = Array.from(props.values()).find((p) => p.name === prefix ||
176
+ p.name === prefix + 's' ||
177
+ p.name === prefix + 'es');
178
+ if (collectionProp) {
179
+ const collectionName = collectionProp.name;
180
+ return javascript `
181
+ {#if ${collectionName} && ${propName}}
182
+ {#each ${collectionName} as item}
183
+ <div slot="${slot.name.replace(`<${placeholder}>`, `{item.${placeholder}}`)}">
184
+ {@render ${propName}(item)}
185
+ </div>
186
+ {/each}
187
+ {/if}`;
188
+ }
189
+ }
190
+ // Use div with slot attribute and display: contents so content projects into named slot of the web component
191
+ return javascript `
192
+ {#if ${propName}}
193
+ <div slot="${slot.name}">
194
+ {@render ${propName}()}
195
+ </div>
196
+ {/if}`;
197
+ });
198
+ if (parts.length === 0) {
199
+ parts.push(javascript `
200
+ {#if children}
201
+ {@render children()}
202
+ {/if}`);
203
+ }
204
+ return parts.join('\n');
205
+ };
206
+ const renderEventsProps = (events) => {
207
+ const eventsProps = Array.from(events.keys())
208
+ .map((event) => kabobToOnEvent(event))
209
+ .join(', ');
210
+ return eventsProps ? `${eventsProps},` : '';
211
+ };
212
+ const wrapperTemplate = (declaration, wcPath) => {
213
+ const { tagname, events, reactiveProperties, slots } = declaration;
214
+ const namingPlan = createNamingPlan(slots, reactiveProperties);
215
+ const typeImports = getElementTypeImports(declaration);
216
+ const typeExports = getElementTypeExportsFromImports(typeImports);
217
+ return javascript `
218
+ <script lang="ts">
219
+ ${typeExports ?? ''}
220
+ import '${wcPath}';
221
+ import { setProperties } from "$lib/util.js";
222
+ ${typeImports}
223
+ import type { Snippet } from 'svelte';
224
+
225
+ ${renderPropsInterface(reactiveProperties)}
226
+ ${renderEventsInterface(events)}
227
+ ${renderSlotsInterface(slots, namingPlan)}
228
+ const {${renderEventsProps(events)} class: className, style, ${renderSlotsDestructureList(slots, namingPlan)}, ...props} = $props<Props & Events & Slots>();
229
+
230
+ </script>
231
+ <${tagname}
232
+ use:setProperties={props}
233
+ class={className}
234
+ style={style}
235
+ ${renderEventsMapper(events)} >
236
+ ${renderSnippets(slots, reactiveProperties, namingPlan)}
237
+ </${tagname}>`;
238
+ };
239
+ //# sourceMappingURL=wrapper-module-template-sfc.js.map
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@oicl-lit/gen-wrapper-svelte",
3
+ "description": "Code generator for Svelte wrapper for Lit components",
4
+ "version": "0.0.2",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "author": "Google LLC",
9
+ "license": "BSD-3-Clause",
10
+ "bugs": "https://github.com/lit/lit/issues",
11
+ "type": "module",
12
+ "main": "lib/index.js",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/lit/lit.git",
16
+ "directory": "packages/labs/gen-wrapper-svelte"
17
+ },
18
+ "scripts": {
19
+ "build": "wireit",
20
+ "test": "wireit",
21
+ "test:gen": "wireit",
22
+ "test:update-goldens": "UPDATE_TEST_GOLDENS=true npm run test:gen"
23
+ },
24
+ "wireit": {
25
+ "build": {
26
+ "command": "tsc --build --pretty",
27
+ "dependencies": [
28
+ "../analyzer:build",
29
+ "../../tests:build",
30
+ "../gen-utils:build"
31
+ ],
32
+ "files": [
33
+ "src/**/*",
34
+ "tsconfig.json"
35
+ ],
36
+ "output": [
37
+ "test-gen",
38
+ "lib",
39
+ "index.{js,js.map,d.ts,d.ts.map}",
40
+ "tsconfig.tsbuildinfo"
41
+ ],
42
+ "clean": "if-file-deleted"
43
+ },
44
+ "test:gen": {
45
+ "files": [
46
+ "goldens/**/*"
47
+ ],
48
+ "dependencies": [
49
+ "build",
50
+ "../test-projects/test-element-a:pack"
51
+ ],
52
+ "#comment": "The quotes around the file regex must be double quotes on windows!",
53
+ "command": "uvu test-gen \"_test\\.js$\"",
54
+ "output": [
55
+ "gen-output",
56
+ "!gen-output/node_modules"
57
+ ]
58
+ },
59
+ "test": {
60
+ "dependencies": [
61
+ "test:gen"
62
+ ]
63
+ }
64
+ },
65
+ "dependencies": {
66
+ "@oicl-lit/analyzer": "^0.14.0",
67
+ "@oicl-lit/gen-utils": "^0.3.0"
68
+ },
69
+ "devDependencies": {
70
+ "@lit-internal/tests": "^0.0.1",
71
+ "prettier-plugin-svelte": "^3.2.6"
72
+ },
73
+ "engines": {
74
+ "node": ">=14.8.0"
75
+ },
76
+ "files": [
77
+ "/index.js",
78
+ "/lib/*.js"
79
+ ],
80
+ "homepage": "https://github.com/lit/lit",
81
+ "keywords": [
82
+ "lit",
83
+ "lit-html",
84
+ "lit-element",
85
+ "LitElement",
86
+ "generator",
87
+ "cli",
88
+ "svelte"
89
+ ]
90
+ }