applescript-node 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.
@@ -0,0 +1,787 @@
1
+ import type { ExprBuilder } from './expressions.js';
2
+ /**
3
+ * Utility type to expand and prettify complex types for better IDE tooltips.
4
+ * Forces TypeScript to display the full expanded type instead of showing type aliases.
5
+ * Handles arrays, objects, and primitives correctly.
6
+ */
7
+ export type Prettify<T> = T extends T[] ? Prettify<T>[] : T extends object ? {
8
+ [K in keyof T]: T[K];
9
+ } : T;
10
+ export interface OsaScriptOptions {
11
+ language?: 'AppleScript' | 'JavaScript';
12
+ humanReadable?: boolean;
13
+ errorToStdout?: boolean;
14
+ }
15
+ export type ScriptExecutionResult<T = unknown> = {
16
+ success: true;
17
+ output?: Prettify<T>;
18
+ error?: undefined;
19
+ exitCode: number;
20
+ } | {
21
+ success: false;
22
+ output?: Prettify<T>;
23
+ error: string;
24
+ exitCode: number;
25
+ };
26
+ export interface WindowInfo {
27
+ name: string;
28
+ index: number;
29
+ bounds?: {
30
+ x: number;
31
+ y: number;
32
+ width: number;
33
+ height: number;
34
+ };
35
+ minimized: boolean;
36
+ zoomed: boolean;
37
+ }
38
+ export interface ProcessInfo {
39
+ name: string;
40
+ bundleId?: string;
41
+ visible: boolean;
42
+ frontmost: boolean;
43
+ }
44
+ export type AppleScriptPrimitive = string | number | boolean | null;
45
+ export type AppleScriptValue = AppleScriptPrimitive | {
46
+ [key: string]: AppleScriptValue;
47
+ } | AppleScriptValue[];
48
+ /**
49
+ * Map AppleScript type names to TypeScript types.
50
+ */
51
+ type AppleScriptTypeToTS<T extends string> = T extends 'string' ? string : T extends 'text' ? string : T extends 'integer' ? number : T extends 'real' ? number : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'date' ? string : string;
52
+ /**
53
+ * Infer TypeScript type from AppleScript property name.
54
+ * Common boolean properties and patterns are mapped to boolean type.
55
+ * Pattern matching includes:
56
+ * - Properties ending in 'able' (capability/state)
57
+ * - Properties ending in 'ed' (past tense/state)
58
+ * - Common boolean properties
59
+ */
60
+ type InferTypeFromPropertyName<T extends string> = T extends `${string}able` ? boolean : T extends `${string}ed` ? boolean : T extends 'shared' | 'password protected' | 'passwordProtected' | 'company' | 'isCompany' | 'visible' | 'frontmost' | 'floating' | 'modal' ? boolean : string;
61
+ /**
62
+ * Normalize a property definition to its runtime value type.
63
+ * Extracts the TypeScript type from PropertyExtractor's asType field.
64
+ * Simple string properties infer type from property name.
65
+ */
66
+ type NormalizeProperty<T> = T extends string ? InferTypeFromPropertyName<T> : T extends {
67
+ property: unknown;
68
+ } ? T extends {
69
+ asType: infer TType extends string;
70
+ } ? AppleScriptTypeToTS<TType> : string : never;
71
+ /**
72
+ * Helper type to infer the shape of objects returned by returnAsJson and mapToJson.
73
+ * Intelligently infers TypeScript types from PropertyExtractor's asType field.
74
+ * Simple string properties default to string type.
75
+ *
76
+ * @example
77
+ * // Simple properties default to string
78
+ * type Result1 = JsonObjectShape<{ id: 'id', name: 'name' }>;
79
+ * // Result: { id: string, name: string }
80
+ *
81
+ * @example
82
+ * // PropertyExtractor without asType defaults to string
83
+ * type Result2 = JsonObjectShape<{
84
+ * id: 'id',
85
+ * email: { property: string, firstOf: true }
86
+ * }>;
87
+ * // Result: { id: string, email: string }
88
+ *
89
+ * @example
90
+ * // PropertyExtractor with asType infers the correct TypeScript type
91
+ * type Result3 = JsonObjectShape<{
92
+ * name: 'name',
93
+ * created: {
94
+ * property: (e: ExprBuilder<never>) => string;
95
+ * ifExists: true;
96
+ * asType: 'string';
97
+ * },
98
+ * count: {
99
+ * property: 'count',
100
+ * asType: 'integer';
101
+ * }
102
+ * }>;
103
+ * // Result: { name: string, created: string, count: number }
104
+ */
105
+ export type JsonObjectShape<T extends Record<string, string | {
106
+ readonly property?: string | ((e: ExprBuilder) => string);
107
+ readonly firstOf?: boolean;
108
+ readonly ifExists?: boolean;
109
+ readonly asType?: string;
110
+ readonly default?: string | ((e: ExprBuilder) => string);
111
+ }>> = Prettify<{
112
+ [K in keyof T]: NormalizeProperty<T[K]>;
113
+ }>;
114
+ /**
115
+ * Property extractor descriptor for advanced field transformations in mapToJson.
116
+ * Allows specifying how to extract and transform individual properties.
117
+ *
118
+ * @example
119
+ * // Simple string property (used as-is)
120
+ * { name: 'name' }
121
+ *
122
+ * @example
123
+ * // First item from collection or default
124
+ * { email: { property: (e) => e.property('aPerson', 'emails'), firstOf: true } }
125
+ *
126
+ * @example
127
+ * // Property with existence check and type conversion
128
+ * { birthday: { property: 'birth date', ifExists: true, asType: 'string' as const, default: 'missing value' } }
129
+ */
130
+ export interface PropertyExtractor<TType extends string = string> {
131
+ /**
132
+ * The property expression to extract.
133
+ * Can be a string (e.g., 'name', 'emails') or an ExprBuilder callback.
134
+ */
135
+ property: string | ((e: ExprBuilder) => string);
136
+ /**
137
+ * If true, gets the first item from the collection or uses default value if empty.
138
+ * Uses setFirstOf() internally.
139
+ */
140
+ firstOf?: boolean;
141
+ /**
142
+ * If true, checks if the property exists before extracting it.
143
+ * Uses setIfExists() internally.
144
+ */
145
+ ifExists?: boolean;
146
+ /**
147
+ * Optional type conversion (e.g., 'string', 'integer', 'text').
148
+ * Only applies when if Exists is true.
149
+ * Use `as const` to preserve the literal type: asType: 'string' as const
150
+ */
151
+ asType?: TType;
152
+ /**
153
+ * Default value to use if property is missing or empty.
154
+ * Defaults to 'missing value' if not specified.
155
+ */
156
+ default?: string | ((e: ExprBuilder) => string);
157
+ }
158
+ export interface ApplicationTarget {
159
+ name: string;
160
+ bundleId?: string;
161
+ }
162
+ export interface ScriptError {
163
+ message: string;
164
+ line?: number;
165
+ column?: number;
166
+ source?: string;
167
+ }
168
+ export interface TypeInfo {
169
+ type: string;
170
+ list?: boolean;
171
+ }
172
+ export interface Parameter {
173
+ name: string;
174
+ code: string;
175
+ type: TypeInfo;
176
+ optional?: boolean;
177
+ description?: string;
178
+ }
179
+ export interface Property {
180
+ name: string;
181
+ code: string;
182
+ type: TypeInfo;
183
+ access: 'r' | 'rw';
184
+ description?: string;
185
+ }
186
+ export interface Element {
187
+ type: string;
188
+ access?: 'r' | 'rw';
189
+ }
190
+ export interface Enumerator {
191
+ name: string;
192
+ code: string;
193
+ description?: string;
194
+ }
195
+ export interface Enumeration {
196
+ name: string;
197
+ code: string;
198
+ enumerators: Enumerator[];
199
+ }
200
+ export interface Command {
201
+ name: string;
202
+ code: string;
203
+ description?: string;
204
+ directParameter?: TypeInfo & {
205
+ description?: string;
206
+ };
207
+ parameters: Parameter[];
208
+ result?: TypeInfo & {
209
+ description?: string;
210
+ };
211
+ }
212
+ export interface Class {
213
+ name: string;
214
+ code: string;
215
+ description?: string;
216
+ plural?: string;
217
+ inherits?: string;
218
+ properties: Property[];
219
+ elements: Element[];
220
+ }
221
+ export interface Suite {
222
+ name: string;
223
+ code: string;
224
+ description?: string;
225
+ classes: Class[];
226
+ commands: Command[];
227
+ enumerations: Enumeration[];
228
+ }
229
+ export interface ApplicationDictionary {
230
+ suites: Suite[];
231
+ }
232
+ /**
233
+ * ScriptBuilder with generic type tracking for variable scope and return type.
234
+ *
235
+ * @template TScope - Union of variable names available in the current scope.
236
+ * Starts as `never` and is extended by loop methods and variable assignments.
237
+ * @template TReturn - The return type of the script when executed.
238
+ * Defaults to `unknown` and is set by methods like `returnAsJson()`.
239
+ *
240
+ * @example
241
+ * // Variable scope tracking
242
+ * createScript()
243
+ * .set('counter', 0)
244
+ * .forEach('aPerson', 'every person', (b) => {
245
+ * // Both 'counter' and 'aPerson' are in scope
246
+ * b.ifThen((e) => e.gte('counter', 50), ...)
247
+ * })
248
+ *
249
+ * @example
250
+ * // Return type inference
251
+ * const script = createScript()
252
+ * .tell('Contacts')
253
+ * .returnAsJson('results', {
254
+ * id: 'id',
255
+ * name: 'name',
256
+ * email: 'email',
257
+ * })
258
+ * .endtell();
259
+ *
260
+ * // Type is inferred: Array<{ id: unknown; name: unknown; email: unknown }>
261
+ * const result = await runScript(script);
262
+ * console.log(result.output[0].name); // TypeScript knows this exists!
263
+ */
264
+ export interface ScriptBuilder<TScope extends string = never, TReturn = unknown> {
265
+ tell: (target: string) => ScriptBuilder<TScope, TReturn>;
266
+ tellTarget: (target: string) => ScriptBuilder<TScope, TReturn>;
267
+ tellProcess: (processName: string) => ScriptBuilder<TScope, TReturn>;
268
+ end: () => ScriptBuilder<TScope, TReturn>;
269
+ endif: () => ScriptBuilder<TScope, TReturn>;
270
+ endrepeat: () => ScriptBuilder<TScope, TReturn>;
271
+ endtry: () => ScriptBuilder<TScope, TReturn>;
272
+ endtell: () => ScriptBuilder<TScope, TReturn>;
273
+ endon: () => ScriptBuilder<TScope, TReturn>;
274
+ endto: () => ScriptBuilder<TScope, TReturn>;
275
+ endrun: () => ScriptBuilder<TScope, TReturn>;
276
+ endquit: () => ScriptBuilder<TScope, TReturn>;
277
+ endopen: () => ScriptBuilder<TScope, TReturn>;
278
+ endidle: () => ScriptBuilder<TScope, TReturn>;
279
+ endconsidering: () => ScriptBuilder<TScope, TReturn>;
280
+ endignoring: () => ScriptBuilder<TScope, TReturn>;
281
+ endusing: () => ScriptBuilder<TScope, TReturn>;
282
+ endwith: () => ScriptBuilder<TScope, TReturn>;
283
+ if: (condition: string | ((expr: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope, TReturn>;
284
+ thenBlock: () => ScriptBuilder<TScope, TReturn>;
285
+ else: () => ScriptBuilder<TScope, TReturn>;
286
+ elseIf: (condition: string) => ScriptBuilder<TScope, TReturn>;
287
+ repeat: (times?: number) => ScriptBuilder<TScope, TReturn>;
288
+ repeatWith: <TNewVar extends string>(variable: TNewVar, list: string) => ScriptBuilder<TScope | TNewVar, TReturn>;
289
+ repeatUntil: (condition: string) => ScriptBuilder<TScope, TReturn>;
290
+ repeatWhile: (condition: string) => ScriptBuilder<TScope, TReturn>;
291
+ repeatWithRange: <TNewVar extends string>(variable: TNewVar, start: number | string, end: number | string) => ScriptBuilder<TScope | TNewVar, TReturn>;
292
+ exitRepeat: () => ScriptBuilder<TScope, TReturn>;
293
+ exitRepeatIf: (condition: string | ((expr: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope, TReturn>;
294
+ continueRepeat: () => ScriptBuilder<TScope, TReturn>;
295
+ on: (handlerName: string, parameters?: string[]) => ScriptBuilder<TScope, TReturn>;
296
+ to: (handlerName: string, parameters?: string[]) => ScriptBuilder<TScope, TReturn>;
297
+ callHandler: (handlerName: string, parameters?: string[]) => ScriptBuilder<TScope, TReturn>;
298
+ my: (handlerName: string, parameters?: string[]) => ScriptBuilder<TScope, TReturn>;
299
+ ofMe: (handlerName: string, parameters?: string[]) => ScriptBuilder<TScope, TReturn>;
300
+ onLabeled: (handlerName: string, labeledParams: Record<string, string>) => ScriptBuilder<TScope, TReturn>;
301
+ toLabeled: (handlerName: string, labeledParams: Record<string, string>) => ScriptBuilder<TScope, TReturn>;
302
+ runHandler: (explicit?: boolean) => ScriptBuilder<TScope, TReturn>;
303
+ quitHandler: () => ScriptBuilder<TScope, TReturn>;
304
+ openHandler: (parameterName?: string) => ScriptBuilder<TScope, TReturn>;
305
+ idleHandler: (returnSeconds?: number) => ScriptBuilder<TScope, TReturn>;
306
+ considering: (attributes: string[]) => ScriptBuilder<TScope, TReturn>;
307
+ ignoring: (attributes: string[]) => ScriptBuilder<TScope, TReturn>;
308
+ using: (terms: string[]) => ScriptBuilder<TScope, TReturn>;
309
+ with: (timeout?: number, transaction?: boolean) => ScriptBuilder<TScope, TReturn>;
310
+ try: () => ScriptBuilder<TScope, TReturn>;
311
+ onError: (variableName?: string) => ScriptBuilder<TScope, TReturn>;
312
+ error: (message: string, number?: number) => ScriptBuilder<TScope, TReturn>;
313
+ return: (value: AppleScriptValue) => ScriptBuilder<TScope, TReturn>;
314
+ returnRaw: (expression: string) => ScriptBuilder<TScope, TReturn>;
315
+ buildJsonObject: (variableMap: Record<string, string>) => string;
316
+ /**
317
+ * Return a single JSON object from variables.
318
+ * Sets the return type to the shape of the object.
319
+ *
320
+ * @template TProperties - Property map type (inferred)
321
+ */
322
+ returnJsonObject: <TProperties extends Record<string, string>>(variableMap: TProperties) => ScriptBuilder<TScope, JsonObjectShape<TProperties>>;
323
+ /**
324
+ * Return a list of records as a JSON array.
325
+ * Sets the return type to an array of objects with the shape of the property map.
326
+ *
327
+ * @template TProperties - Property map type (inferred)
328
+ * @param listVariable - Variable containing the list of records
329
+ * @param propertyMap - Mapping of JSON keys to AppleScript properties
330
+ * @returns Builder with return type set to Array<JsonObjectShape<TProperties>>
331
+ *
332
+ * @example
333
+ * const script = createScript()
334
+ * .tell('Contacts')
335
+ * .returnAsJson('results', {
336
+ * id: 'id',
337
+ * name: 'name',
338
+ * email: 'email',
339
+ * })
340
+ * .endtell();
341
+ *
342
+ * // Type is inferred as: Array<{ id: string; name: string; email: string }>
343
+ * const result = await runScript(script);
344
+ * result.output[0].name; // TypeScript knows 'name' exists!
345
+ */
346
+ returnAsJson: <TProperties extends Record<string, string>>(listVariable: string, propertyMap: TProperties) => ScriptBuilder<TScope, JsonObjectShape<TProperties>[]>;
347
+ /**
348
+ * Map a collection to JSON with automatic iteration, property extraction, and type inference.
349
+ * Sets the return type to an array of objects with the shape of the properties map.
350
+ *
351
+ * Supports advanced property extractors for field-level transformations:
352
+ * - Simple strings for direct property access
353
+ * - PropertyExtractor objects for firstOf, ifExists, and type conversion
354
+ *
355
+ * @template TProperties - Property map type (inferred)
356
+ *
357
+ * @example
358
+ * // Simple properties
359
+ * .mapToJson('aPerson', 'every person', {
360
+ * id: 'id',
361
+ * name: 'name'
362
+ * })
363
+ *
364
+ * @example
365
+ * // Advanced field extractors
366
+ * .mapToJson('aPerson', 'every person', {
367
+ * id: 'id',
368
+ * name: 'name',
369
+ * email: { property: (e) => e.property('aPerson', 'emails'), firstOf: true },
370
+ * birthday: { property: 'birth date', ifExists: true, asType: 'string' }
371
+ * }, { limit: 50, skipErrors: true })
372
+ */
373
+ mapToJson: <TProperties extends Record<string, string | {
374
+ readonly property?: string | ((e: ExprBuilder) => string);
375
+ readonly firstOf?: boolean;
376
+ readonly ifExists?: boolean;
377
+ readonly asType?: string;
378
+ readonly default?: string | ((e: ExprBuilder) => string);
379
+ }>>(itemVariable: string, collection: string, properties: TProperties, options?: {
380
+ limit?: number;
381
+ until?: string | ((expr: ExprBuilder<TScope>) => string);
382
+ while?: string | ((expr: ExprBuilder<TScope>) => string);
383
+ skipErrors?: boolean;
384
+ }) => ScriptBuilder<TScope, JsonObjectShape<TProperties>[]>;
385
+ log: (message: string) => ScriptBuilder<TScope, TReturn>;
386
+ comment: (text: string) => ScriptBuilder<TScope, TReturn>;
387
+ tellApp: (appName: string, block: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
388
+ ifThen: (condition: string | ((expr: ExprBuilder<TScope>) => string), thenBlock: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
389
+ ifThenElse: (condition: string | ((expr: ExprBuilder<TScope>) => string), thenBlock: (builder: ScriptBuilder<TScope, TReturn>) => void, elseBlock: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
390
+ tryCatch: (tryBlock: (builder: ScriptBuilder<TScope, TReturn>) => void, catchBlock: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
391
+ tryCatchError: (tryBlock: (builder: ScriptBuilder<TScope, TReturn>) => void, errorVarName: string, catchBlock: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
392
+ /**
393
+ * Iterate over a list with a loop variable, executing a block for each item.
394
+ *
395
+ * This is a generic method that extends the type scope. The loop variable `TNewVar`
396
+ * is added to the scope within the callback, enabling TypeScript autocomplete.
397
+ *
398
+ * @template TNewVar - The name of the loop variable (inferred from first parameter)
399
+ * @param variable - Loop variable name (will be added to scope)
400
+ * @param list - AppleScript list expression to iterate over
401
+ * @param block - Callback that receives a builder with extended scope (TScope | TNewVar)
402
+ * @returns Builder instance for method chaining
403
+ *
404
+ * @example
405
+ * .forEach('aPerson', 'every person', (b) => {
406
+ * // 'aPerson' is now in scope
407
+ * b.setExpression('name', (e) => e.property('aPerson', 'name'));
408
+ * b.setExpression('email', (e) => e.valueOfItem(1, e.property('aPerson', 'emails')));
409
+ * })
410
+ *
411
+ * @example
412
+ * // Nested loops with multiple scoped variables
413
+ * .forEach('anAccount', 'every account', (outer) => {
414
+ * outer.forEach('aNote', 'notes of anAccount', (inner) => {
415
+ * // Both 'anAccount' and 'aNote' are in scope
416
+ * inner.setExpression('accountName', (e) => e.property('anAccount', 'name'));
417
+ * inner.setExpression('noteName', (e) => e.property('aNote', 'name'));
418
+ * });
419
+ * })
420
+ */
421
+ forEach: <TNewVar extends string>(variable: TNewVar, list: string, block: (builder: ScriptBuilder<TScope | TNewVar, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
422
+ /**
423
+ * Iterate over a list while a condition is true.
424
+ *
425
+ * This is a generic method that extends the type scope. The loop variable is added
426
+ * to the scope, and the condition callback also receives the extended scope.
427
+ *
428
+ * @template TNewVar - The name of the loop variable (inferred from first parameter)
429
+ * @param variable - Loop variable name (will be added to scope)
430
+ * @param list - AppleScript list expression to iterate over
431
+ * @param condition - Condition to check before each iteration (string or callback with scoped ExprBuilder)
432
+ * @param block - Callback that receives a builder with extended scope
433
+ * @returns Builder instance for method chaining
434
+ *
435
+ * @example
436
+ * .forEachWhile(
437
+ * 'aPerson',
438
+ * 'matchingPeople',
439
+ * (e) => e.exists(e.property('aPerson', 'email')), // 'aPerson' in scope
440
+ * (b) => {
441
+ * b.setExpression('email', (e) =>
442
+ * e.valueOfItem(1, e.property('aPerson', 'emails')) // 'aPerson' in scope
443
+ * );
444
+ * }
445
+ * )
446
+ */
447
+ forEachWhile: <TNewVar extends string>(variable: TNewVar, list: string, condition: string | ((expr: ExprBuilder<TScope | TNewVar>) => string), block: (builder: ScriptBuilder<TScope | TNewVar, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
448
+ /**
449
+ * Iterate over a list until a condition becomes true (then exit loop).
450
+ *
451
+ * This is a generic method that extends the type scope. The loop variable is added
452
+ * to the scope, and both the condition callback and block callback receive the extended scope.
453
+ *
454
+ * @template TNewVar - The name of the loop variable (inferred from first parameter)
455
+ * @param variable - Loop variable name (will be added to scope)
456
+ * @param list - AppleScript list expression to iterate over
457
+ * @param condition - Exit condition (loop stops when this becomes true)
458
+ * @param block - Callback that receives a builder with extended scope
459
+ * @returns Builder instance for method chaining
460
+ *
461
+ * @example
462
+ * .set('counter', 0)
463
+ * .forEachUntil(
464
+ * 'aPerson',
465
+ * 'matchingPeople',
466
+ * (e) => e.gte('counter', 50), // Exit when counter >= 50
467
+ * (b) => {
468
+ * b.increment('counter');
469
+ * b.ifThen(
470
+ * (e) => e.gt(e.count(e.property('aPerson', 'emails')), 0), // 'aPerson' in scope
471
+ * (then_) => then_.setExpression('email', (e) =>
472
+ * e.valueOfItem(1, e.property('aPerson', 'emails'))
473
+ * )
474
+ * );
475
+ * }
476
+ * )
477
+ */
478
+ forEachUntil: <TNewVar extends string>(variable: TNewVar, list: string, condition: string | ((expr: ExprBuilder<TScope | TNewVar>) => string), block: (builder: ScriptBuilder<TScope | TNewVar, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
479
+ repeatTimes: (times: number, block: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
480
+ repeatWhileBlock: (condition: string, block: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
481
+ repeatUntilBlock: (condition: string, block: (builder: ScriptBuilder<TScope, TReturn>) => void) => ScriptBuilder<TScope, TReturn>;
482
+ activate: () => ScriptBuilder<TScope, TReturn>;
483
+ quit: () => ScriptBuilder<TScope, TReturn>;
484
+ reopen: () => ScriptBuilder<TScope, TReturn>;
485
+ launch: () => ScriptBuilder<TScope, TReturn>;
486
+ running: () => ScriptBuilder<TScope, TReturn>;
487
+ getRunningApplications: () => ScriptBuilder<TScope, TReturn>;
488
+ getFrontmostApplication: () => ScriptBuilder<TScope, TReturn>;
489
+ activateApplication: (appName: string) => ScriptBuilder<TScope, TReturn>;
490
+ hideApplication: (appName: string) => ScriptBuilder<TScope, TReturn>;
491
+ unhideApplication: (appName: string) => ScriptBuilder<TScope, TReturn>;
492
+ quitApplication: (appName: string) => ScriptBuilder<TScope, TReturn>;
493
+ isApplicationRunning: (appName: string) => ScriptBuilder<TScope, TReturn>;
494
+ getApplicationInfo: (appName: string) => ScriptBuilder<TScope, TReturn>;
495
+ closeWindow: (window?: string) => ScriptBuilder<TScope, TReturn>;
496
+ closeAllWindows: () => ScriptBuilder<TScope, TReturn>;
497
+ minimizeWindow: (window?: string) => ScriptBuilder<TScope, TReturn>;
498
+ zoomWindow: (window?: string) => ScriptBuilder<TScope, TReturn>;
499
+ getWindowInfo: (appName: string, windowName?: string) => ScriptBuilder<TScope, TReturn>;
500
+ getAllWindows: (appName: string) => ScriptBuilder<TScope, TReturn>;
501
+ getFrontmostWindow: (appName: string) => ScriptBuilder<TScope, TReturn>;
502
+ setWindowBounds: (appName: string, windowName: string, bounds: {
503
+ x: number;
504
+ y: number;
505
+ width: number;
506
+ height: number;
507
+ }) => ScriptBuilder<TScope, TReturn>;
508
+ moveWindow: (appName: string, windowName: string, x: number, y: number) => ScriptBuilder<TScope, TReturn>;
509
+ resizeWindow: (appName: string, windowName: string, width: number, height: number) => ScriptBuilder<TScope, TReturn>;
510
+ arrangeWindows: (arrangement: 'cascade' | 'tile' | 'stack') => ScriptBuilder<TScope, TReturn>;
511
+ focusWindow: (appName: string, windowName: string) => ScriptBuilder<TScope, TReturn>;
512
+ switchToWindow: (appName: string, windowName: string) => ScriptBuilder<TScope, TReturn>;
513
+ click: (target: string) => ScriptBuilder<TScope, TReturn>;
514
+ select: (target: string) => ScriptBuilder<TScope, TReturn>;
515
+ keystroke: (text: string, modifiers?: string[]) => ScriptBuilder<TScope, TReturn>;
516
+ keystrokes: (text: string, delayBetween?: number) => ScriptBuilder<TScope, TReturn>;
517
+ delay: (seconds: number) => ScriptBuilder<TScope, TReturn>;
518
+ pressKey: (key: string, modifiers?: ('command' | 'option' | 'control' | 'shift')[]) => ScriptBuilder<TScope, TReturn>;
519
+ pressKeyCode: (keyCode: number, modifiers?: ('command' | 'option' | 'control' | 'shift')[]) => ScriptBuilder<TScope, TReturn>;
520
+ typeText: (text: string) => ScriptBuilder<TScope, TReturn>;
521
+ clickButton: (buttonName: string) => ScriptBuilder<TScope, TReturn>;
522
+ clickMenuItem: (menuName: string, itemName: string) => ScriptBuilder<TScope, TReturn>;
523
+ displayDialog: (text: string, options?: {
524
+ buttons?: string[];
525
+ defaultButton?: string;
526
+ withIcon?: 'stop' | 'note' | 'caution';
527
+ givingUpAfter?: number;
528
+ }) => ScriptBuilder<TScope, TReturn>;
529
+ displayNotification: (text: string, options?: {
530
+ title?: string;
531
+ subtitle?: string;
532
+ sound?: string;
533
+ }) => ScriptBuilder<TScope, TReturn>;
534
+ /**
535
+ * Set a variable to a value and add it to the tracked scope.
536
+ *
537
+ * @template TNewVar - The variable name (inferred from first parameter)
538
+ * @param variable - Variable name to set (will be added to scope)
539
+ * @param value - Value to assign
540
+ * @returns Builder with extended scope including the new variable
541
+ *
542
+ * @example
543
+ * createScript()
544
+ * .set('counter', 0)
545
+ * .set('results', [])
546
+ * .forEachUntil('aNote', 'every note',
547
+ * (e) => e.gte('counter', 50), // 'counter' is in scope!
548
+ * (b) => {
549
+ * b.increment('counter');
550
+ * b.setEndRecord('results', {...}); // 'results' is in scope!
551
+ * }
552
+ * )
553
+ */
554
+ set: <TNewVar extends string>(variable: TNewVar, value: AppleScriptValue) => ScriptBuilder<TScope | TNewVar, TReturn>;
555
+ /**
556
+ * Set a variable to an expression and add it to the tracked scope.
557
+ *
558
+ * @template TNewVar - The variable name (inferred from first parameter)
559
+ * @param variable - Variable name to set (will be added to scope)
560
+ * @param expression - Expression (string, record, or callback)
561
+ * @returns Builder with extended scope including the new variable
562
+ *
563
+ * @example
564
+ * .setExpression('personEmail', (e) =>
565
+ * e.valueOfItem(1, e.property('aPerson', 'emails'))
566
+ * )
567
+ * // Later 'personEmail' is in scope
568
+ */
569
+ setExpression: <TNewVar extends string>(variable: TNewVar, expression: string | Record<string, string> | ((expr: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope | TNewVar, TReturn>;
570
+ setExpressions: (expressions: Record<string, string | ((expr: ExprBuilder<TScope>) => string)>) => ScriptBuilder<TScope, TReturn>;
571
+ appendTo: (variable: string, expression: string | ((expr: ExprBuilder<TScope>) => string), options?: {
572
+ prependLinefeed?: boolean;
573
+ appendLinefeed?: boolean;
574
+ }) => ScriptBuilder<TScope, TReturn>;
575
+ increment: (variable: string, by?: number) => ScriptBuilder<TScope, TReturn>;
576
+ decrement: (variable: string, by?: number) => ScriptBuilder<TScope, TReturn>;
577
+ get: (property: string) => ScriptBuilder<TScope, TReturn>;
578
+ /**
579
+ * Copy a value to a variable and add it to the tracked scope.
580
+ *
581
+ * @template TNewVar - The variable name (inferred from second parameter)
582
+ * @param value - Value to copy
583
+ * @param to - Variable name (will be added to scope)
584
+ * @returns Builder with extended scope including the new variable
585
+ */
586
+ copy: <TNewVar extends string>(value: AppleScriptValue, to: TNewVar) => ScriptBuilder<TScope | TNewVar, TReturn>;
587
+ count: (items: string) => ScriptBuilder<TScope, TReturn>;
588
+ /**
589
+ * Set a variable to the count of items and add it to the tracked scope.
590
+ *
591
+ * @template TNewVar - The variable name (inferred from first parameter)
592
+ * @param variable - Variable name to set (will be added to scope)
593
+ * @param items - Items to count
594
+ * @returns Builder with extended scope including the new variable
595
+ */
596
+ setCountOf: <TNewVar extends string>(variable: TNewVar, items: string) => ScriptBuilder<TScope | TNewVar, TReturn>;
597
+ exists: (item: string) => ScriptBuilder<TScope, TReturn>;
598
+ setEnd: (variable: string, value: AppleScriptValue) => ScriptBuilder<TScope, TReturn>;
599
+ setEndRaw: (variable: string, expression: string | Record<string, string> | ((expr: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope, TReturn>;
600
+ setEndRecord: (listVariable: string, sourceOrExpressions: string | Record<string, string>, propertyMap?: Record<string, string>) => ScriptBuilder<TScope, TReturn>;
601
+ pickEndRecord: (listVariable: string, sourceObject: string, propertyMap: Record<string, string>) => ScriptBuilder<TScope, TReturn>;
602
+ /**
603
+ * Set variable using ternary operator pattern with if-then-else block.
604
+ * Much more concise than manually calling ifThenElse for simple conditional assignments.
605
+ *
606
+ * @template TNewVar - The variable name (inferred from first parameter)
607
+ * @param variable - Variable name to set (will be added to scope)
608
+ * @param condition - Condition to evaluate (string or ExprBuilder callback)
609
+ * @param trueExpression - Expression to use if condition is true
610
+ * @param falseExpression - Expression to use if condition is false
611
+ * @returns Builder with extended scope including the new variable
612
+ *
613
+ * @example
614
+ * // Replaces verbose manual ifThenElse calls for simple assignments
615
+ * .setTernary('personEmail',
616
+ * (e) => e.gt(e.count(e.property('aPerson', 'emails')), 0),
617
+ * (e) => e.valueOfItem(1, e.property('aPerson', 'emails')),
618
+ * 'missing value'
619
+ * )
620
+ * // Generates an if-then-else block that conditionally sets personEmail
621
+ */
622
+ setTernary: <TNewVar extends string>(variable: TNewVar, condition: string | ((e: ExprBuilder<TScope>) => string), trueExpression: string | ((e: ExprBuilder<TScope>) => string), falseExpression: string | ((e: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope | TNewVar, TReturn>;
623
+ /**
624
+ * Append to list using ternary operator pattern with if-then-else block.
625
+ * Combines setEndRaw with conditional logic for ultra-concise syntax.
626
+ *
627
+ * @param listVariable - Name of the list to append to
628
+ * @param condition - Condition to evaluate (string or ExprBuilder callback)
629
+ * @param trueExpression - Expression to append if condition is true
630
+ * @param falseExpression - Expression to append if condition is false
631
+ * @returns Builder instance for method chaining
632
+ *
633
+ * @example
634
+ * // Conditionally append different values based on condition
635
+ * .forEach('item', 'every file of desktop', (loop) =>
636
+ * loop.setEndTernary('results',
637
+ * (e) => e.gt(e.property('item', 'size'), 1000000),
638
+ * '"large"',
639
+ * '"small"'
640
+ * )
641
+ * )
642
+ * // Generates an if-then-else block that conditionally appends to results
643
+ */
644
+ setEndTernary: (listVariable: string, condition: string | ((e: ExprBuilder<TScope>) => string), trueExpression: string | ((e: ExprBuilder<TScope>) => string), falseExpression: string | ((e: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope, TReturn>;
645
+ /**
646
+ * Set variable to first item of collection or default value if collection is empty.
647
+ * Ultra-shorthand for the common "first or default" pattern.
648
+ *
649
+ * Automatically generates: `set variable to (if count of collection > 0 then value of item 1 of collection else defaultValue)`
650
+ *
651
+ * @template TNewVar - The variable name (inferred from first parameter)
652
+ * @param variable - Variable name to set (will be added to scope)
653
+ * @param collection - Collection expression (string or ExprBuilder callback)
654
+ * @param defaultValue - Value to use if collection is empty (defaults to 'missing value')
655
+ * @returns Builder with extended scope including the new variable
656
+ *
657
+ * @example
658
+ * // OLD WAY: Verbose ternary with explicit condition
659
+ * .setTernary('personEmail',
660
+ * (e) => e.gt(e.count(e.property('aPerson', 'emails')), 0),
661
+ * (e) => e.valueOfItem(1, e.property('aPerson', 'emails')),
662
+ * 'missing value'
663
+ * )
664
+ *
665
+ * // NEW WAY: Ultra-concise first-or-default
666
+ * .setFirstOf('personEmail', (e) => e.property('aPerson', 'emails'))
667
+ *
668
+ * @example
669
+ * // With custom default value
670
+ * .setFirstOf('userEmail', 'emailAddresses', '"noreply@example.com"')
671
+ */
672
+ setFirstOf: <TNewVar extends string>(variable: TNewVar, collection: string | ((e: ExprBuilder<TScope>) => string), defaultValue?: string | ((e: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope | TNewVar, TReturn>;
673
+ /**
674
+ * Append first item of collection or default value to a list.
675
+ * Ultra-shorthand for the common "first or default" pattern in list building.
676
+ *
677
+ * Automatically generates: `set end of list to (if count of collection > 0 then value of item 1 of collection else defaultValue)`
678
+ *
679
+ * @param listVariable - Name of the list to append to
680
+ * @param collection - Collection expression (string or ExprBuilder callback)
681
+ * @param defaultValue - Value to append if collection is empty (defaults to 'missing value')
682
+ * @returns Builder instance for method chaining
683
+ *
684
+ * @example
685
+ * // Building a list with first-or-default pattern
686
+ * .set('emailList', [])
687
+ * .forEach('person', 'every person', (loop) =>
688
+ * loop.setEndFirstOf('emailList', (e) => e.property('person', 'emails'))
689
+ * )
690
+ *
691
+ * @example
692
+ * // With custom default
693
+ * .setEndFirstOf('phoneNumbers', 'availablePhones', '"555-0000"')
694
+ */
695
+ setEndFirstOf: (listVariable: string, collection: string | ((e: ExprBuilder<TScope>) => string), defaultValue?: string | ((e: ExprBuilder<TScope>) => string)) => ScriptBuilder<TScope, TReturn>;
696
+ /**
697
+ * Set variable to property value if it exists, otherwise use default value.
698
+ * Ultra-shorthand for the common "take if exists or default" pattern.
699
+ *
700
+ * Automatically generates: `if exists property then set variable to property [as type] else set variable to defaultValue`
701
+ *
702
+ * @template TNewVar - The variable name (inferred from first parameter)
703
+ * @param variable - Variable name to set (will be added to scope)
704
+ * @param property - Property expression to check and retrieve (string or ExprBuilder callback)
705
+ * @param defaultValue - Value to use if property doesn't exist (defaults to 'missing value')
706
+ * @param asType - Optional type to convert property to (e.g., 'string', 'integer')
707
+ * @returns Builder with extended scope including the new variable
708
+ *
709
+ * @example
710
+ * // OLD WAY: Verbose ternary with exists check and type conversion
711
+ * .setTernary('personBirthday',
712
+ * (e) => e.exists(e.property('aPerson', 'birth date')),
713
+ * (e) => e.asType(e.property('aPerson', 'birth date'), 'string'),
714
+ * 'missing value'
715
+ * )
716
+ *
717
+ * // NEW WAY: Ultra-concise if-exists with type conversion
718
+ * .setIfExists('personBirthday',
719
+ * (e) => e.property('aPerson', 'birth date'),
720
+ * 'missing value',
721
+ * 'string'
722
+ * )
723
+ *
724
+ * @example
725
+ * // Even simpler with string expression
726
+ * .setIfExists('personBirthday', 'birth date of aPerson', 'missing value', 'string')
727
+ *
728
+ * @example
729
+ * // Without type conversion
730
+ * .setIfExists('personNote', 'note of aPerson', '""')
731
+ */
732
+ setIfExists: <TNewVar extends string>(variable: TNewVar, property: string | ((e: ExprBuilder<TScope>) => string), defaultValue?: string | ((e: ExprBuilder<TScope>) => string), asType?: string) => ScriptBuilder<TScope | TNewVar, TReturn>;
733
+ /**
734
+ * Append property value to list if it exists, otherwise append default value.
735
+ * Ultra-shorthand for the common "take if exists or default" pattern in list building.
736
+ *
737
+ * Automatically generates: `if exists property then set end of list to property [as type] else set end of list to defaultValue`
738
+ *
739
+ * @param listVariable - Name of the list to append to
740
+ * @param property - Property expression to check and retrieve (string or ExprBuilder callback)
741
+ * @param defaultValue - Value to append if property doesn't exist (defaults to 'missing value')
742
+ * @param asType - Optional type to convert property to (e.g., 'string', 'integer')
743
+ * @returns Builder instance for method chaining
744
+ *
745
+ * @example
746
+ * // Building a list with if-exists pattern
747
+ * .set('birthdayList', [])
748
+ * .forEach('person', 'every person', (loop) =>
749
+ * loop.setEndIfExists('birthdayList',
750
+ * 'birth date of person',
751
+ * '""',
752
+ * 'string'
753
+ * )
754
+ * )
755
+ *
756
+ * @example
757
+ * // With ExprBuilder
758
+ * .setEndIfExists('notes',
759
+ * (e) => e.property('contact', 'note'),
760
+ * 'missing value'
761
+ * )
762
+ */
763
+ setEndIfExists: (listVariable: string, property: string | ((e: ExprBuilder<TScope>) => string), defaultValue?: string | ((e: ExprBuilder<TScope>) => string), asType?: string) => ScriptBuilder<TScope, TReturn>;
764
+ setProperty: (variable: string, property: string, value: AppleScriptValue) => ScriptBuilder<TScope, TReturn>;
765
+ makeRecordFrom: (variableNames: Record<string, string>) => string;
766
+ first: (items: string) => ScriptBuilder<TScope, TReturn>;
767
+ last: (items: string) => ScriptBuilder<TScope, TReturn>;
768
+ rest: (items: string) => ScriptBuilder<TScope, TReturn>;
769
+ reverse: (items: string) => ScriptBuilder<TScope, TReturn>;
770
+ some: (items: string, test: string) => ScriptBuilder<TScope, TReturn>;
771
+ every: (items: string, test: string) => ScriptBuilder<TScope, TReturn>;
772
+ whose: (items: string, condition: string) => string;
773
+ getEvery: (itemType: string, location?: string) => ScriptBuilder<TScope, TReturn>;
774
+ getEveryWhere: (itemType: string, condition: string, location?: string) => ScriptBuilder<TScope, TReturn>;
775
+ offset: (text: string, in_: string) => ScriptBuilder<TScope, TReturn>;
776
+ contains: (text: string, in_: string) => ScriptBuilder<TScope, TReturn>;
777
+ beginsWith: (text: string, with_: string) => ScriptBuilder<TScope, TReturn>;
778
+ endsWith: (text: string, with_: string) => ScriptBuilder<TScope, TReturn>;
779
+ path: (to: string) => ScriptBuilder<TScope, TReturn>;
780
+ info: (for_: string) => ScriptBuilder<TScope, TReturn>;
781
+ do: (script: string) => ScriptBuilder<TScope, TReturn>;
782
+ doShellScript: (command: string, administrator?: boolean) => ScriptBuilder<TScope, TReturn>;
783
+ raw: (script: string) => ScriptBuilder<TScope, TReturn>;
784
+ build: () => string;
785
+ reset: () => ScriptBuilder<TScope, TReturn>;
786
+ }
787
+ export {};