@shapeshift-labs/frontier-lang-compiler 0.2.3 → 0.2.5
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/dist/index.d.ts +67 -1
- package/dist/index.js +260 -0
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ import type {
|
|
|
13
13
|
NativeSourceNode,
|
|
14
14
|
SemanticIndexRecord,
|
|
15
15
|
SemanticNode,
|
|
16
|
-
SemanticPatchBundle
|
|
16
|
+
SemanticPatchBundle,
|
|
17
|
+
SourceSpan
|
|
17
18
|
} from '@shapeshift-labs/frontier-lang-kernel';
|
|
18
19
|
import type { Diagnostic } from '@shapeshift-labs/frontier-lang-checker';
|
|
19
20
|
import type { EmitTypeScriptOptions, TypeScriptAstModule } from '@shapeshift-labs/frontier-lang-typescript';
|
|
@@ -68,6 +69,18 @@ export interface CapabilityResolution {
|
|
|
68
69
|
readonly reason?: string;
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
export interface NativeImporterAdapterDiagnostic {
|
|
73
|
+
readonly id?: string;
|
|
74
|
+
readonly severity?: 'info' | 'warning' | 'error';
|
|
75
|
+
readonly code?: string;
|
|
76
|
+
readonly phase?: 'read' | 'parse' | 'map' | 'index' | 'import' | string;
|
|
77
|
+
readonly kind?: NativeAstLossRecord['kind'];
|
|
78
|
+
readonly message: string;
|
|
79
|
+
readonly path?: string;
|
|
80
|
+
readonly span?: SourceSpan;
|
|
81
|
+
readonly metadata?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
export interface ImportNativeSourceOptions {
|
|
72
85
|
readonly id?: string;
|
|
73
86
|
readonly language?: FrontierSourceLanguage;
|
|
@@ -112,6 +125,58 @@ export type NativeSourceImportResult = LanguageImportResult & {
|
|
|
112
125
|
readonly universalAst: FrontierUniversalAstEnvelope;
|
|
113
126
|
};
|
|
114
127
|
|
|
128
|
+
export interface NativeImporterAdapterParseInput {
|
|
129
|
+
readonly sourceText: string;
|
|
130
|
+
readonly sourcePath?: string;
|
|
131
|
+
readonly sourceHash: string;
|
|
132
|
+
readonly language: FrontierSourceLanguage;
|
|
133
|
+
readonly parser: string;
|
|
134
|
+
readonly parserVersion?: string;
|
|
135
|
+
readonly adapterId: string;
|
|
136
|
+
readonly adapterVersion?: string;
|
|
137
|
+
readonly options: Record<string, unknown>;
|
|
138
|
+
readonly metadata: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface NativeImporterAdapterParseResult extends Omit<ImportNativeSourceOptions, 'language' | 'parser' | 'parserVersion' | 'sourceText'> {
|
|
142
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface NativeImporterAdapter {
|
|
146
|
+
readonly id: string;
|
|
147
|
+
readonly language: FrontierSourceLanguage;
|
|
148
|
+
readonly parser: string;
|
|
149
|
+
readonly version?: string;
|
|
150
|
+
readonly capabilities?: readonly string[];
|
|
151
|
+
readonly supportedExtensions?: readonly string[];
|
|
152
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
153
|
+
readonly parse: (input: NativeImporterAdapterParseInput) => NativeImporterAdapterParseResult | Promise<NativeImporterAdapterParseResult>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface NativeImporterAdapterSummary {
|
|
157
|
+
readonly id: string;
|
|
158
|
+
readonly language: FrontierSourceLanguage;
|
|
159
|
+
readonly parser: string;
|
|
160
|
+
readonly version?: string;
|
|
161
|
+
readonly capabilities: readonly string[];
|
|
162
|
+
readonly supportedExtensions: readonly string[];
|
|
163
|
+
readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface RunNativeImporterAdapterOptions extends Omit<ImportNativeSourceOptions, 'language' | 'parser' | 'parserVersion' | 'sourceText'> {
|
|
167
|
+
readonly sourceText: string;
|
|
168
|
+
readonly language?: FrontierSourceLanguage;
|
|
169
|
+
readonly parser?: string;
|
|
170
|
+
readonly parserVersion?: string;
|
|
171
|
+
readonly adapterOptions?: Record<string, unknown>;
|
|
172
|
+
readonly adapterMetadata?: Record<string, unknown>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export type NativeImporterAdapterImportResult = NativeSourceImportResult & {
|
|
176
|
+
readonly adapter: NativeImporterAdapterSummary;
|
|
177
|
+
readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
|
|
178
|
+
};
|
|
179
|
+
|
|
115
180
|
export declare const FrontierCompileTargets: readonly FrontierCompileTarget[];
|
|
116
181
|
export declare function normalizeCompileTarget(target?: string): FrontierCompileTarget;
|
|
117
182
|
export declare function compileFrontierSource(source: string, options?: FrontierCompileOptions): FrontierCompileResult;
|
|
@@ -119,6 +184,7 @@ export declare function compileFrontierDocument(document: FrontierLangDocument,
|
|
|
119
184
|
export declare function projectFrontierAst(document: FrontierLangDocument, target?: FrontierCompileOptions['target'], options?: FrontierCompileEmitOptions): FrontierTargetAst;
|
|
120
185
|
export declare function renderTargetAst(ast: FrontierTargetAst, target?: FrontierCompileOptions['target']): string;
|
|
121
186
|
export declare function resolveCapabilityAdapters(document: FrontierLangDocument, target?: FrontierCompileOptions['target'], options?: { readonly platform?: string }): readonly CapabilityResolution[];
|
|
187
|
+
export declare function runNativeImporterAdapter(adapter: NativeImporterAdapter, input: RunNativeImporterAdapterOptions): Promise<NativeImporterAdapterImportResult>;
|
|
122
188
|
export declare function importNativeSource(input: ImportNativeSourceOptions): NativeSourceImportResult;
|
|
123
189
|
export declare function createUniversalAstFromDocument(document: FrontierLangDocument, input?: {
|
|
124
190
|
readonly id?: string;
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,125 @@ export function resolveCapabilityAdapters(document, target = 'typescript', optio
|
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
export async function runNativeImporterAdapter(adapter, input = {}) {
|
|
139
|
+
const summary = normalizeNativeImporterAdapter(adapter);
|
|
140
|
+
const language = input.language ?? summary.language;
|
|
141
|
+
const parser = input.parser ?? summary.parser;
|
|
142
|
+
const parserVersion = input.parserVersion ?? summary.version;
|
|
143
|
+
const sourceText = input.sourceText ?? '';
|
|
144
|
+
const sourceHash = input.sourceHash ?? hashSemanticValue(sourceText);
|
|
145
|
+
const parseInput = {
|
|
146
|
+
sourceText,
|
|
147
|
+
sourcePath: input.sourcePath,
|
|
148
|
+
sourceHash,
|
|
149
|
+
language,
|
|
150
|
+
parser,
|
|
151
|
+
parserVersion,
|
|
152
|
+
adapterId: summary.id,
|
|
153
|
+
adapterVersion: summary.version,
|
|
154
|
+
options: input.adapterOptions ?? {},
|
|
155
|
+
metadata: input.adapterMetadata ?? {}
|
|
156
|
+
};
|
|
157
|
+
let parsed;
|
|
158
|
+
let thrownDiagnostic;
|
|
159
|
+
try {
|
|
160
|
+
parsed = await adapter.parse(parseInput);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
thrownDiagnostic = {
|
|
163
|
+
severity: 'error',
|
|
164
|
+
code: 'adapter.parse.threw',
|
|
165
|
+
phase: 'parse',
|
|
166
|
+
kind: 'unsupportedSyntax',
|
|
167
|
+
message: error instanceof Error ? error.message : String(error),
|
|
168
|
+
metadata: {
|
|
169
|
+
errorName: error instanceof Error ? error.name : undefined
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
parsed = {
|
|
173
|
+
rootId: 'adapter_error_root',
|
|
174
|
+
nodes: {
|
|
175
|
+
adapter_error_root: {
|
|
176
|
+
id: 'adapter_error_root',
|
|
177
|
+
kind: 'AdapterParseError',
|
|
178
|
+
languageKind: `${language}.adapterParseError`,
|
|
179
|
+
value: thrownDiagnostic.message,
|
|
180
|
+
metadata: { adapterId: summary.id, parser }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const parseResult = parsed ?? {};
|
|
186
|
+
const diagnostics = [
|
|
187
|
+
...normalizeAdapterDiagnostics(summary.diagnostics, summary, parseInput, 'adapter'),
|
|
188
|
+
...(thrownDiagnostic ? normalizeAdapterDiagnostics([thrownDiagnostic], summary, parseInput, 'throw') : []),
|
|
189
|
+
...normalizeAdapterDiagnostics(parseResult.diagnostics, summary, parseInput, 'parse')
|
|
190
|
+
];
|
|
191
|
+
const losses = mergeNativeLosses(
|
|
192
|
+
parseResult.losses,
|
|
193
|
+
diagnostics.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, summary, parseInput))
|
|
194
|
+
);
|
|
195
|
+
const sourceEvidence = adapterDiagnosticsEvidence(summary, diagnostics, {
|
|
196
|
+
language,
|
|
197
|
+
parser,
|
|
198
|
+
parserVersion,
|
|
199
|
+
sourcePath: parseResult.sourcePath ?? input.sourcePath,
|
|
200
|
+
sourceHash: parseResult.sourceHash ?? sourceHash
|
|
201
|
+
});
|
|
202
|
+
const evidence = [...(parseResult.evidence ?? []), sourceEvidence];
|
|
203
|
+
const importInput = {
|
|
204
|
+
...input,
|
|
205
|
+
...parseResult,
|
|
206
|
+
language,
|
|
207
|
+
parser,
|
|
208
|
+
parserVersion,
|
|
209
|
+
sourceText,
|
|
210
|
+
sourcePath: parseResult.sourcePath ?? input.sourcePath,
|
|
211
|
+
sourceHash: parseResult.sourceHash ?? sourceHash,
|
|
212
|
+
losses,
|
|
213
|
+
evidence,
|
|
214
|
+
metadata: {
|
|
215
|
+
adapterId: summary.id,
|
|
216
|
+
adapterVersion: summary.version,
|
|
217
|
+
adapterCapabilities: summary.capabilities,
|
|
218
|
+
supportedExtensions: summary.supportedExtensions,
|
|
219
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
220
|
+
...input.metadata,
|
|
221
|
+
...parseResult.metadata
|
|
222
|
+
},
|
|
223
|
+
nativeAstMetadata: {
|
|
224
|
+
adapterId: summary.id,
|
|
225
|
+
adapterVersion: summary.version,
|
|
226
|
+
parser,
|
|
227
|
+
...input.nativeAstMetadata,
|
|
228
|
+
...parseResult.nativeAstMetadata
|
|
229
|
+
},
|
|
230
|
+
nativeSourceMetadata: {
|
|
231
|
+
adapterId: summary.id,
|
|
232
|
+
adapterVersion: summary.version,
|
|
233
|
+
parser,
|
|
234
|
+
...input.nativeSourceMetadata,
|
|
235
|
+
...parseResult.nativeSourceMetadata
|
|
236
|
+
},
|
|
237
|
+
documentMetadata: {
|
|
238
|
+
nativeImporterAdapterId: summary.id,
|
|
239
|
+
nativeImporterAdapterVersion: summary.version,
|
|
240
|
+
...input.documentMetadata,
|
|
241
|
+
...parseResult.documentMetadata
|
|
242
|
+
},
|
|
243
|
+
universalAstMetadata: {
|
|
244
|
+
nativeImporterAdapterId: summary.id,
|
|
245
|
+
nativeImporterAdapterVersion: summary.version,
|
|
246
|
+
...input.universalAstMetadata,
|
|
247
|
+
...parseResult.universalAstMetadata
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
return {
|
|
251
|
+
...importNativeSource(importInput),
|
|
252
|
+
adapter: summary,
|
|
253
|
+
diagnostics
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
138
257
|
export function importNativeSource(input) {
|
|
139
258
|
const language = input.language ?? input.nativeAst?.language;
|
|
140
259
|
if (!language) throw new Error('importNativeSource requires a language or nativeAst.language');
|
|
@@ -599,6 +718,147 @@ export function emitForTarget(document, target = 'typescript', options = {}) {
|
|
|
599
718
|
return renderTargetAst(projectFrontierAst(document, target, options), target);
|
|
600
719
|
}
|
|
601
720
|
|
|
721
|
+
function normalizeNativeImporterAdapter(adapter) {
|
|
722
|
+
if (!adapter || typeof adapter !== 'object') {
|
|
723
|
+
throw new Error('Native importer adapter must be an object');
|
|
724
|
+
}
|
|
725
|
+
if (!adapter.id) throw new Error('Native importer adapter requires an id');
|
|
726
|
+
if (!adapter.language) throw new Error(`Native importer adapter ${adapter.id} requires a language`);
|
|
727
|
+
if (!adapter.parser) throw new Error(`Native importer adapter ${adapter.id} requires a parser`);
|
|
728
|
+
if (typeof adapter.parse !== 'function') throw new Error(`Native importer adapter ${adapter.id} requires a parse function`);
|
|
729
|
+
const summaryInput = {
|
|
730
|
+
id: String(adapter.id),
|
|
731
|
+
language: adapter.language,
|
|
732
|
+
parser: String(adapter.parser),
|
|
733
|
+
version: adapter.version === undefined ? undefined : String(adapter.version)
|
|
734
|
+
};
|
|
735
|
+
return Object.freeze({
|
|
736
|
+
...summaryInput,
|
|
737
|
+
capabilities: normalizeStringList(adapter.capabilities),
|
|
738
|
+
supportedExtensions: normalizeStringList(adapter.supportedExtensions).map((extension) => extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`),
|
|
739
|
+
diagnostics: normalizeAdapterDiagnostics(adapter.diagnostics, summaryInput, {
|
|
740
|
+
language: adapter.language,
|
|
741
|
+
parser: String(adapter.parser),
|
|
742
|
+
parserVersion: adapter.version === undefined ? undefined : String(adapter.version)
|
|
743
|
+
}, 'adapter')
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function normalizeStringList(value) {
|
|
748
|
+
if (value === undefined || value === null) return [];
|
|
749
|
+
if (Array.isArray(value)) return value.map((item) => String(item)).filter(Boolean);
|
|
750
|
+
return [String(value)].filter(Boolean);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
function normalizeAdapterDiagnostics(value, adapter, input, scope = 'diagnostic') {
|
|
754
|
+
if (value === undefined || value === null) return [];
|
|
755
|
+
const diagnostics = Array.isArray(value) ? value : [value];
|
|
756
|
+
return diagnostics.map((diagnostic, index) => {
|
|
757
|
+
const normalized = typeof diagnostic === 'string' ? { message: diagnostic } : diagnostic ?? {};
|
|
758
|
+
const severity = normalizeDiagnosticSeverity(normalized.severity);
|
|
759
|
+
return Object.freeze({
|
|
760
|
+
id: normalized.id ?? `diagnostic_${idFragment(adapter.id)}_${idFragment(scope)}_${index + 1}`,
|
|
761
|
+
severity,
|
|
762
|
+
code: normalized.code,
|
|
763
|
+
phase: normalized.phase ?? 'parse',
|
|
764
|
+
kind: normalized.kind,
|
|
765
|
+
message: String(normalized.message ?? `${adapter.id} reported a ${severity} diagnostic.`),
|
|
766
|
+
path: normalized.path ?? input.sourcePath,
|
|
767
|
+
span: normalized.span,
|
|
768
|
+
metadata: {
|
|
769
|
+
adapterId: adapter.id,
|
|
770
|
+
adapterVersion: adapter.version,
|
|
771
|
+
language: input.language ?? adapter.language,
|
|
772
|
+
parser: input.parser ?? adapter.parser,
|
|
773
|
+
parserVersion: input.parserVersion,
|
|
774
|
+
...normalized.metadata
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function normalizeDiagnosticSeverity(value) {
|
|
781
|
+
const severity = String(value ?? 'warning').toLowerCase();
|
|
782
|
+
if (severity === 'error') return 'error';
|
|
783
|
+
if (severity === 'info') return 'info';
|
|
784
|
+
return 'warning';
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function adapterDiagnosticToLoss(diagnostic, index, adapter, input) {
|
|
788
|
+
const code = diagnostic.code ?? diagnostic.kind ?? diagnostic.severity;
|
|
789
|
+
return {
|
|
790
|
+
id: `loss_${idFragment(diagnostic.id ?? `${adapter.id}_${index}_${code}`)}`,
|
|
791
|
+
severity: diagnostic.severity,
|
|
792
|
+
phase: diagnostic.phase,
|
|
793
|
+
sourceFormat: input.language,
|
|
794
|
+
kind: diagnostic.kind ?? (diagnostic.severity === 'error' ? 'unsupportedSyntax' : 'opaqueNative'),
|
|
795
|
+
message: diagnostic.message,
|
|
796
|
+
span: diagnostic.span,
|
|
797
|
+
metadata: {
|
|
798
|
+
adapterId: adapter.id,
|
|
799
|
+
adapterVersion: adapter.version,
|
|
800
|
+
diagnosticId: diagnostic.id,
|
|
801
|
+
diagnosticCode: diagnostic.code,
|
|
802
|
+
parser: input.parser,
|
|
803
|
+
parserVersion: input.parserVersion,
|
|
804
|
+
path: diagnostic.path,
|
|
805
|
+
...diagnostic.metadata
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function mergeNativeLosses(primary = [], secondary = []) {
|
|
811
|
+
const seen = new Set();
|
|
812
|
+
const losses = [];
|
|
813
|
+
for (const loss of [...primary, ...secondary]) {
|
|
814
|
+
if (!loss) continue;
|
|
815
|
+
const id = loss.id ?? `loss_${losses.length + 1}`;
|
|
816
|
+
if (seen.has(id)) continue;
|
|
817
|
+
seen.add(id);
|
|
818
|
+
losses.push(loss.id ? loss : { ...loss, id });
|
|
819
|
+
}
|
|
820
|
+
return losses;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
function adapterDiagnosticsEvidence(adapter, diagnostics, input) {
|
|
824
|
+
const errors = diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length;
|
|
825
|
+
const warnings = diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length;
|
|
826
|
+
return {
|
|
827
|
+
id: `evidence_${idFragment(adapter.id)}_native_importer_adapter`,
|
|
828
|
+
kind: 'import',
|
|
829
|
+
status: errors ? 'failed' : 'passed',
|
|
830
|
+
path: input.sourcePath,
|
|
831
|
+
summary: `Ran ${adapter.id} native importer for ${input.language} with ${diagnostics.length} diagnostic(s).`,
|
|
832
|
+
metadata: {
|
|
833
|
+
adapterId: adapter.id,
|
|
834
|
+
adapterVersion: adapter.version,
|
|
835
|
+
language: input.language,
|
|
836
|
+
parser: input.parser,
|
|
837
|
+
parserVersion: input.parserVersion,
|
|
838
|
+
sourceHash: input.sourceHash,
|
|
839
|
+
capabilities: adapter.capabilities,
|
|
840
|
+
supportedExtensions: adapter.supportedExtensions,
|
|
841
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
842
|
+
errors,
|
|
843
|
+
warnings
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
function serializableDiagnostic(diagnostic) {
|
|
849
|
+
return {
|
|
850
|
+
id: diagnostic.id,
|
|
851
|
+
severity: diagnostic.severity,
|
|
852
|
+
code: diagnostic.code,
|
|
853
|
+
phase: diagnostic.phase,
|
|
854
|
+
kind: diagnostic.kind,
|
|
855
|
+
message: diagnostic.message,
|
|
856
|
+
path: diagnostic.path,
|
|
857
|
+
span: diagnostic.span,
|
|
858
|
+
metadata: diagnostic.metadata
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
|
|
602
862
|
function idFragment(value) {
|
|
603
863
|
return String(value ?? 'native')
|
|
604
864
|
.toLowerCase()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@shapeshift-labs/frontier-lang-c": "0.2.
|
|
60
|
-
"@shapeshift-labs/frontier-lang-checker": "0.3.
|
|
61
|
-
"@shapeshift-labs/frontier-lang-javascript": "0.2.
|
|
59
|
+
"@shapeshift-labs/frontier-lang-c": "0.2.1",
|
|
60
|
+
"@shapeshift-labs/frontier-lang-checker": "0.3.1",
|
|
61
|
+
"@shapeshift-labs/frontier-lang-javascript": "0.2.1",
|
|
62
62
|
"@shapeshift-labs/frontier-lang-kernel": "0.3.1",
|
|
63
|
-
"@shapeshift-labs/frontier-lang-parser": "0.3.
|
|
64
|
-
"@shapeshift-labs/frontier-lang-python": "0.2.
|
|
65
|
-
"@shapeshift-labs/frontier-lang-rust": "0.2.
|
|
66
|
-
"@shapeshift-labs/frontier-lang-typescript": "0.3.
|
|
63
|
+
"@shapeshift-labs/frontier-lang-parser": "0.3.1",
|
|
64
|
+
"@shapeshift-labs/frontier-lang-python": "0.2.1",
|
|
65
|
+
"@shapeshift-labs/frontier-lang-rust": "0.2.1",
|
|
66
|
+
"@shapeshift-labs/frontier-lang-typescript": "0.3.1"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"typescript": "^5.9.3"
|