Skip to content

Commit 104377c

Browse files
authored
Add dynamic loader to compiled autocomplete specs (#360)
1 parent 14d7cf8 commit 104377c

File tree

19 files changed

+388
-171
lines changed

19 files changed

+388
-171
lines changed

.husky/pre-commit

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
#!/usr/bin/env sh
2-
. "$(dirname -- "$0")/_/husky.sh"
3-
42
pnpm pre-commit

cli/publish-spec/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"homepage": "https://github.com/withfig/autocomplete-tools#readme",
4848
"dependencies": {
4949
"commander": "^11.1.0",
50-
"esbuild": "^0.23.1",
50+
"esbuild": "^0.24.2",
5151
"node-fetch": "^3.3.2",
5252
"prettier": "^3.3.3",
5353
"prompts": "^2.4.2"

cli/tools-cli/.eslintrc.cjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
rules: {
3+
"import/no-unresolved": "off",
4+
},
5+
};

cli/tools-cli/README.md

Lines changed: 2 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,3 @@
1-
<p align="center">
2-
<img width="300" src="https://github.com/withfig/fig/blob/main/static/FigBanner.png?raw=true"/>
3-
</p>
1+
# `@withfig/autocomplete-tools`
42

5-
---
6-
7-
![os](https://img.shields.io/badge/os-%20macOS-light)
8-
[![Signup](https://img.shields.io/badge/signup-private%20beta-blueviolet)](https://fig.io?ref=github_autocomplete)
9-
[![Documentation](https://img.shields.io/badge/documentation-black)](https://fig.io/docs/)
10-
[![Discord](https://img.shields.io/discord/837809111248535583?color=768ad4&label=discord)](https://fig.io/community)
11-
[![Twitter](https://img.shields.io/twitter/follow/fig.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=fig)
12-
13-
14-
# Fig Autocomplete Boilerplate Repo
15-
16-
Looking to build [Fig](https://fig.io) autocomplete for private CLI tools, scripts, or NPM packages? This npx module makes it easy to **build** [Fig autocomplete specs](https://fig.io/docs) and **share** them specs with your team.
17-
18-
This repo is similar to a minimal version of our public specs repo,
19-
[withfig/autocomplete](https://github.com/withfig/autocomplete), except with an empty `src/` folder.
20-
21-
22-
23-
## Usage
24-
25-
### Init the .fig folder
26-
27-
Go to the directory that contains your CLI tool, script, or NPM package and run the following
28-
29-
```bash
30-
npx @withfig/autocomplete-tools init
31-
```
32-
This will create initialise a `.fig/` folder in your current working directory like the following
33-
```bash
34-
cli/
35-
├── .fig/
36-
│   └── autocomplete/
37-
│   ├── src/ # where you edit your completion specs
38-
│   ├── build/ # where your specs compile to
39-
│   ├── .eslintrc.js
40-
│   ├── README.md
41-
│   ├── package-lock.json
42-
│   ├── package.json
43-
│   └── tsconfig.json
44-
├── node_mod/
45-
└── my_cli_tool.sh
46-
```
47-
48-
### Create, test, and compile specs
49-
50-
`cd` into the `.fig/autocomplete/` folder and run the remaining commands as package.json scripts
51-
52-
```bash
53-
# Make a new empty completion spec object in src/
54-
npm run create-spec
55-
56-
# Start dev mode to see live updates to your spec in your terminal as you edit.
57-
npm run dev
58-
59-
# Compile your specs from the src/ folder to build/
60-
npm run build
61-
```
62-
63-
### Push Specs to Fig's Cloud
64-
Coming soon
65-
66-
## Documentation
67-
68-
- [Building your first autocomplete spec](https://fig.io/docs/)
69-
- [Personal shortcut autocomplete](https://fig.io/docs/tutorials/visual-shortcuts)
70-
- [Autocomplete for teams / internal CLI tools](https://fig.io/docs/tutorials/building-internal-clis)
71-
- [Autocomplete for local scripts](https://fig.io/docs/tutorials/autocomplete-for-internal-scripts)
72-
73-
74-
## 😊 Need Help?
75-
76-
77-
78-
<p align="center">
79-
Join our community
80-
<br/>
81-
<a href="https://fig.io/community">
82-
<img src="http://fig.io/icons/discord-logo-square.png" width="80px" height="80px" />
83-
</a>
84-
</p>
3+
The `@withfig/autocomplete-tools` is a CLI used to build and manage the withfig/autocomplete repo.

cli/tools-cli/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
{
22
"name": "@withfig/autocomplete-tools",
3-
"version": "2.10.0",
3+
"version": "2.11.0",
44
"description": "Command line tools for working with fig autocomplete specs",
55
"author": "The Fig Team",
66
"scripts": {
77
"build": "rm -rf build/ && pnpm run build:bin && pnpm run build:lib",
8-
"build:bin": "esbuild src/bin.ts --bundle --platform=node --packages=external --outdir=build --minify",
8+
"build:bin": "esbuild src/bin.ts --bundle --platform=node --packages=external --outdir=build --minify --format=esm",
99
"build:lib": "tsc",
1010
"test": "tsx test/index.ts",
1111
"test:overwrite": "OVERWRITE=true pnpm test",
1212
"prepack": "pnpm build",
1313
"generate-spec": "tsx generate-spec.ts generate-fig-spec"
1414
},
1515
"license": "MIT",
16+
"type": "module",
1617
"bin": "./build/bin.js",
1718
"main": "./build/index.js",
1819
"types": "./build/index.d.ts",
@@ -24,11 +25,11 @@
2425
"@fig/autocomplete-helpers": "workspace:^",
2526
"@fig/autocomplete-merge": "workspace:^",
2627
"@types/semver": "^7.5.8",
27-
"chalk": "^4.1.2",
28+
"chalk": "^5.4.1",
2829
"chokidar": "^4.0.1",
29-
"commander": "^11.1.0",
30+
"commander": "^13.0.0",
3031
"create-completion-spec": "workspace:^",
31-
"esbuild": "^0.23.1",
32+
"esbuild": "^0.24.2",
3233
"fast-glob": "^3.3.2",
3334
"module-from-string": "^3.3.1",
3435
"prettier": "^3.3.3",

cli/tools-cli/src/scripts/compile.ts

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import fs from "node:fs/promises";
2+
import fsSync from "node:fs";
3+
import path from "node:path";
14
import { build } from "esbuild";
25
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
36
import chokidar from "chokidar";
47
import { Command } from "commander";
58
import glob from "fast-glob";
6-
import fs from "node:fs/promises";
7-
import path from "node:path";
89
import SpecLogger, { Level } from "./log";
910
import { setSetting } from "./settings";
1011

@@ -33,33 +34,55 @@ async function generateIndex(outdir: string, files: string[]) {
3334
.concat(diffVersionedSpecNames);
3435
specNames.sort();
3536

36-
await fs.mkdir(outdir, { recursive: true });
37+
const modules = files
38+
.filter((p) => fsSync.statSync(p).isFile())
39+
.map(path.parse)
40+
.map((p) => `${p.dir}/${p.name}`.replace(/^src\//, ""));
3741

38-
Promise.all([
39-
// index.js
40-
await fs.writeFile(
41-
path.join(outdir, "index.js"),
42-
`var e=${JSON.stringify(specNames)},diffVersionedCompletions=${JSON.stringify(
43-
diffVersionedSpecNames
44-
)};export{e as default,diffVersionedCompletions};`
45-
),
46-
// index.json
47-
fs.writeFile(
48-
path.join(outdir, "index.json"),
49-
JSON.stringify({
50-
completions: specNames,
51-
diffVersionedCompletions: diffVersionedSpecNames,
52-
})
53-
),
54-
// index.d.ts
55-
fs.writeFile(
56-
path.join(outdir, "index.d.ts"),
57-
`declare const completions: string[]
42+
await fs.mkdir(outdir, { recursive: true });
43+
await fs.mkdir(path.join(outdir, "dynamic"), { recursive: true });
44+
45+
// index.js
46+
await fs.writeFile(
47+
path.join(outdir, "index.js"),
48+
`var e=${JSON.stringify(specNames)},diffVersionedCompletions=${JSON.stringify(
49+
diffVersionedSpecNames
50+
)};export{e as default,diffVersionedCompletions};`
51+
);
52+
// index.json
53+
await fs.writeFile(
54+
path.join(outdir, "index.json"),
55+
JSON.stringify({
56+
completions: specNames,
57+
diffVersionedCompletions: diffVersionedSpecNames,
58+
})
59+
);
60+
// index.d.ts
61+
await fs.writeFile(
62+
path.join(outdir, "index.d.ts"),
63+
`declare const completions: string[]
5864
declare const diffVersionedCompletions: string[]
5965
export { completions as default, diffVersionedCompletions }
60-
`
61-
),
62-
]);
66+
`
67+
);
68+
// dynamic/index.js
69+
await fs.writeFile(
70+
path.join(outdir, "dynamic/index.js"),
71+
`var e={${modules
72+
.map((mod) => `${JSON.stringify(mod)}:()=>import(${JSON.stringify(`../${mod}.js`)})`)
73+
.join(",")}};export{e as default};`
74+
);
75+
// dynamic/index.d.ts
76+
await fs.writeFile(
77+
path.join(outdir, "dynamic/index.d.ts"),
78+
`declare const completions: {
79+
[key: string]: () => Promise<{
80+
default: any;
81+
}>
82+
}
83+
export { completions as default }
84+
`
85+
);
6386
}
6487

6588
/**

cli/tools-cli/src/scripts/create-spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import path from "node:path";
2+
import readline from "node:readline";
13
import { createCompletionSpec } from "create-completion-spec";
24
import { Command } from "commander";
3-
import readline from "readline";
4-
import path from "path";
55
import chalk from "chalk";
66

77
const program = new Command("create-spec")

cli/tools-cli/src/scripts/dev.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import os from "os";
2-
import fs from "fs";
3-
import path from "path";
1+
import os from "node:os";
2+
import fs from "node:fs";
3+
import path from "node:path";
44
import chalk from "chalk";
55
import { Command } from "commander";
66
import { runCompiler } from "./compile";

cli/tools-cli/src/scripts/merge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import fs from "fs";
1+
import fs from "node:fs";
22
import { Command, Option } from "commander";
33
import { merge, presets, PresetName } from "@fig/autocomplete-merge";
44

cli/tools-cli/src/scripts/version.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
import fs from "node:fs";
2+
import path from "node:path";
13
import { Command } from "commander";
24
import semver from "semver";
35
import { applySpecDiff, diffSpecs } from "@fig/autocomplete-helpers";
46
import { importFromStringSync } from "module-from-string";
57
import prettier from "prettier";
6-
import fs from "fs";
78
import ts from "typescript";
89
import { build } from "esbuild";
9-
import path from "path";
1010

1111
export const copyDirectorySync = (oldPath: string, newPath: string) => {
1212
if (!fs.existsSync(newPath)) {

0 commit comments

Comments
 (0)