permcraft 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Akif
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,350 @@
1
+ # Permcraft
2
+
3
+ Interactive CLI tool that lets Salesforce developers manage permission set XML files without manually editing XML. Express your permission intent once, and Permcraft applies it across multiple permission sets.
4
+
5
+ ## What it does
6
+
7
+ - Fetches objects and fields from your connected Salesforce org
8
+ - Lets you search and select objects/fields using fuzzy search
9
+ - Assigns object permissions (Read, Create, Edit, Delete, View All, Modify All) and field permissions (Read, Edit)
10
+ - Applies selected permissions to one or more local `.permissionset-meta.xml` files
11
+ - Automatically enforces permission dependencies (e.g., selecting Edit auto-enables Read)
12
+ - Supports two permission modes: **Bulk** (same permissions across all selections) and **Granular** (different permissions per object/field)
13
+ - Never downgrades existing permissions — only adds or upgrades
14
+
15
+ ## Prerequisites
16
+
17
+ - **Node.js** (LTS version)
18
+ - **Salesforce CLI (`sf`)** installed and available in your PATH
19
+ - An **authenticated Salesforce org** connected via `sf org login web`
20
+ - Must be run inside a **Salesforce DX project** (directory containing `sfdx-project.json`)
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ # Clone the repository
26
+ git clone <repo-url>
27
+ cd salesforce-permission-cli
28
+
29
+ # Install dependencies
30
+ npm install
31
+
32
+ # Build
33
+ npm run build
34
+
35
+ # Link globally so "permcraft" is available anywhere
36
+ npm link
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ Navigate to your SFDX project directory and run:
42
+
43
+ ```bash
44
+ permcraft
45
+ ```
46
+
47
+ ### Options
48
+
49
+ ```
50
+ -h, --help Show help message
51
+ -v, --version Show version number
52
+ ```
53
+
54
+ ### Uninstalling
55
+
56
+ To remove the global `permcraft` command:
57
+
58
+ ```bash
59
+ cd /path/to/salesforce-permission-cli
60
+ npm unlink permcraft
61
+ ```
62
+
63
+ ## Walkthrough
64
+
65
+ ### Example 1: Bulk mode — same permissions for multiple objects
66
+
67
+ ```
68
+ $ permcraft
69
+
70
+ Permcraft — Salesforce Permission Set Editor
71
+
72
+ Checking environment...
73
+ Project: /Users/dev/my-sfdx-project
74
+ Org: admin@myorg.com
75
+
76
+ Fetching objects from org...
77
+ Found 847 objects.
78
+
79
+ Start typing to search for an object. Select it to add.
80
+
81
+ ? Search for an object: acc
82
+ Account
83
+ AccountContactRole
84
+ AccountTeamMember
85
+ > Account # user selects Account
86
+
87
+ Added: Account
88
+ ? Add another object? Yes
89
+
90
+ ? Selected: [Account] — Search for another object (or type "done"): cas
91
+ > Case # user selects Case
92
+
93
+ Added: Case
94
+ ? Add another object? No
95
+
96
+ Selected objects: Account, Case
97
+
98
+ Fetching fields for Account...
99
+ Found 72 fields.
100
+
101
+ Start typing to search for a field on Account.
102
+
103
+ ? Search for a field on Account: indus
104
+ > Account.Industry # user selects Industry
105
+
106
+ Added: Account.Industry
107
+ ? Add another field? No
108
+
109
+ Fetching fields for Case...
110
+ Found 58 fields.
111
+
112
+ Start typing to search for a field on Case.
113
+
114
+ ? Search for a field on Case: stat
115
+ > Case.Status # user selects Status
116
+
117
+ Added: Case.Status
118
+ ? Add another field? No
119
+
120
+ ? How would you like to assign permissions?
121
+ > Bulk — same permissions for all selected objects/fields
122
+
123
+ ? Permissions for 2 objects (Account, Case) (Press <space> to select)
124
+ [x] Read
125
+ [x] Create
126
+ [x] Edit
127
+ [ ] Delete
128
+ [ ] View All
129
+ [ ] Modify All
130
+
131
+ ? Permissions for 2 fields (Press <space> to select)
132
+ [x] Read
133
+ [ ] Edit
134
+
135
+ Scanning local permission sets...
136
+ Found 3 permission sets.
137
+
138
+ ? Select permission sets to update (press <space> to select, <enter> to confirm)
139
+ [x] Sales_User
140
+ [x] Support_User
141
+ [ ] Admin
142
+
143
+ --- Preview ---
144
+
145
+ Permission Set: Sales_User
146
+ + Account: Read, Create, Edit
147
+ + Case: Read, Create, Edit
148
+ + Account.Industry: Read
149
+ + Case.Status: Read
150
+
151
+ Permission Set: Support_User
152
+ + Account: Read, Create, Edit
153
+ + Case: Read, Create, Edit
154
+ + Account.Industry: Read
155
+ + Case.Status: Read
156
+
157
+ ? Apply these changes? Yes
158
+
159
+ Applying changes...
160
+
161
+ Updating /Users/dev/my-sfdx-project/force-app/main/default/permissionsets/Sales_User.permissionset-meta.xml
162
+ Updating /Users/dev/my-sfdx-project/force-app/main/default/permissionsets/Support_User.permissionset-meta.xml
163
+
164
+ All changes applied successfully!
165
+ ```
166
+
167
+ ### Example 2: Granular mode — different permissions per object/field
168
+
169
+ ```
170
+ $ permcraft
171
+
172
+ Permcraft — Salesforce Permission Set Editor
173
+
174
+ Checking environment...
175
+ Project: /Users/dev/my-sfdx-project
176
+ Org: admin@myorg.com
177
+
178
+ Fetching objects from org...
179
+ Found 847 objects.
180
+
181
+ Start typing to search for an object. Select it to add.
182
+
183
+ ? Search for an object: Account
184
+ Added: Account
185
+ ? Add another object? Yes
186
+ ? Selected: [Account] — Search for another object (or type "done"): Case
187
+ Added: Case
188
+ ? Add another object? No
189
+
190
+ Selected objects: Account, Case
191
+
192
+ Fetching fields for Account...
193
+ Found 72 fields.
194
+
195
+ Start typing to search for a field on Account.
196
+
197
+ ? Search for a field on Account: Revenue
198
+ Added: Account.AnnualRevenue
199
+ ? Add another field? No
200
+
201
+ Fetching fields for Case...
202
+ Found 58 fields.
203
+
204
+ Start typing to search for a field on Case.
205
+
206
+ ? Search for a field on Case: Priority
207
+ Added: Case.Priority
208
+ ? Add another field? No
209
+
210
+ ? How would you like to assign permissions?
211
+ > Granular — different permissions for each object/field
212
+
213
+ ? Permissions for Account
214
+ [x] Read
215
+ [x] Create
216
+ [x] Edit
217
+ [x] Delete
218
+ [ ] View All
219
+ [ ] Modify All
220
+
221
+ ? Permissions for Case
222
+ [x] Read
223
+ [x] Create
224
+ [ ] Edit
225
+ [ ] Delete
226
+ [ ] View All
227
+ [ ] Modify All
228
+
229
+ ? Permissions for Account.AnnualRevenue
230
+ [x] Read
231
+ [x] Edit
232
+
233
+ ? Permissions for Case.Priority
234
+ [x] Read
235
+ [ ] Edit
236
+
237
+ Scanning local permission sets...
238
+ Found 2 permission sets.
239
+
240
+ ? Select permission sets to update (press <space> to select, <enter> to confirm)
241
+ [x] Sales_User
242
+
243
+ --- Preview ---
244
+
245
+ Permission Set: Sales_User
246
+ + Account: Read, Create, Edit, Delete
247
+ + Case: Read, Create
248
+ + Account.AnnualRevenue: Read, Edit
249
+ + Case.Priority: Read
250
+
251
+ ? Apply these changes? Yes
252
+
253
+ Applying changes...
254
+
255
+ Updating /Users/dev/my-sfdx-project/force-app/main/default/permissionsets/Sales_User.permissionset-meta.xml
256
+
257
+ All changes applied successfully!
258
+ ```
259
+
260
+ ### Example 3: Generated XML output
261
+
262
+ After running permcraft, the permission set XML file is updated cleanly:
263
+
264
+ ```xml
265
+ <?xml version="1.0" encoding="UTF-8"?>
266
+ <PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
267
+ <hasActivationRequired>false</hasActivationRequired>
268
+ <label>Sales_User</label>
269
+ <objectPermissions>
270
+ <allowCreate>true</allowCreate>
271
+ <allowDelete>false</allowDelete>
272
+ <allowEdit>true</allowEdit>
273
+ <allowRead>true</allowRead>
274
+ <modifyAllRecords>false</modifyAllRecords>
275
+ <object>Account</object>
276
+ <viewAllRecords>false</viewAllRecords>
277
+ </objectPermissions>
278
+ <objectPermissions>
279
+ <allowCreate>true</allowCreate>
280
+ <allowDelete>false</allowDelete>
281
+ <allowEdit>false</allowEdit>
282
+ <allowRead>true</allowRead>
283
+ <modifyAllRecords>false</modifyAllRecords>
284
+ <object>Case</object>
285
+ <viewAllRecords>false</viewAllRecords>
286
+ </objectPermissions>
287
+ <fieldPermissions>
288
+ <editable>false</editable>
289
+ <field>Account.Industry</field>
290
+ <readable>true</readable>
291
+ </fieldPermissions>
292
+ </PermissionSet>
293
+ ```
294
+
295
+ ## Permission dependency rules
296
+
297
+ Permcraft automatically enforces Salesforce permission dependencies. When you select a permission, all its prerequisites are auto-enabled:
298
+
299
+ **Object permissions** (each implies all below it):
300
+
301
+ ```
302
+ Modify All → View All → Delete → Edit → Read
303
+ ```
304
+
305
+ **Field permissions:**
306
+
307
+ ```
308
+ Edit → Read
309
+ ```
310
+
311
+ Auto-enabled dependencies are shown in the preview before applying.
312
+
313
+ ## What it supports
314
+
315
+ - Fuzzy search across all org objects and fields
316
+ - Object-level permissions: Read, Create, Edit, Delete, View All, Modify All
317
+ - Field-level permissions: Read, Edit
318
+ - Bulk and granular permission assignment modes
319
+ - Updating existing permission set XML files
320
+ - Creating new permission set XML files (for permission sets that exist in the org but not locally)
321
+ - Preserving existing permissions (never downgrades)
322
+ - Preserving XML formatting and indentation style of existing files
323
+ - Applying permissions across multiple permission sets in a single session
324
+
325
+ ## What it does not support (yet)
326
+
327
+ - Non-interactive / CI mode (flags and arguments for scripting)
328
+ - Tab permissions (TabVisibility)
329
+ - Apex class and Visualforce page access
330
+ - Record type assignments
331
+ - Application visibility
332
+ - Custom permission assignments
333
+ - Removing or revoking permissions
334
+ - Profile metadata editing (only permission sets)
335
+ - Deploying changes to the org (use `sf project deploy start` after running permcraft)
336
+
337
+ ## Development
338
+
339
+ ```bash
340
+ npm install # install dependencies
341
+ npm run build # compile TypeScript
342
+ npm run dev # run without building (uses tsx)
343
+ npm test # run test suite
344
+ npm run lint # lint source files
345
+ npm run format # format source files
346
+ ```
347
+
348
+ ## License
349
+
350
+ MIT
@@ -0,0 +1,9 @@
1
+ import type { ObjectPermissions, FieldPermissions } from './types.js';
2
+ export declare function resolveObjectDependencies(perms: ObjectPermissions): {
3
+ resolved: ObjectPermissions;
4
+ autoEnabled: string[];
5
+ };
6
+ export declare function resolveFieldDependencies(perms: FieldPermissions): {
7
+ resolved: FieldPermissions;
8
+ autoEnabled: string[];
9
+ };
@@ -0,0 +1,51 @@
1
+ // Each key implies all keys listed in its array (transitive dependencies)
2
+ const OBJECT_DEPENDENCY_CHAIN = [
3
+ 'modifyAllRecords',
4
+ 'viewAllRecords',
5
+ 'allowDelete',
6
+ 'allowEdit',
7
+ 'allowRead',
8
+ ];
9
+ export function resolveObjectDependencies(perms) {
10
+ const resolved = { ...perms };
11
+ const autoEnabled = [];
12
+ // Find the highest permission that's enabled, then enable everything below it
13
+ let highestIndex = -1;
14
+ for (let i = 0; i < OBJECT_DEPENDENCY_CHAIN.length; i++) {
15
+ if (resolved[OBJECT_DEPENDENCY_CHAIN[i]]) {
16
+ highestIndex = i;
17
+ break;
18
+ }
19
+ }
20
+ if (highestIndex >= 0) {
21
+ for (let i = highestIndex + 1; i < OBJECT_DEPENDENCY_CHAIN.length; i++) {
22
+ const key = OBJECT_DEPENDENCY_CHAIN[i];
23
+ if (!resolved[key]) {
24
+ resolved[key] = true;
25
+ autoEnabled.push(key);
26
+ }
27
+ }
28
+ }
29
+ // Also handle Edit → Read independently (Edit without Delete should still imply Read)
30
+ if (resolved.allowEdit && !resolved.allowRead) {
31
+ resolved.allowRead = true;
32
+ if (!autoEnabled.includes('allowRead'))
33
+ autoEnabled.push('allowRead');
34
+ }
35
+ if (resolved.allowCreate && !resolved.allowRead) {
36
+ resolved.allowRead = true;
37
+ if (!autoEnabled.includes('allowRead'))
38
+ autoEnabled.push('allowRead');
39
+ }
40
+ return { resolved, autoEnabled };
41
+ }
42
+ export function resolveFieldDependencies(perms) {
43
+ const resolved = { ...perms };
44
+ const autoEnabled = [];
45
+ if (resolved.editable && !resolved.readable) {
46
+ resolved.readable = true;
47
+ autoEnabled.push('readable');
48
+ }
49
+ return { resolved, autoEnabled };
50
+ }
51
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../src/dependencies.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,MAAM,uBAAuB,GAA0B;IACrD,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,WAAW;CACZ,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,KAAwB;IAIhE,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,8EAA8E;IAC9E,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,IAAI,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,YAAY,GAAG,CAAC,CAAC;YACjB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvE,MAAM,GAAG,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACrB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,sFAAsF;IACtF,IAAI,QAAQ,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC9C,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAChD,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAuB;IAI9D,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC5C,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { OrgInfo, SfdxProject } from './types.js';
2
+ export declare function findProjectRoot(startDir?: string): string;
3
+ export declare function readSfdxProject(projectRoot: string): SfdxProject;
4
+ export declare function getPackageDirectories(project: SfdxProject, projectRoot: string): string[];
5
+ export declare function getAuthenticatedOrg(): OrgInfo;
6
+ export declare function validateEnvironment(): {
7
+ projectRoot: string;
8
+ project: SfdxProject;
9
+ org: OrgInfo;
10
+ };
package/dist/env.js ADDED
@@ -0,0 +1,54 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ export function findProjectRoot(startDir = process.cwd()) {
5
+ let dir = startDir;
6
+ while (true) {
7
+ if (existsSync(resolve(dir, 'sfdx-project.json'))) {
8
+ return dir;
9
+ }
10
+ const parent = resolve(dir, '..');
11
+ if (parent === dir) {
12
+ throw new Error('Not inside a Salesforce DX project. No sfdx-project.json found.\n' +
13
+ 'Run this command from within an SFDX project directory.');
14
+ }
15
+ dir = parent;
16
+ }
17
+ }
18
+ export function readSfdxProject(projectRoot) {
19
+ const filePath = resolve(projectRoot, 'sfdx-project.json');
20
+ const content = readFileSync(filePath, 'utf-8');
21
+ return JSON.parse(content);
22
+ }
23
+ export function getPackageDirectories(project, projectRoot) {
24
+ return project.packageDirectories.map((d) => resolve(projectRoot, d.path));
25
+ }
26
+ export function getAuthenticatedOrg() {
27
+ try {
28
+ const result = execSync('sf org display --json', {
29
+ encoding: 'utf-8',
30
+ stdio: ['pipe', 'pipe', 'pipe'],
31
+ });
32
+ const parsed = JSON.parse(result);
33
+ if (parsed.status !== 0) {
34
+ throw new Error(parsed.message || 'Failed to get org info');
35
+ }
36
+ const { username, id: orgId, instanceUrl } = parsed.result;
37
+ return { username, orgId, instanceUrl };
38
+ }
39
+ catch (err) {
40
+ if (err instanceof Error && err.message.includes('No default org found')) {
41
+ throw new Error('No authenticated Salesforce org found.\n' +
42
+ 'Run `sf org login web` or `sf config set target-org <alias>` first.');
43
+ }
44
+ throw new Error('Failed to connect to Salesforce org. Ensure `sf` CLI is installed and you have an authenticated org.\n' +
45
+ `Details: ${err instanceof Error ? err.message : String(err)}`);
46
+ }
47
+ }
48
+ export function validateEnvironment() {
49
+ const projectRoot = findProjectRoot();
50
+ const project = readSfdxProject(projectRoot);
51
+ const org = getAuthenticatedOrg();
52
+ return { projectRoot, project, org };
53
+ }
54
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,UAAU,eAAe,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC9D,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,mEAAmE;gBACjE,yDAAyD,CAC5D,CAAC;QACJ,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAoB,EAAE,WAAmB;IAC7E,OAAO,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,uBAAuB,EAAE;YAC/C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,wBAAwB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CACb,0CAA0C;gBACxC,qEAAqE,CACxE,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CACb,wGAAwG;YACtG,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACjE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};