@invinite-org/chartlang-compiler 1.0.1
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 +683 -0
- package/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/analysis/extractAlertConditions.d.ts +33 -0
- package/dist/analysis/extractAlertConditions.d.ts.map +1 -0
- package/dist/analysis/extractAlertConditions.js +118 -0
- package/dist/analysis/extractAlertConditions.js.map +1 -0
- package/dist/analysis/extractCapabilities.d.ts +22 -0
- package/dist/analysis/extractCapabilities.d.ts.map +1 -0
- package/dist/analysis/extractCapabilities.js +44 -0
- package/dist/analysis/extractCapabilities.js.map +1 -0
- package/dist/analysis/extractInputs.d.ts +44 -0
- package/dist/analysis/extractInputs.d.ts.map +1 -0
- package/dist/analysis/extractInputs.js +306 -0
- package/dist/analysis/extractInputs.js.map +1 -0
- package/dist/analysis/extractMaxLookback.d.ts +37 -0
- package/dist/analysis/extractMaxLookback.d.ts.map +1 -0
- package/dist/analysis/extractMaxLookback.js +90 -0
- package/dist/analysis/extractMaxLookback.js.map +1 -0
- package/dist/analysis/extractRequestedIntervals.d.ts +19 -0
- package/dist/analysis/extractRequestedIntervals.d.ts.map +1 -0
- package/dist/analysis/extractRequestedIntervals.js +85 -0
- package/dist/analysis/extractRequestedIntervals.js.map +1 -0
- package/dist/analysis/extractRequiresIntervals.d.ts +16 -0
- package/dist/analysis/extractRequiresIntervals.d.ts.map +1 -0
- package/dist/analysis/extractRequiresIntervals.js +71 -0
- package/dist/analysis/extractRequiresIntervals.js.map +1 -0
- package/dist/analysis/forbiddenConstructs.d.ts +22 -0
- package/dist/analysis/forbiddenConstructs.d.ts.map +1 -0
- package/dist/analysis/forbiddenConstructs.js +214 -0
- package/dist/analysis/forbiddenConstructs.js.map +1 -0
- package/dist/analysis/index.d.ts +15 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +13 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/statefulCallInLoop.d.ts +26 -0
- package/dist/analysis/statefulCallInLoop.d.ts.map +1 -0
- package/dist/analysis/statefulCallInLoop.js +64 -0
- package/dist/analysis/statefulCallInLoop.js.map +1 -0
- package/dist/analysis/structuralChecks.d.ts +73 -0
- package/dist/analysis/structuralChecks.d.ts.map +1 -0
- package/dist/analysis/structuralChecks.js +243 -0
- package/dist/analysis/structuralChecks.js.map +1 -0
- package/dist/analysis/validateLowerTfIntervals.d.ts +26 -0
- package/dist/analysis/validateLowerTfIntervals.d.ts.map +1 -0
- package/dist/analysis/validateLowerTfIntervals.js +91 -0
- package/dist/analysis/validateLowerTfIntervals.js.map +1 -0
- package/dist/api.d.ts +205 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +354 -0
- package/dist/api.js.map +1 -0
- package/dist/bundle.d.ts +75 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +90 -0
- package/dist/bundle.js.map +1 -0
- package/dist/diagnostics.d.ts +88 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +95 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +40 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +57 -0
- package/dist/manifest.js.map +1 -0
- package/dist/program.d.ts +68 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +1391 -0
- package/dist/program.js.map +1 -0
- package/dist/transformers/callsiteIdInjection.d.ts +48 -0
- package/dist/transformers/callsiteIdInjection.d.ts.map +1 -0
- package/dist/transformers/callsiteIdInjection.js +91 -0
- package/dist/transformers/callsiteIdInjection.js.map +1 -0
- package/dist/transformers/index.d.ts +4 -0
- package/dist/transformers/index.d.ts.map +1 -0
- package/dist/transformers/index.js +5 -0
- package/dist/transformers/index.js.map +1 -0
- package/dist/transformers/resolveCallee.d.ts +39 -0
- package/dist/transformers/resolveCallee.d.ts.map +1 -0
- package/dist/transformers/resolveCallee.js +136 -0
- package/dist/transformers/resolveCallee.js.map +1 -0
- package/dist/typesEmit.d.ts +35 -0
- package/dist/typesEmit.d.ts.map +1 -0
- package/dist/typesEmit.js +27 -0
- package/dist/typesEmit.js.map +1 -0
- package/package.json +48 -0
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { IntervalDescriptor, ScriptManifest } from "@invinite-org/chartlang-core";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import type { CompileDiagnostic } from "./diagnostics.js";
|
|
4
|
+
/**
|
|
5
|
+
* Options accepted by `transformAndAnalyse`. `sourcePath` is the
|
|
6
|
+
* package-relative POSIX path baked into every callsite id; the compiler
|
|
7
|
+
* does not read any other file. `declaredIntervals` is the host-supplied
|
|
8
|
+
* `Capabilities.intervals` set used by the `lower-tf-not-lower` validation —
|
|
9
|
+
* when omitted the lower-timeframe ordering check is skipped.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.1
|
|
12
|
+
* @example
|
|
13
|
+
* const opts: TransformAndAnalyseOptions = { sourcePath: "demo.chart.ts" };
|
|
14
|
+
*/
|
|
15
|
+
export type TransformAndAnalyseOptions = Readonly<{
|
|
16
|
+
sourcePath: string;
|
|
17
|
+
declaredIntervals?: ReadonlyArray<IntervalDescriptor>;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Result of `transformAndAnalyse`. `transformed` is the AST after callsite
|
|
21
|
+
* ids have been injected; `manifest` is the recursively-frozen
|
|
22
|
+
* `ScriptManifest`; `diagnostics` is the flat list of every diagnostic
|
|
23
|
+
* emitted by any pass (errors abort the rewrite, warnings flow through).
|
|
24
|
+
*
|
|
25
|
+
* @since 0.1
|
|
26
|
+
* @example
|
|
27
|
+
* // const { transformed, manifest, diagnostics } =
|
|
28
|
+
* // transformAndAnalyse(src, { sourcePath: "demo.chart.ts" });
|
|
29
|
+
* const shape: { transformed: unknown; manifest: unknown; diagnostics: unknown } = {
|
|
30
|
+
* transformed: null,
|
|
31
|
+
* manifest: null,
|
|
32
|
+
* diagnostics: [],
|
|
33
|
+
* };
|
|
34
|
+
* void shape;
|
|
35
|
+
*/
|
|
36
|
+
export type TransformAndAnalyseResult = Readonly<{
|
|
37
|
+
transformed: ts.SourceFile;
|
|
38
|
+
manifest: ScriptManifest;
|
|
39
|
+
diagnostics: ReadonlyArray<CompileDiagnostic>;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Run the Phase-1 compiler pipeline against an in-memory script source.
|
|
43
|
+
* Builds a TypeScript program, runs the structural / forbidden-construct /
|
|
44
|
+
* stateful-call-in-loop checks, rewrites stateful calls with callsite ids,
|
|
45
|
+
* and extracts the manifest's `capabilities` / `maxLookback` /
|
|
46
|
+
* `seriesCapacities` / `inputs` fields.
|
|
47
|
+
*
|
|
48
|
+
* Error-severity diagnostics short-circuit the transform: the function
|
|
49
|
+
* returns the original `sourceFile` and a placeholder manifest so callers
|
|
50
|
+
* can still surface the errors uniformly. The public `compile` /
|
|
51
|
+
* `compileFile` / `compileProject` wrappers above turn those error
|
|
52
|
+
* diagnostics into a `CompileError` throw.
|
|
53
|
+
*
|
|
54
|
+
* @since 0.1
|
|
55
|
+
* @example
|
|
56
|
+
* // const result = transformAndAnalyse(
|
|
57
|
+
* // 'export default defineIndicator({ name: "x", apiVersion: 1, compute: () => {} });',
|
|
58
|
+
* // { sourcePath: "demo.chart.ts" },
|
|
59
|
+
* // );
|
|
60
|
+
* const fn: typeof transformAndAnalyse = transformAndAnalyse;
|
|
61
|
+
* void fn;
|
|
62
|
+
*/
|
|
63
|
+
export declare function transformAndAnalyse(source: string, opts: TransformAndAnalyseOptions): TransformAndAnalyseResult;
|
|
64
|
+
/**
|
|
65
|
+
* Options accepted by `compile`. `apiVersion` is the frozen language
|
|
66
|
+
* version this compiler implements. Passing `apiVersion: 1` is an explicit
|
|
67
|
+
* acknowledgement of that contract; the type stays the literal `1` so a
|
|
68
|
+
* future `apiVersion: 2` compiler is a type-level break. See
|
|
69
|
+
* `docs/spec/versioning.md`. `sourcePath` overrides the file-system-derived
|
|
70
|
+
* path used in callsite ids; `sourcemap`, `minify`, and `target` mirror the
|
|
71
|
+
* bundler's flags. `declaredIntervals` is the adapter's
|
|
72
|
+
* `Capabilities.intervals` set — when supplied, `request.lowerTf` literals
|
|
73
|
+
* are validated against the smallest declared main interval
|
|
74
|
+
* (`lower-tf-not-lower`).
|
|
75
|
+
*
|
|
76
|
+
* @since 0.1
|
|
77
|
+
* @example
|
|
78
|
+
* const opts: CompileOptions = { apiVersion: 1, sourcePath: "demo.chart.ts" };
|
|
79
|
+
* void opts;
|
|
80
|
+
*/
|
|
81
|
+
export type CompileOptions = Readonly<{
|
|
82
|
+
apiVersion: 1;
|
|
83
|
+
sourcePath?: string;
|
|
84
|
+
sourcemap?: boolean | "inline" | "external";
|
|
85
|
+
minify?: boolean;
|
|
86
|
+
target?: "es2022";
|
|
87
|
+
declaredIntervals?: ReadonlyArray<IntervalDescriptor>;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Options accepted by `compileFile`. Extends `CompileOptions` with a `write`
|
|
91
|
+
* toggle that, when `false`, skips the sibling-file writes and returns the
|
|
92
|
+
* triple in memory only.
|
|
93
|
+
*
|
|
94
|
+
* @since 0.1
|
|
95
|
+
* @example
|
|
96
|
+
* const opts: CompileFileOptions = { apiVersion: 1, write: false };
|
|
97
|
+
* void opts;
|
|
98
|
+
*/
|
|
99
|
+
export type CompileFileOptions = CompileOptions & Readonly<{
|
|
100
|
+
write?: boolean;
|
|
101
|
+
}>;
|
|
102
|
+
/**
|
|
103
|
+
* Frozen result of a single script compilation. `moduleSource` is the bundled
|
|
104
|
+
* ESM string (with the `export const __manifest = …;` tail appended);
|
|
105
|
+
* `sourcemap` is present when the caller asked for an external map;
|
|
106
|
+
* `manifest` is the recursively-frozen `ScriptManifest`; `types` is the
|
|
107
|
+
* `.d.ts` sibling source.
|
|
108
|
+
*
|
|
109
|
+
* @since 0.1
|
|
110
|
+
* @example
|
|
111
|
+
* // const result: CompiledScript = await compile(src, { apiVersion: 1 });
|
|
112
|
+
* const shape: CompiledScript = {} as CompiledScript;
|
|
113
|
+
* void shape;
|
|
114
|
+
*/
|
|
115
|
+
export type CompiledScript = Readonly<{
|
|
116
|
+
moduleSource: string;
|
|
117
|
+
sourcemap?: string;
|
|
118
|
+
manifest: ScriptManifest;
|
|
119
|
+
types: string;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Error thrown by `compile` / `compileFile` / `compileProject` when any
|
|
123
|
+
* compilation produces an error-severity diagnostic. Carries the full
|
|
124
|
+
* frozen diagnostic array on `err.diagnostics`; the message starts with the
|
|
125
|
+
* first diagnostic's `code: message (file:line:column)` so console output
|
|
126
|
+
* stays compact.
|
|
127
|
+
*
|
|
128
|
+
* @since 0.1
|
|
129
|
+
* @example
|
|
130
|
+
* // try { await compile(badSrc, { apiVersion: 1 }); }
|
|
131
|
+
* // catch (err) { if (err instanceof CompileError) console.error(err.diagnostics); }
|
|
132
|
+
* const E: typeof CompileError = CompileError;
|
|
133
|
+
* void E;
|
|
134
|
+
*/
|
|
135
|
+
export declare class CompileError extends Error {
|
|
136
|
+
readonly diagnostics: ReadonlyArray<CompileDiagnostic>;
|
|
137
|
+
constructor(diagnostics: ReadonlyArray<CompileDiagnostic>);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Compile a script source into a frozen `CompiledScript` triple. Runs
|
|
141
|
+
* `transformAndAnalyse`, throws `CompileError` on any error diagnostic,
|
|
142
|
+
* prints the transformed AST, drives esbuild to ESM, appends the
|
|
143
|
+
* `__manifest` assignment, and emits the `.d.ts` sibling.
|
|
144
|
+
*
|
|
145
|
+
* @since 0.1
|
|
146
|
+
* @example
|
|
147
|
+
* // const result = await compile(emaCrossSource, {
|
|
148
|
+
* // apiVersion: 1,
|
|
149
|
+
* // sourcePath: "ema-cross.chart.ts",
|
|
150
|
+
* // });
|
|
151
|
+
* const fn: typeof compile = compile;
|
|
152
|
+
* void fn;
|
|
153
|
+
*/
|
|
154
|
+
export declare function compile(source: string, opts: CompileOptions): Promise<CompiledScript>;
|
|
155
|
+
/**
|
|
156
|
+
* Write a file atomically — render to a `<target>.tmp.<rand>` sibling first,
|
|
157
|
+
* then `rename` into place. On any error during write or rename, the temp
|
|
158
|
+
* file is unlinked so the caller never sees a half-written artefact.
|
|
159
|
+
*
|
|
160
|
+
* @since 0.1
|
|
161
|
+
* @example
|
|
162
|
+
* // await writeAtomic("/tmp/foo.txt", "hello");
|
|
163
|
+
* const fn: typeof writeAtomic = writeAtomic;
|
|
164
|
+
* void fn;
|
|
165
|
+
*/
|
|
166
|
+
export declare function writeAtomic(target: string, contents: string): Promise<void>;
|
|
167
|
+
/**
|
|
168
|
+
* Read a `.chart.ts` file from disk, compile it, and (when `write !== false`)
|
|
169
|
+
* emit the three sibling files atomically — `<base>.chart.js`,
|
|
170
|
+
* `<base>.chart.manifest.json`, `<base>.chart.d.ts`, plus
|
|
171
|
+
* `<base>.chart.js.map` when `sourcemap` is external.
|
|
172
|
+
*
|
|
173
|
+
* @since 0.1
|
|
174
|
+
* @example
|
|
175
|
+
* // const result = await compileFile("./demo.chart.ts", { apiVersion: 1 });
|
|
176
|
+
* const fn: typeof compileFile = compileFile;
|
|
177
|
+
* void fn;
|
|
178
|
+
*/
|
|
179
|
+
export declare function compileFile(path: string, opts: CompileFileOptions): Promise<CompiledScript>;
|
|
180
|
+
/**
|
|
181
|
+
* Walk `rootDir` recursively and return every `*.chart.ts` file's absolute
|
|
182
|
+
* path. Skips `node_modules` and `dist` subtrees. The walker is iterative to
|
|
183
|
+
* stay portable across Node 20.1 → 20.x.
|
|
184
|
+
*
|
|
185
|
+
* @since 0.1
|
|
186
|
+
* @example
|
|
187
|
+
* // const files = await walkChartFiles("./examples/scripts");
|
|
188
|
+
* const fn: typeof walkChartFiles = walkChartFiles;
|
|
189
|
+
* void fn;
|
|
190
|
+
*/
|
|
191
|
+
export declare function walkChartFiles(rootDir: string): Promise<string[]>;
|
|
192
|
+
/**
|
|
193
|
+
* Discover every `*.chart.ts` under `rootDir` and compile each in parallel.
|
|
194
|
+
* Results are returned in deterministic (path-sorted) order so callers can
|
|
195
|
+
* snapshot the array safely. Compilation runs in memory only — the CLI
|
|
196
|
+
* (Phase-1 Task 11) loops `compileFile` when it needs sibling files on disk.
|
|
197
|
+
*
|
|
198
|
+
* @since 0.1
|
|
199
|
+
* @example
|
|
200
|
+
* // const all = await compileProject("./examples/scripts", { apiVersion: 1 });
|
|
201
|
+
* const fn: typeof compileProject = compileProject;
|
|
202
|
+
* void fn;
|
|
203
|
+
*/
|
|
204
|
+
export declare function compileProject(rootDir: string, opts: CompileOptions): Promise<ReadonlyArray<CompiledScript>>;
|
|
205
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAAE,MAAM,YAAY,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAO1D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC7C,WAAW,EAAE,EAAE,CAAC,UAAU,CAAC;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CACjD,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,0BAA0B,GACjC,yBAAyB,CAkH3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAClC,UAAU,EAAE,CAAC,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,iBAAiB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAC3C,QAAQ,CAAC;IACL,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEP;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACnC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;gBAE3C,WAAW,EAAE,aAAa,CAAC,iBAAiB,CAAC;CAU5D;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAuC3F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA4BjG;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+BvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAYxC"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
4
|
+
import { readFile, readdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
5
|
+
import { isAbsolute, join, relative, resolve as resolvePath } from "node:path";
|
|
6
|
+
import { STATEFUL_PRIMITIVES_BY_NAME } from "@invinite-org/chartlang-core";
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
import { extractAlertConditions, extractCapabilities, extractInputs, extractMaxLookback, extractRequestedIntervals, extractRequiresIntervals, runForbiddenConstructs, runStatefulCallInLoop, runStructuralChecks, validateLowerTfIntervals, } from "./analysis/index.js";
|
|
9
|
+
import { bundleModule, formatManifestAssignment } from "./bundle.js";
|
|
10
|
+
import { mapTsDiagnostic } from "./diagnostics.js";
|
|
11
|
+
import { buildManifest } from "./manifest.js";
|
|
12
|
+
import { createProgramForSource } from "./program.js";
|
|
13
|
+
import { injectCallsiteIds } from "./transformers/callsiteIdInjection.js";
|
|
14
|
+
import { emitTypes } from "./typesEmit.js";
|
|
15
|
+
/**
|
|
16
|
+
* Run the Phase-1 compiler pipeline against an in-memory script source.
|
|
17
|
+
* Builds a TypeScript program, runs the structural / forbidden-construct /
|
|
18
|
+
* stateful-call-in-loop checks, rewrites stateful calls with callsite ids,
|
|
19
|
+
* and extracts the manifest's `capabilities` / `maxLookback` /
|
|
20
|
+
* `seriesCapacities` / `inputs` fields.
|
|
21
|
+
*
|
|
22
|
+
* Error-severity diagnostics short-circuit the transform: the function
|
|
23
|
+
* returns the original `sourceFile` and a placeholder manifest so callers
|
|
24
|
+
* can still surface the errors uniformly. The public `compile` /
|
|
25
|
+
* `compileFile` / `compileProject` wrappers above turn those error
|
|
26
|
+
* diagnostics into a `CompileError` throw.
|
|
27
|
+
*
|
|
28
|
+
* @since 0.1
|
|
29
|
+
* @example
|
|
30
|
+
* // const result = transformAndAnalyse(
|
|
31
|
+
* // 'export default defineIndicator({ name: "x", apiVersion: 1, compute: () => {} });',
|
|
32
|
+
* // { sourcePath: "demo.chart.ts" },
|
|
33
|
+
* // );
|
|
34
|
+
* const fn: typeof transformAndAnalyse = transformAndAnalyse;
|
|
35
|
+
* void fn;
|
|
36
|
+
*/
|
|
37
|
+
export function transformAndAnalyse(source, opts) {
|
|
38
|
+
const sourcePath = opts.sourcePath;
|
|
39
|
+
const { program, sourceFile, checker } = createProgramForSource(source, { sourcePath });
|
|
40
|
+
const structural = runStructuralChecks(sourceFile, checker, sourcePath);
|
|
41
|
+
const forbidden = runForbiddenConstructs(sourceFile, sourcePath);
|
|
42
|
+
const statefulInLoop = runStatefulCallInLoop(sourceFile, checker, sourcePath, STATEFUL_PRIMITIVES_BY_NAME);
|
|
43
|
+
// PLAN §5.2 step 1: the pipeline starts with tsc programmatic-API
|
|
44
|
+
// typechecking against `@invinite-org/chartlang-core`'s ambient
|
|
45
|
+
// declarations. Surface every semantic error coming from the
|
|
46
|
+
// user's source file under the stable `type-error` code. Shim
|
|
47
|
+
// diagnostics are dropped — they always come from the synthetic
|
|
48
|
+
// core.d.ts and would only ever signal a chartlang-side bug.
|
|
49
|
+
const semanticDiagnostics = program
|
|
50
|
+
.getSemanticDiagnostics(sourceFile)
|
|
51
|
+
.filter((d) => d.file?.fileName === sourceFile.fileName)
|
|
52
|
+
.map((d) => mapTsDiagnostic(d, sourcePath));
|
|
53
|
+
const earlyDiagnostics = [
|
|
54
|
+
...semanticDiagnostics,
|
|
55
|
+
...structural.diagnostics,
|
|
56
|
+
...forbidden,
|
|
57
|
+
...statefulInLoop,
|
|
58
|
+
];
|
|
59
|
+
const hasError = earlyDiagnostics.some((d) => d.severity === "error");
|
|
60
|
+
if (hasError) {
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
transformed: sourceFile,
|
|
63
|
+
manifest: buildManifest({
|
|
64
|
+
name: structural.name,
|
|
65
|
+
kind: structural.kind,
|
|
66
|
+
capabilities: ["indicators"],
|
|
67
|
+
requestedIntervals: [],
|
|
68
|
+
userPickableInterval: false,
|
|
69
|
+
seriesCapacities: {},
|
|
70
|
+
maxLookback: 0,
|
|
71
|
+
inputs: {},
|
|
72
|
+
...structural.overrides,
|
|
73
|
+
}),
|
|
74
|
+
diagnostics: Object.freeze(earlyDiagnostics.slice()),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const injection = injectCallsiteIds(sourceFile, checker, {
|
|
78
|
+
sourcePath,
|
|
79
|
+
statefulByName: STATEFUL_PRIMITIVES_BY_NAME,
|
|
80
|
+
});
|
|
81
|
+
const capabilities = extractCapabilities(sourceFile, checker, structural.kind);
|
|
82
|
+
const lookback = extractMaxLookback(sourceFile, checker, sourcePath);
|
|
83
|
+
const inputs = extractInputs(sourceFile, checker, sourcePath);
|
|
84
|
+
const alertConditions = extractAlertConditions(sourceFile, checker, sourcePath);
|
|
85
|
+
const intervalDiagnostics = [];
|
|
86
|
+
const requestedIntervalsFromCalls = extractRequestedIntervals(sourceFile, checker, inputs.inputs, intervalDiagnostics, sourcePath);
|
|
87
|
+
const requiresIntervals = extractRequiresIntervals(sourceFile, checker, intervalDiagnostics, sourcePath);
|
|
88
|
+
const lowerTfDiagnostics = validateLowerTfIntervals(sourceFile, checker, sourcePath, opts.declaredIntervals ?? []);
|
|
89
|
+
const requestedIntervals = Array.from(new Set([...requestedIntervalsFromCalls, ...requiresIntervals])).sort();
|
|
90
|
+
const { requiresIntervals: structuralRequiresIntervals, ...structuralOverrides } = structural.overrides;
|
|
91
|
+
void structuralRequiresIntervals;
|
|
92
|
+
const manifest = buildManifest({
|
|
93
|
+
name: structural.name,
|
|
94
|
+
kind: structural.kind,
|
|
95
|
+
capabilities,
|
|
96
|
+
requestedIntervals,
|
|
97
|
+
userPickableInterval: inputs.userPickableInterval,
|
|
98
|
+
seriesCapacities: lookback.seriesCapacities,
|
|
99
|
+
maxLookback: lookback.maxLookback,
|
|
100
|
+
inputs: inputs.inputs,
|
|
101
|
+
...structuralOverrides,
|
|
102
|
+
...(requiresIntervals.length === 0 ? {} : { requiresIntervals }),
|
|
103
|
+
...(alertConditions.alertConditions.length === 0
|
|
104
|
+
? {}
|
|
105
|
+
: { alertConditions: alertConditions.alertConditions }),
|
|
106
|
+
});
|
|
107
|
+
const allDiagnostics = [
|
|
108
|
+
...earlyDiagnostics,
|
|
109
|
+
...injection.diagnostics,
|
|
110
|
+
...lookback.diagnostics,
|
|
111
|
+
...inputs.diagnostics,
|
|
112
|
+
...alertConditions.diagnostics,
|
|
113
|
+
...intervalDiagnostics,
|
|
114
|
+
...lowerTfDiagnostics,
|
|
115
|
+
];
|
|
116
|
+
return Object.freeze({
|
|
117
|
+
transformed: injection.transformed,
|
|
118
|
+
manifest,
|
|
119
|
+
diagnostics: Object.freeze(allDiagnostics.slice()),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Error thrown by `compile` / `compileFile` / `compileProject` when any
|
|
124
|
+
* compilation produces an error-severity diagnostic. Carries the full
|
|
125
|
+
* frozen diagnostic array on `err.diagnostics`; the message starts with the
|
|
126
|
+
* first diagnostic's `code: message (file:line:column)` so console output
|
|
127
|
+
* stays compact.
|
|
128
|
+
*
|
|
129
|
+
* @since 0.1
|
|
130
|
+
* @example
|
|
131
|
+
* // try { await compile(badSrc, { apiVersion: 1 }); }
|
|
132
|
+
* // catch (err) { if (err instanceof CompileError) console.error(err.diagnostics); }
|
|
133
|
+
* const E: typeof CompileError = CompileError;
|
|
134
|
+
* void E;
|
|
135
|
+
*/
|
|
136
|
+
export class CompileError extends Error {
|
|
137
|
+
diagnostics;
|
|
138
|
+
constructor(diagnostics) {
|
|
139
|
+
const first = diagnostics[0];
|
|
140
|
+
const message = first === undefined
|
|
141
|
+
? "Compilation failed"
|
|
142
|
+
: `${first.code}: ${first.message} (${first.file}:${first.line}:${first.column})`;
|
|
143
|
+
super(message);
|
|
144
|
+
this.name = "CompileError";
|
|
145
|
+
this.diagnostics = diagnostics;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const PRINTER = ts.createPrinter({
|
|
149
|
+
removeComments: false,
|
|
150
|
+
newLine: ts.NewLineKind.LineFeed,
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* Compile a script source into a frozen `CompiledScript` triple. Runs
|
|
154
|
+
* `transformAndAnalyse`, throws `CompileError` on any error diagnostic,
|
|
155
|
+
* prints the transformed AST, drives esbuild to ESM, appends the
|
|
156
|
+
* `__manifest` assignment, and emits the `.d.ts` sibling.
|
|
157
|
+
*
|
|
158
|
+
* @since 0.1
|
|
159
|
+
* @example
|
|
160
|
+
* // const result = await compile(emaCrossSource, {
|
|
161
|
+
* // apiVersion: 1,
|
|
162
|
+
* // sourcePath: "ema-cross.chart.ts",
|
|
163
|
+
* // });
|
|
164
|
+
* const fn: typeof compile = compile;
|
|
165
|
+
* void fn;
|
|
166
|
+
*/
|
|
167
|
+
export async function compile(source, opts) {
|
|
168
|
+
const sourcePath = opts.sourcePath ?? "script.chart.ts";
|
|
169
|
+
const result = transformAndAnalyse(source, {
|
|
170
|
+
sourcePath,
|
|
171
|
+
...(opts.declaredIntervals === undefined
|
|
172
|
+
? {}
|
|
173
|
+
: { declaredIntervals: opts.declaredIntervals }),
|
|
174
|
+
});
|
|
175
|
+
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
176
|
+
if (errors.length > 0) {
|
|
177
|
+
throw new CompileError(Object.freeze(errors.slice()));
|
|
178
|
+
}
|
|
179
|
+
const transformedSource = PRINTER.printFile(result.transformed);
|
|
180
|
+
const sourcemap = opts.sourcemap ?? false;
|
|
181
|
+
const bundle = await bundleModule({
|
|
182
|
+
transformedSource,
|
|
183
|
+
sourcePath,
|
|
184
|
+
sourcemap,
|
|
185
|
+
minify: opts.minify ?? false,
|
|
186
|
+
});
|
|
187
|
+
const moduleSource = `${bundle.moduleSource}${formatManifestAssignment(result.manifest)}`;
|
|
188
|
+
const types = emitTypes({ manifest: result.manifest, sourcePath });
|
|
189
|
+
if (bundle.sourcemap !== undefined) {
|
|
190
|
+
return Object.freeze({
|
|
191
|
+
moduleSource,
|
|
192
|
+
sourcemap: bundle.sourcemap,
|
|
193
|
+
manifest: result.manifest,
|
|
194
|
+
types,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return Object.freeze({
|
|
198
|
+
moduleSource,
|
|
199
|
+
manifest: result.manifest,
|
|
200
|
+
types,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Write a file atomically — render to a `<target>.tmp.<rand>` sibling first,
|
|
205
|
+
* then `rename` into place. On any error during write or rename, the temp
|
|
206
|
+
* file is unlinked so the caller never sees a half-written artefact.
|
|
207
|
+
*
|
|
208
|
+
* @since 0.1
|
|
209
|
+
* @example
|
|
210
|
+
* // await writeAtomic("/tmp/foo.txt", "hello");
|
|
211
|
+
* const fn: typeof writeAtomic = writeAtomic;
|
|
212
|
+
* void fn;
|
|
213
|
+
*/
|
|
214
|
+
export async function writeAtomic(target, contents) {
|
|
215
|
+
const suffix = randomBytes(8).toString("hex");
|
|
216
|
+
const tmp = `${target}.tmp.${suffix}`;
|
|
217
|
+
try {
|
|
218
|
+
await writeFile(tmp, contents, "utf8");
|
|
219
|
+
await rename(tmp, target);
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
try {
|
|
223
|
+
await unlink(tmp);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Best-effort cleanup; the rename failure is the real error.
|
|
227
|
+
}
|
|
228
|
+
throw err;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Read a `.chart.ts` file from disk, compile it, and (when `write !== false`)
|
|
233
|
+
* emit the three sibling files atomically — `<base>.chart.js`,
|
|
234
|
+
* `<base>.chart.manifest.json`, `<base>.chart.d.ts`, plus
|
|
235
|
+
* `<base>.chart.js.map` when `sourcemap` is external.
|
|
236
|
+
*
|
|
237
|
+
* @since 0.1
|
|
238
|
+
* @example
|
|
239
|
+
* // const result = await compileFile("./demo.chart.ts", { apiVersion: 1 });
|
|
240
|
+
* const fn: typeof compileFile = compileFile;
|
|
241
|
+
* void fn;
|
|
242
|
+
*/
|
|
243
|
+
export async function compileFile(path, opts) {
|
|
244
|
+
const absolute = isAbsolute(path) ? path : resolvePath(process.cwd(), path);
|
|
245
|
+
const source = await readFile(absolute, "utf8");
|
|
246
|
+
const sourcePath = opts.sourcePath ?? toPosixRelative(process.cwd(), absolute);
|
|
247
|
+
const compileOpts = stripWriteFlag({ ...opts, sourcePath });
|
|
248
|
+
const result = await compile(source, compileOpts);
|
|
249
|
+
if (opts.write === false) {
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
const base = absolute.replace(/\.chart\.ts$/, "");
|
|
253
|
+
const jsPath = `${base}.chart.js`;
|
|
254
|
+
const manifestPath = `${base}.chart.manifest.json`;
|
|
255
|
+
const dtsPath = `${base}.chart.d.ts`;
|
|
256
|
+
await writeAtomic(jsPath, result.moduleSource);
|
|
257
|
+
await writeAtomic(manifestPath, JSON.stringify(result.manifest, null, 4));
|
|
258
|
+
await writeAtomic(dtsPath, result.types);
|
|
259
|
+
if ((opts.sourcemap === true || opts.sourcemap === "external") &&
|
|
260
|
+
result.sourcemap !== undefined) {
|
|
261
|
+
await writeAtomic(`${jsPath}.map`, result.sourcemap);
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Walk `rootDir` recursively and return every `*.chart.ts` file's absolute
|
|
267
|
+
* path. Skips `node_modules` and `dist` subtrees. The walker is iterative to
|
|
268
|
+
* stay portable across Node 20.1 → 20.x.
|
|
269
|
+
*
|
|
270
|
+
* @since 0.1
|
|
271
|
+
* @example
|
|
272
|
+
* // const files = await walkChartFiles("./examples/scripts");
|
|
273
|
+
* const fn: typeof walkChartFiles = walkChartFiles;
|
|
274
|
+
* void fn;
|
|
275
|
+
*/
|
|
276
|
+
export async function walkChartFiles(rootDir) {
|
|
277
|
+
const absolute = isAbsolute(rootDir) ? rootDir : resolvePath(process.cwd(), rootDir);
|
|
278
|
+
const out = [];
|
|
279
|
+
const queue = [absolute];
|
|
280
|
+
for (;;) {
|
|
281
|
+
const current = queue.shift();
|
|
282
|
+
if (current === undefined)
|
|
283
|
+
break;
|
|
284
|
+
let entries;
|
|
285
|
+
try {
|
|
286
|
+
entries = await readDirEntries(current);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
for (const entry of entries) {
|
|
292
|
+
if (entry.name === "node_modules" || entry.name === "dist")
|
|
293
|
+
continue;
|
|
294
|
+
const full = join(current, entry.name);
|
|
295
|
+
if (entry.isDirectory) {
|
|
296
|
+
queue.push(full);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (entry.isFile && full.endsWith(".chart.ts")) {
|
|
300
|
+
out.push(full);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
out.sort();
|
|
305
|
+
return out;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Discover every `*.chart.ts` under `rootDir` and compile each in parallel.
|
|
309
|
+
* Results are returned in deterministic (path-sorted) order so callers can
|
|
310
|
+
* snapshot the array safely. Compilation runs in memory only — the CLI
|
|
311
|
+
* (Phase-1 Task 11) loops `compileFile` when it needs sibling files on disk.
|
|
312
|
+
*
|
|
313
|
+
* @since 0.1
|
|
314
|
+
* @example
|
|
315
|
+
* // const all = await compileProject("./examples/scripts", { apiVersion: 1 });
|
|
316
|
+
* const fn: typeof compileProject = compileProject;
|
|
317
|
+
* void fn;
|
|
318
|
+
*/
|
|
319
|
+
export async function compileProject(rootDir, opts) {
|
|
320
|
+
const files = await walkChartFiles(rootDir);
|
|
321
|
+
const compiled = await Promise.all(files.map((file) => compileFile(file, {
|
|
322
|
+
...opts,
|
|
323
|
+
write: false,
|
|
324
|
+
sourcePath: toPosixRelative(process.cwd(), file),
|
|
325
|
+
})));
|
|
326
|
+
return Object.freeze(compiled);
|
|
327
|
+
}
|
|
328
|
+
function toPosixRelative(cwd, absolute) {
|
|
329
|
+
return relative(cwd, absolute).replace(/\\/g, "/");
|
|
330
|
+
}
|
|
331
|
+
async function readDirEntries(dir) {
|
|
332
|
+
const raw = await readdir(dir, { withFileTypes: true });
|
|
333
|
+
return raw.map((entry) => Object.freeze({
|
|
334
|
+
name: entry.name,
|
|
335
|
+
isDirectory: entry.isDirectory(),
|
|
336
|
+
isFile: entry.isFile(),
|
|
337
|
+
}));
|
|
338
|
+
}
|
|
339
|
+
function stripWriteFlag(opts) {
|
|
340
|
+
const { apiVersion, sourcePath, sourcemap, minify, target, declaredIntervals } = opts;
|
|
341
|
+
const out = { apiVersion };
|
|
342
|
+
if (sourcePath !== undefined)
|
|
343
|
+
out.sourcePath = sourcePath;
|
|
344
|
+
if (sourcemap !== undefined)
|
|
345
|
+
out.sourcemap = sourcemap;
|
|
346
|
+
if (minify !== undefined)
|
|
347
|
+
out.minify = minify;
|
|
348
|
+
if (target !== undefined)
|
|
349
|
+
out.target = target;
|
|
350
|
+
if (declaredIntervals !== undefined)
|
|
351
|
+
out.declaredIntervals = declaredIntervals;
|
|
352
|
+
return out;
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/bundle.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ScriptManifest } from "@invinite-org/chartlang-core";
|
|
2
|
+
/**
|
|
3
|
+
* Options accepted by `bundleModule`. `transformedSource` is the printed text
|
|
4
|
+
* of the callsite-id-injected `ts.SourceFile`; `sourcePath` becomes the
|
|
5
|
+
* sourcemap `sourcefile` field; `sourcemap` mirrors the compile API contract;
|
|
6
|
+
* `minify` toggles esbuild's minifier.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.1
|
|
9
|
+
* @example
|
|
10
|
+
* const opts: BundleModuleOptions = {
|
|
11
|
+
* transformedSource: "export default {};",
|
|
12
|
+
* sourcePath: "demo.chart.ts",
|
|
13
|
+
* sourcemap: false,
|
|
14
|
+
* minify: false,
|
|
15
|
+
* };
|
|
16
|
+
*/
|
|
17
|
+
export type BundleModuleOptions = Readonly<{
|
|
18
|
+
transformedSource: string;
|
|
19
|
+
sourcePath: string;
|
|
20
|
+
sourcemap: boolean | "inline" | "external";
|
|
21
|
+
minify: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Result of `bundleModule`. `moduleSource` is the ESM output; `sourcemap` is
|
|
25
|
+
* the external map JSON when `sourcemap === true | "external"` and omitted
|
|
26
|
+
* when `sourcemap === false | "inline"`. Inline sourcemaps land inside
|
|
27
|
+
* `moduleSource` as a base64 `sourceMappingURL` comment.
|
|
28
|
+
*
|
|
29
|
+
* @since 0.1
|
|
30
|
+
* @example
|
|
31
|
+
* const result: BundleModuleResult = { moduleSource: "export default {};" };
|
|
32
|
+
* void result;
|
|
33
|
+
*/
|
|
34
|
+
export type BundleModuleResult = Readonly<{
|
|
35
|
+
moduleSource: string;
|
|
36
|
+
sourcemap?: string;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Drive esbuild's `build` API against an in-memory transformed TS source and
|
|
40
|
+
* emit a self-contained ESM bundle. Pinned flags: `bundle: true`,
|
|
41
|
+
* `loader: "ts"`, `format: "esm"`, `target: "es2022"`, `treeShaking: true`,
|
|
42
|
+
* `platform: "neutral"`. Bare specifiers like
|
|
43
|
+
* `@invinite-org/chartlang-core` resolve through the compiler package's own
|
|
44
|
+
* `node_modules/` (i.e. `resolveDir` is fixed to the compiler package dir),
|
|
45
|
+
* so the output has zero remaining `import` statements and can load from a
|
|
46
|
+
* `data:` URL inside any host (worker / QuickJS / Node) without a module
|
|
47
|
+
* resolver. Output is ~5–50 KB unminified per PLAN §5.2.
|
|
48
|
+
*
|
|
49
|
+
* @since 0.1
|
|
50
|
+
* @example
|
|
51
|
+
* // const { moduleSource } = await bundleModule({
|
|
52
|
+
* // transformedSource: "export default {};",
|
|
53
|
+
* // sourcePath: "demo.chart.ts",
|
|
54
|
+
* // sourcemap: false,
|
|
55
|
+
* // minify: false,
|
|
56
|
+
* // });
|
|
57
|
+
* const fn: typeof bundleModule = bundleModule;
|
|
58
|
+
* void fn;
|
|
59
|
+
*/
|
|
60
|
+
export declare function bundleModule(opts: BundleModuleOptions): Promise<BundleModuleResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Synthesise the bottom-of-bundle `export const __manifest = …;` assignment.
|
|
63
|
+
* The runtime reads this constant via dynamic `import(...)` to recover the
|
|
64
|
+
* frozen `ScriptManifest` that travels alongside the compiled JS. Serialised
|
|
65
|
+
* via `JSON.stringify` for determinism (insertion-order key emission).
|
|
66
|
+
*
|
|
67
|
+
* @since 0.1
|
|
68
|
+
* @example
|
|
69
|
+
* // const line = formatManifestAssignment(manifest);
|
|
70
|
+
* // line === 'export const __manifest = {"apiVersion":1,…};\n'
|
|
71
|
+
* const fn: typeof formatManifestAssignment = formatManifestAssignment;
|
|
72
|
+
* void fn;
|
|
73
|
+
*/
|
|
74
|
+
export declare function formatManifestAssignment(manifest: ScriptManifest): string;
|
|
75
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC3C,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAOH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgDzF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEzE"}
|