aboutsummaryrefslogtreecommitdiff
path: root/src/options.zig
blob: 9106fbdf6eea42ed88428690481cbbc158f4a06e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const std = @import("std");
const log = @import("logger.zig");
const fs = @import("fs.zig");
const alloc = @import("alloc.zig");

usingnamespace @import("strings.zig");

const assert = std.debug.assert;

pub const Loader = enum {
    jsx,
    js,
    ts,
    tsx,
    css,
    file,
    json,
};

pub const defaultLoaders = std.ComptimeStringMap(Loader, .{
    .{ ".jsx", Loader.jsx },
    .{ ".json", Loader.json },
    .{ ".js", Loader.js },
    .{ ".mjs", Loader.js },
    .{ ".css", Loader.css },
    .{ ".ts", Loader.ts },
    .{ ".tsx", Loader.tsx },
});

pub const JSX = struct {
    parse: bool = true,
    factory: string = "createElement",
    fragment: string = "Fragment",
    jsx: string = "jsxDEV",
    runtime: Runtime = Runtime.automatic,
    development: bool = true,

    /// Set on a per file basis like this:
    /// /** @jsxImportSource @emotion/core */
    import_source: string = "react",

    pub const Runtime = enum { classic, automatic };
};

const TypeScript = struct {
    parse: bool = false,
};

pub const TransformOptions = struct {
    footer: string = "",
    banner: string = "",
    define: std.StringHashMap(string),
    loader: Loader = Loader.tsx,
    resolve_dir: string = "/",
    jsx_factory: string = "React.createElement",
    jsx_fragment: string = "Fragment",
    jsx_import_source: string = "react",
    ts: bool = true,
    react_fast_refresh: bool = false,
    inject: ?[]string = null,
    public_url: string = "/",
    filesystem_cache: std.StringHashMap(fs.File),
    entry_point: fs.File,
    resolve_paths: bool = false,

    pub fn initUncached(allocator: *std.mem.Allocator, entryPointName: string, code: string) !TransformOptions {
        assert(entryPointName.len > 0);

        var filesystemCache = std.StringHashMap(fs.File).init(allocator);

        var entryPoint = fs.File{
            .path = fs.Path.init(entryPointName),
            .contents = code,
        };

        var define = std.StringHashMap(string).init(allocator);
        try define.ensureCapacity(1);

        define.putAssumeCapacity("process.env.NODE_ENV", "development");

        var loader = Loader.file;
        if (defaultLoaders.get(entryPoint.path.name.ext)) |defaultLoader| {
            loader = defaultLoader;
        }

        assert(loader != .file);
        assert(code.len > 0);
        try filesystemCache.put(entryPointName, entryPoint);

        return TransformOptions{
            .entry_point = entryPoint,
            .define = define,
            .loader = loader,
            .filesystem_cache = filesystemCache,
            .resolve_dir = entryPoint.path.name.dir,
        };
    }
};

pub const OutputFile = struct {
    path: []u8,
    contents: []u8,
};

pub const TransformResult = struct { errors: []log.Msg, warnings: []log.Msg, output_files: []OutputFile };

test "TransformOptions.initUncached" {
    try alloc.setup(std.heap.page_allocator);
    const opts = try TransformOptions.initUncached(alloc.dynamic, "lol.jsx", "<Hi />");

    std.testing.expectEqualStrings("lol", opts.entry_point.path.name.base);
    std.testing.expectEqualStrings(".jsx", opts.entry_point.path.name.ext);
    std.testing.expect(Loader.jsx == opts.loader);
}