-
Notifications
You must be signed in to change notification settings - Fork 0
/
esbuild-plugin-scriptable.ts
83 lines (72 loc) · 2.44 KB
/
esbuild-plugin-scriptable.ts
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
import { readFile, writeFile } from 'fs/promises';
import { dirname, resolve } from 'path';
import type { Plugin } from 'esbuild';
import { merge as _merge } from 'lodash-es';
import * as pkg from '../package.json' assert { type: 'json' };
export type DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : T;
export type ScriptableMetadata = {
always_run_in_app: boolean;
icon: {
color: string;
glyph: string;
};
name: string;
script: string;
share_sheet_inputs: string[];
};
export type ScriptablePluginOptions = {
scriptfile: string;
outfile?: string;
package?: string | DeepPartial<ScriptableMetadata>;
};
export const prepareScriptable = (options: ScriptablePluginOptions): Plugin => ({
name: 'esbuild-plugin-scriptable',
setup(build) {
build.onEnd(async results => {
// do not go on if there are errors
if (results.errors.length > 0) return;
// given package data can be set inline or as file
let packageData: DeepPartial<ScriptableMetadata> | undefined;
if (options.package) {
// assume a file path
if (typeof options.package === 'string') {
const rawPackageData = await readFile(resolve(options.package), 'utf-8');
packageData = JSON.parse(`${rawPackageData}`);
}
// assume inline data
else {
packageData = options.package;
}
}
// prepare target
const scriptName = packageData?.name ?? pkg.name;
let { outdir, outfile } = build.initialOptions;
let target: string;
if (options.outfile) {
target = resolve(options.outfile);
} else if (outdir) {
target = resolve(outdir, `${scriptName}.scriptable`);
} else if (outfile) {
target = resolve(dirname(outfile), `${scriptName}.scriptable`);
} else {
throw new Error('No output file could be determined');
}
// prepare package
const script = await readFile(resolve(options.scriptfile), 'utf-8');
const packageDefaults: ScriptableMetadata = {
always_run_in_app: false,
icon: {
color: 'deep-blue',
glyph: 'magic'
},
name: pkg.name,
script,
share_sheet_inputs: []
};
// build metadata
const scriptable: ScriptableMetadata = _merge({}, packageDefaults, packageData);
// write package to target
return writeFile(target, JSON.stringify(scriptable, null, 2));
});
}
});