@mearl/preset 3.0.0-beta.4 → 3.0.0-beta.7
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 +45 -2
- package/dist/browserControls.d.ts +29 -0
- package/dist/browserControls.js +54 -0
- package/dist/browserPreset.js +8 -3
- package/dist/browserViews.d.ts +1 -1
- package/dist/browserViews.js +5 -5
- package/dist/bundle.d.ts +4 -1
- package/dist/bundle.js +24 -5
- package/dist/bundleStore.js +80 -75
- package/dist/bundles.d.ts +7 -1
- package/dist/bundles.js +4 -1
- package/dist/{nodeSnapshot.d.ts → capabilitySnapshot.d.ts} +11 -11
- package/dist/{nodeSnapshot.js → capabilitySnapshot.js} +36 -35
- package/dist/extensionContributions.d.ts +29 -0
- package/dist/extensionContributions.js +57 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/installation.d.ts +5 -1
- package/dist/installation.js +19 -6
- package/dist/manifest.js +5 -5
- package/dist/networkRoutes.d.ts +12 -0
- package/dist/networkRoutes.js +32 -0
- package/dist/prepare.d.ts +6 -0
- package/dist/prepare.js +81 -16
- package/dist/preset.js +3 -1
- package/dist/requestUi.d.ts +3 -1
- package/dist/requestUi.js +2 -2
- package/dist/resolve.js +4 -0
- package/dist/toolboxCatalogs.d.ts +8 -0
- package/dist/toolboxCatalogs.js +34 -0
- package/dist/types.d.ts +2 -1
- package/installation-site.json +4 -0
- package/package.json +9 -3
package/dist/prepare.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { BundleError, MAX_BROWSER_STORAGE_BYTES, bundleDigest, bundleSourceUrl, prepareBundle } from './bundle.js';
|
|
1
|
+
import { BundleError, MAX_BROWSER_STORAGE_BYTES, MAX_BUNDLE_MANIFEST_BYTES, bundleDigest, bundleSourceUrl, prepareBundle, validateBundleManifest } from './bundle.js';
|
|
2
|
+
import { satisfies } from 'semver';
|
|
2
3
|
import { clonePresetDefaults, validatePreset } from './manifest.js';
|
|
3
4
|
import { resolvePreset } from './resolve.js';
|
|
4
5
|
export async function presetSnapshotRevision(value) {
|
|
5
6
|
return bundleDigest(new TextEncoder().encode(JSON.stringify(value)));
|
|
6
7
|
}
|
|
8
|
+
/** Select candidates without assuming that inferred locations have been discovered. */
|
|
9
|
+
function selectPresetPackages(preset, runtimes) {
|
|
10
|
+
const entries = Object.entries(preset.packages).filter(([, entry]) => entry.enabled !== false && (entry.targets ?? ['browser', 'node']).some(runtime => runtimes.includes(runtime)));
|
|
11
|
+
if (entries.length > 64)
|
|
12
|
+
throw new BundleError('BUNDLE_QUOTA', 'A preset can activate at most 64 packages');
|
|
13
|
+
return entries;
|
|
14
|
+
}
|
|
7
15
|
/** Each execution location must be able to satisfy its own package dependencies. */
|
|
8
16
|
export function presetPackages(preset, runtimes) {
|
|
9
|
-
if (runtimes.includes('node') && runtimes.includes('browser') && Object.values(preset.packages).some(entry => entry.enabled !== false && !entry.runtimes?.length)) {
|
|
10
|
-
throw new BundleError('BUNDLE_INCOMPATIBLE', 'Every enabled package must declare its browser and/or Node runtime');
|
|
11
|
-
}
|
|
12
17
|
for (const runtime of runtimes) {
|
|
13
|
-
const entries = Object.entries(preset.packages).filter(([, entry]) => entry.enabled !== false && entry.
|
|
18
|
+
const entries = Object.entries(preset.packages).filter(([, entry]) => entry.enabled !== false && (entry.targets ?? ['browser', 'node']).includes(runtime));
|
|
14
19
|
const ids = new Set(entries.map(([id]) => id));
|
|
15
20
|
for (const [id, entry] of entries) {
|
|
16
21
|
if (entry.dependsOn?.some(dependency => !ids.has(dependency))) {
|
|
@@ -25,10 +30,37 @@ export function presetPackages(preset, runtimes) {
|
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
return selectPresetPackages(preset, runtimes);
|
|
34
|
+
}
|
|
35
|
+
export function bundleTargets(bundle) {
|
|
36
|
+
const contributions = bundle.manifest.contributions;
|
|
37
|
+
const targets = [];
|
|
38
|
+
if (contributions && (Object.keys(contributions.browserRuntimes ?? {}).length || Object.keys(contributions.pageRuntimes ?? {}).length || contributions.appProfiles?.length || contributions.extension || contributions.requestUi || contributions.browserViews || contributions.browserControls))
|
|
39
|
+
targets.push('browser');
|
|
40
|
+
if (Object.keys(contributions?.nodeRuntimes ?? {}).length)
|
|
41
|
+
targets.push('node');
|
|
42
|
+
return targets.length ? targets : ['browser', 'node'];
|
|
43
|
+
}
|
|
44
|
+
/** Resolved activation choices are derived data; source manifests remain unchanged. */
|
|
45
|
+
export function applyPackageTargets(preset, targets) {
|
|
46
|
+
const enabled = Object.entries(preset.packages).filter(([, entry]) => entry.enabled !== false);
|
|
47
|
+
if (enabled.length !== Object.keys(targets).length)
|
|
48
|
+
throw new BundleError('BUNDLE_INTEGRITY', 'Package target selection does not match the preset');
|
|
49
|
+
const packages = { ...preset.packages };
|
|
50
|
+
for (const [id, entry] of enabled) {
|
|
51
|
+
const selected = targets[id];
|
|
52
|
+
if (!Array.isArray(selected) || !selected.length || selected.length > 2 || new Set(selected).size !== selected.length || selected.some(target => target !== 'browser' && target !== 'node') || entry.targets && JSON.stringify(entry.targets) !== JSON.stringify(selected))
|
|
53
|
+
throw new BundleError('BUNDLE_INTEGRITY', 'Invalid package target selection');
|
|
54
|
+
packages[id] = { ...entry, targets: [...selected] };
|
|
55
|
+
}
|
|
56
|
+
return { ...preset, packages };
|
|
57
|
+
}
|
|
58
|
+
export function verifyPackageTargets(preset, bundles) {
|
|
59
|
+
for (const bundle of bundles) {
|
|
60
|
+
const available = bundleTargets(bundle);
|
|
61
|
+
if (preset.packages[bundle.manifest.id]?.targets?.some(target => !available.includes(target)))
|
|
62
|
+
throw new BundleError('BUNDLE_INCOMPATIBLE', 'Package does not support the selected target');
|
|
63
|
+
}
|
|
32
64
|
}
|
|
33
65
|
/** Shared preparation performs no installation, code execution or permission changes. */
|
|
34
66
|
export async function preparePresetPackages(source, options, runtimes) {
|
|
@@ -47,7 +79,7 @@ export async function preparePresetPackages(source, options, runtimes) {
|
|
|
47
79
|
return bytes;
|
|
48
80
|
};
|
|
49
81
|
const manifests = {};
|
|
50
|
-
|
|
82
|
+
let preset = await resolvePreset(source, {
|
|
51
83
|
mearlApiVersion: options.mearlApiVersion,
|
|
52
84
|
signal: options.signal,
|
|
53
85
|
load: async (url) => {
|
|
@@ -63,18 +95,49 @@ export async function preparePresetPackages(source, options, runtimes) {
|
|
|
63
95
|
return manifest;
|
|
64
96
|
},
|
|
65
97
|
});
|
|
66
|
-
const
|
|
98
|
+
const targetsKnown = Object.values(preset.packages).every(entry => entry.enabled === false || Boolean(entry.targets?.length));
|
|
99
|
+
const entries = targetsKnown ? presetPackages(preset, runtimes) : selectPresetPackages(preset, runtimes);
|
|
67
100
|
const bundles = [];
|
|
101
|
+
const pending = [];
|
|
102
|
+
const packageTargets = Object.fromEntries(Object.entries(preset.packages).filter(([, entry]) => entry.enabled !== false).map(([id, entry]) => [id, entry.targets ?? []]));
|
|
68
103
|
for (const [id, entry] of entries) {
|
|
69
|
-
|
|
104
|
+
const manifestSource = bundleSourceUrl(entry.source);
|
|
105
|
+
const bytes = Uint8Array.from(await load(manifestSource, { maxBytes: MAX_BUNDLE_MANIFEST_BYTES, signal: options.signal }));
|
|
106
|
+
let manifest;
|
|
107
|
+
try {
|
|
108
|
+
manifest = validateBundleManifest(JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes)), options.mearlApiVersion);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
if (error instanceof BundleError)
|
|
112
|
+
throw error;
|
|
113
|
+
throw new BundleError('BUNDLE_INVALID', error instanceof Error ? error.message : 'Invalid package manifest');
|
|
114
|
+
}
|
|
115
|
+
if (manifest.id !== id)
|
|
116
|
+
throw new BundleError('BUNDLE_INVALID', 'Package identity does not match the preset');
|
|
117
|
+
if (entry.version && !satisfies(manifest.version, entry.version))
|
|
118
|
+
throw new BundleError('BUNDLE_INCOMPATIBLE', 'Package version does not satisfy the preset');
|
|
119
|
+
const available = bundleTargets({ manifest });
|
|
120
|
+
const targets = entry.targets ?? available;
|
|
121
|
+
if (targets.some(target => !available.includes(target)))
|
|
122
|
+
throw new BundleError('BUNDLE_INCOMPATIBLE', 'Package does not support the selected target');
|
|
123
|
+
packageTargets[id] = targets;
|
|
124
|
+
pending.push({ id, entry, source: manifestSource, bytes });
|
|
125
|
+
}
|
|
126
|
+
preset = applyPackageTargets(preset, packageTargets);
|
|
127
|
+
const selected = new Set(presetPackages(preset, runtimes).map(([id]) => id));
|
|
128
|
+
for (const candidate of pending) {
|
|
129
|
+
if (!selected.has(candidate.id))
|
|
130
|
+
continue;
|
|
131
|
+
bundles.push(await prepareBundle(candidate.source, { ...options, load: (url, request) => url === candidate.source ? Promise.resolve(candidate.bytes) : load(url, request), expectedId: candidate.id, version: candidate.entry.version }));
|
|
70
132
|
}
|
|
133
|
+
verifyPackageTargets(preset, bundles);
|
|
71
134
|
options.signal?.throwIfAborted();
|
|
72
|
-
return { source, manifests, preset, bundles };
|
|
135
|
+
return { source, manifests, preset, bundles: bundles.filter(bundle => selected.has(bundle.manifest.id)), packageTargets };
|
|
73
136
|
}
|
|
74
137
|
/** The exact graph is checked offline; installed resources are verified by the target store. */
|
|
75
138
|
export async function verifyPresetGraph(value, mearlApiVersion, runtimes, full) {
|
|
76
139
|
const json = clonePresetDefaults(value);
|
|
77
|
-
const allowed = ['source', 'manifests', 'bundleRevisions', 'revision', ...(full ? ['schemaVersion'] : [])];
|
|
140
|
+
const allowed = ['source', 'manifests', 'bundleRevisions', 'packageTargets', 'revision', ...(full ? ['schemaVersion'] : [])];
|
|
78
141
|
if (Object.keys(json).some(key => !allowed.includes(key)) || (full && json.schemaVersion !== 1) ||
|
|
79
142
|
typeof json.source !== 'string' || typeof json.revision !== 'string' || !/^[a-f0-9]{64}$/.test(json.revision)) {
|
|
80
143
|
throw new BundleError('BUNDLE_INTEGRITY', 'Invalid stored preset identity');
|
|
@@ -93,10 +156,11 @@ export async function verifyPresetGraph(value, mearlApiVersion, runtimes, full)
|
|
|
93
156
|
throw new BundleError('BUNDLE_INTEGRITY', 'Invalid stored preset source');
|
|
94
157
|
validated[url] = validatePreset(manifest);
|
|
95
158
|
}
|
|
96
|
-
const
|
|
159
|
+
const packageTargets = clonePresetDefaults(json.packageTargets);
|
|
160
|
+
const data = { ...(full ? { schemaVersion: 1 } : {}), source, manifests: validated, bundleRevisions, packageTargets };
|
|
97
161
|
if (await presetSnapshotRevision(data) !== json.revision)
|
|
98
162
|
throw new BundleError('BUNDLE_INTEGRITY', 'Stored preset revision does not match');
|
|
99
|
-
|
|
163
|
+
let preset = await resolvePreset(source, {
|
|
100
164
|
mearlApiVersion,
|
|
101
165
|
load: async (url) => {
|
|
102
166
|
if (!Object.hasOwn(validated, url))
|
|
@@ -104,6 +168,7 @@ export async function verifyPresetGraph(value, mearlApiVersion, runtimes, full)
|
|
|
104
168
|
return validated[url];
|
|
105
169
|
},
|
|
106
170
|
});
|
|
171
|
+
preset = applyPackageTargets(preset, packageTargets);
|
|
107
172
|
const entries = presetPackages(preset, runtimes);
|
|
108
173
|
if (preset.chain.length !== Object.keys(validated).length || entries.length !== Object.keys(bundleRevisions).length || entries.some(([id]) => !Object.hasOwn(bundleRevisions, id))) {
|
|
109
174
|
throw new BundleError('BUNDLE_INTEGRITY', 'Stored preset package graph does not match');
|
package/dist/preset.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { browserPresetSnapshot } from './browserPreset.js';
|
|
2
|
-
import { preparePresetPackages, presetSnapshotRevision, verifyPresetGraph } from './prepare.js';
|
|
2
|
+
import { preparePresetPackages, presetSnapshotRevision, verifyPresetGraph, verifyPackageTargets } from './prepare.js';
|
|
3
3
|
import { satisfies } from 'semver';
|
|
4
4
|
import { BundleError, MAX_BROWSER_STORAGE_BYTES, verifyBundle } from './bundle.js';
|
|
5
5
|
export async function preparePreset(source, options) {
|
|
@@ -9,6 +9,7 @@ export async function preparePreset(source, options) {
|
|
|
9
9
|
source: prepared.source,
|
|
10
10
|
manifests: prepared.manifests,
|
|
11
11
|
bundleRevisions: Object.fromEntries(prepared.bundles.map(bundle => [bundle.manifest.id, bundle.revision])),
|
|
12
|
+
packageTargets: prepared.packageTargets,
|
|
12
13
|
};
|
|
13
14
|
const snapshot = { ...data, revision: await presetSnapshotRevision(data) };
|
|
14
15
|
const browser = await browserPresetSnapshot(prepared.source, prepared.manifests, prepared.preset, prepared.bundles);
|
|
@@ -44,6 +45,7 @@ export async function verifyPreparedPreset(value, mearlApiVersion) {
|
|
|
44
45
|
Promise.all(value.bundles.map(bundle => verifyBundle(bundle, mearlApiVersion))),
|
|
45
46
|
]);
|
|
46
47
|
const { snapshot, preset } = graph;
|
|
48
|
+
verifyPackageTargets(preset, bundles);
|
|
47
49
|
if (bundles.length !== Object.keys(snapshot.bundleRevisions).length || new Set(bundles.map(bundle => bundle.manifest.id)).size !== bundles.length || bundles.some(bundle => {
|
|
48
50
|
const entry = preset.packages[bundle.manifest.id];
|
|
49
51
|
return snapshot.bundleRevisions[bundle.manifest.id] !== bundle.revision || entry?.source !== bundle.source || (entry.version && !satisfies(bundle.manifest.version, entry.version));
|
package/dist/requestUi.d.ts
CHANGED
|
@@ -49,7 +49,9 @@ export interface SelectedBrowserRequestUi {
|
|
|
49
49
|
definition: BrowserRequestUi;
|
|
50
50
|
}
|
|
51
51
|
export declare function validateBrowserUiText(value: unknown): void;
|
|
52
|
-
export declare function browserUiHttpUrl(value: unknown
|
|
52
|
+
export declare function browserUiHttpUrl(value: unknown, options?: {
|
|
53
|
+
allowFragment?: boolean;
|
|
54
|
+
}): string;
|
|
53
55
|
export declare function validateBrowserRequestUi(input: unknown): BrowserRequestUi;
|
|
54
56
|
/** Contribution validation is pure; factories and UI side effects belong to the host. */
|
|
55
57
|
export declare function selectBrowserRequestUi(bundles: PreparedBundle[], apiVersion: string): SelectedBrowserRequestUi | undefined;
|
package/dist/requestUi.js
CHANGED
|
@@ -10,7 +10,7 @@ export function validateBrowserUiText(value) {
|
|
|
10
10
|
if (typeof value.en !== 'string' || !value.en.trim() || Object.values(value).some(entry => typeof entry !== 'string' || entry.length > 1024 || !entry.trim()))
|
|
11
11
|
invalid('Request UI text requires bounded translations');
|
|
12
12
|
}
|
|
13
|
-
export function browserUiHttpUrl(value) {
|
|
13
|
+
export function browserUiHttpUrl(value, options = {}) {
|
|
14
14
|
if (typeof value !== 'string' || value.length > 4096)
|
|
15
15
|
invalid('Invalid request UI URL');
|
|
16
16
|
let url;
|
|
@@ -20,7 +20,7 @@ export function browserUiHttpUrl(value) {
|
|
|
20
20
|
catch {
|
|
21
21
|
invalid('Invalid request UI URL');
|
|
22
22
|
}
|
|
23
|
-
if (url.username || url.password || url.hash || url.protocol !== 'https:' && !(url.protocol === 'http:' && ['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname)))
|
|
23
|
+
if (url.username || url.password || !options.allowFragment && url.hash || url.protocol !== 'https:' && !(url.protocol === 'http:' && ['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname)))
|
|
24
24
|
invalid('Request UI requires credential-free HTTPS or loopback URLs');
|
|
25
25
|
return url.href;
|
|
26
26
|
}
|
package/dist/resolve.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseToolboxCatalogs } from './toolboxCatalogs.js';
|
|
1
2
|
import { satisfies, valid } from 'semver';
|
|
2
3
|
import { clonePresetDefaults, isJsonObject, PresetError, validatePreset } from './manifest.js';
|
|
3
4
|
const kinds = ['packages', 'skills', 'providers'];
|
|
@@ -127,6 +128,9 @@ export async function resolvePreset(source, options) {
|
|
|
127
128
|
return result;
|
|
128
129
|
};
|
|
129
130
|
const result = await load(sourceUrl(source));
|
|
131
|
+
const extension = result.defaults.extension;
|
|
132
|
+
if (isJsonObject(extension))
|
|
133
|
+
parseToolboxCatalogs(extension.toolCatalogs);
|
|
130
134
|
// Dependency validity is checked on the final graph, so children may complete or disable parent entries.
|
|
131
135
|
for (const kind of kinds)
|
|
132
136
|
validateDependencies(kind, result[kind]);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ToolboxCatalogConfig {
|
|
2
|
+
url?: string;
|
|
3
|
+
label?: string;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export type ToolboxCatalogConfigs = Record<string, ToolboxCatalogConfig>;
|
|
7
|
+
/** Stable keys let child presets patch or disable a parent directory through defaults merging. */
|
|
8
|
+
export declare function parseToolboxCatalogs(input: unknown): ToolboxCatalogConfigs;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isJsonObject, PresetError } from './manifest.js';
|
|
2
|
+
/** Stable keys let child presets patch or disable a parent directory through defaults merging. */
|
|
3
|
+
export function parseToolboxCatalogs(input) {
|
|
4
|
+
if (input === undefined)
|
|
5
|
+
return {};
|
|
6
|
+
function invalid() { throw new PresetError('PRESET_INVALID', 'Invalid extension.toolCatalogs configuration'); }
|
|
7
|
+
if (!isJsonObject(input) || Object.keys(input).length > 16)
|
|
8
|
+
invalid();
|
|
9
|
+
return Object.fromEntries(Object.entries(input).map(([id, entry]) => {
|
|
10
|
+
if (!/^[a-z][a-z0-9-]{0,63}$/.test(id) || id === 'official' || !isJsonObject(entry) || Object.keys(entry).some(key => !['url', 'label', 'enabled'].includes(key)))
|
|
11
|
+
invalid();
|
|
12
|
+
if (entry.enabled !== undefined && typeof entry.enabled !== 'boolean')
|
|
13
|
+
invalid();
|
|
14
|
+
if (entry.label !== undefined && (typeof entry.label !== 'string' || !entry.label.trim() || entry.label.length > 120))
|
|
15
|
+
invalid();
|
|
16
|
+
let url;
|
|
17
|
+
if (entry.url !== undefined) {
|
|
18
|
+
if (typeof entry.url !== 'string' || entry.url.length > 2048)
|
|
19
|
+
invalid();
|
|
20
|
+
try {
|
|
21
|
+
const parsed = new URL(entry.url);
|
|
22
|
+
if (parsed.username || parsed.password || parsed.hash || !(parsed.protocol === 'https:' || parsed.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(parsed.hostname)))
|
|
23
|
+
invalid();
|
|
24
|
+
url = parsed.href;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
invalid();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if (entry.enabled !== false)
|
|
31
|
+
invalid();
|
|
32
|
+
return [id, { ...(url ? { url } : {}), ...(entry.label !== undefined ? { label: entry.label } : {}), ...(entry.enabled !== undefined ? { enabled: entry.enabled } : {}) }];
|
|
33
|
+
}));
|
|
34
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ export interface PresetComponent {
|
|
|
11
11
|
/** Previous Skill sources eligible for migration only when setup owns the installation. */
|
|
12
12
|
migrateFrom?: string[];
|
|
13
13
|
enabled?: boolean;
|
|
14
|
-
|
|
14
|
+
/** Optional activation subset; supported locations are defined by the package. */
|
|
15
|
+
targets?: PresetRuntime[];
|
|
15
16
|
dependsOn?: string[];
|
|
16
17
|
}
|
|
17
18
|
export interface PresetReference {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/preset",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.7",
|
|
4
4
|
"description": "Browser-compatible preset validation, inheritance and capability resolution for Mearl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,11 +18,17 @@
|
|
|
18
18
|
"./installation": {
|
|
19
19
|
"types": "./dist/installation.d.ts",
|
|
20
20
|
"import": "./dist/installation.js"
|
|
21
|
+
},
|
|
22
|
+
"./installation-site.json": "./installation-site.json",
|
|
23
|
+
"./networkRoutes": {
|
|
24
|
+
"types": "./dist/networkRoutes.d.ts",
|
|
25
|
+
"import": "./dist/networkRoutes.js"
|
|
21
26
|
}
|
|
22
27
|
},
|
|
23
28
|
"files": [
|
|
24
29
|
"dist",
|
|
25
|
-
"!dist/**/*.map"
|
|
30
|
+
"!dist/**/*.map",
|
|
31
|
+
"installation-site.json"
|
|
26
32
|
],
|
|
27
33
|
"dependencies": {
|
|
28
34
|
"semver": "^7.8.5"
|
|
@@ -32,7 +38,7 @@
|
|
|
32
38
|
},
|
|
33
39
|
"repository": {
|
|
34
40
|
"type": "git",
|
|
35
|
-
"url": "git+https://github.com/
|
|
41
|
+
"url": "git+https://github.com/mearlhq/mearl.git",
|
|
36
42
|
"directory": "packages/preset"
|
|
37
43
|
},
|
|
38
44
|
"scripts": {
|