A TypeScript wrapper for FileMaker FMDeveloperTool command-line utility.
npm install fmdevelopertoolA TypeScript/Node.js wrapper for the FileMaker Developer CLI tool. This library provides a convenient programmatic interface to interact with FileMaker databases from Node.js applications.
``bash`
npm install fmdevelopertool
- 🎯 TypeScript support - Full type definitions for all commands and parameters
- 🚀 Cross-platform - Automatically detects and uses the correct FileMaker Server installation path on Windows, macOS, and Linux
- 📦 Promise-based API - Modern async/await support
- 🔧 Comprehensive - Supports all FileMaker Developer Tool commands
- 🛡️ Type-safe - Catch errors at compile time with TypeScript
FileMaker Server must be installed on your system. The library will automatically detect the installation path based on your platform:
- macOS: /Library/FileMaker Server/Database Server/bin/FMDeveloperToolC:\Program Files\FileMaker\FileMaker Server\Database Server\bin\FMDeveloperTool.exe
- Windows: /opt/FileMaker/FileMaker Server/Database Server/bin/FMDeveloperTool
- Linux:
You can also specify a custom path if your installation differs.
`typescript
import { FMDeveloperTool } from 'fmdevelopertool';
// Create an instance with default settings
const devtool = new FMDeveloperTool();
// Or with custom configuration
const devtool = new FMDeveloperTool({
cliPath: '/custom/path/to/FMDeveloperTool',
defaultUsername: 'Admin',
defaultPassword: 'password123',
verbose: true
});
// Use the tool
async function example() {
// Clone a database
const result = await devtool.clone({
sourceFilename: '/path/to/source.fmp12',
targetFilename: '/path/to/target.fmp12',
encryptionKey: 'mykey'
});
if (result.success) {
console.log('Clone successful!');
console.log(result.stdout);
} else {
console.error('Clone failed:', result.stderr);
}
}
`
`typescript
interface FMDeveloperToolConfig {
// Path to the FMDeveloperTool executable
// If not provided, defaults to platform-specific FileMaker Server installation path
cliPath?: string;
// Default username for FileMaker files (default: 'Admin')
defaultUsername?: string;
// Default password for FileMaker files (default: '')
defaultPassword?: string;
// Enable verbose output by default (default: false)
verbose?: boolean;
// Enable quiet mode by default (default: false)
quiet?: boolean;
// Specify CLI version manually (format: "major.minor.update.build")
// If not provided, version will be auto-detected on first use
version?: string;
// Skip version checking for commands (default: false)
// Use with caution - may cause errors if command is not available
skipVersionCheck?: boolean;
// Callback function called immediately when a process is spawned
// Receives the PID and command name - useful for tracking processes while running
onSpawn?: (pid: number, command: string) => void;
}
`
The library automatically handles version-specific features of the FileMaker Developer Tool. It detects the CLI version and validates command availability before execution.
`typescript
const devtool = new FMDeveloperTool();
// Version is automatically detected on first command
const version = await devtool.getVersion();
console.log(CLI Version: ${version.raw}); // e.g., "22.0.4.427"`
`typescript`
const devtool = new FMDeveloperTool({
version: '22.0.4.427'
});
The library will throw a CommandNotAvailableError if you try to use a command that's not available in your CLI version:
`typescript
import { FMDeveloperTool, CommandNotAvailableError } from 'fmdevelopertool';
const devtool = new FMDeveloperTool();
try {
await devtool.someCommand(params);
} catch (error) {
if (error instanceof CommandNotAvailableError) {
console.error('This command is not available in your CLI version');
console.error(error.message);
// Handle gracefully
}
}
`
`typescript
import { getAvailableCommands } from 'fmdevelopertool';
const devtool = new FMDeveloperTool();
const version = await devtool.getVersion();
const commands = getAvailableCommands(version);
if (commands.includes('uploadDatabases')) {
// Use upload feature
await devtool.uploadDatabases(params);
} else {
// Use alternative approach
console.log('Upload not available, using manual transfer');
}
`
For performance-critical applications where you're certain about command availability:
`typescript`
const devtool = new FMDeveloperTool({
skipVersionCheck: true // Commands execute without version validation
});
Currently supported FileMaker Developer Tool versions:
- 22.0.4.427 - Full feature set
When new versions are released, update the library by adding new documentation to documentation/FMDeveloperTool/ and the library will be updated accordingly.
#### copy(params: CopyParams): Promise
Creates a copy of an FMP12 file with all data.
`typescript`
await devtool.copy({
sourceFilename: 'source.fmp12',
username: 'admin',
password: 'admin',
targetFilename: 'copy.fmp12',
encryptionKey: 'abc'
});
#### clone(params: CloneParams): Promise
Creates a copy of an FMP12 file without data (schema only).
`typescript`
await devtool.clone({
sourceFilename: 'source.fmp12',
targetFilename: 'clone.fmp12'
});
#### copyCompress(params: CopyCompressParams): Promise
Creates a compressed copy of an FMP12 file with all data.
`typescript`
await devtool.copyCompress({
sourceFilename: 'source.fmp12',
targetFilename: 'compressed.fmp12'
});
#### copySelfContained(params: CopySelfContainedParams): Promise
Creates a self-contained copy with all container data embedded.
`typescript`
await devtool.copySelfContained({
sourceFilename: 'source.fmp12',
targetFilename: 'selfcontained.fmp12'
});
#### saveAsXML(params: SaveAsXMLParams): Promise
Creates an XML representation of the schema, layouts, and scripts.
`typescript`
await devtool.saveAsXML({
sourceFilename: 'source.fmp12',
targetFilename: 'output.xml',
includeDDRInfo: true,
pluginFolder: '/path/to/plugins'
});
#### querySize(params: QuerySizeParams): Promise
Queries size information for tables or fields.
`typescript`
await devtool.querySize({
sourceFilename: 'source.fmp12',
targetTablename: 'Product Details',
sizeUnit: 'mb'
});
#### sortBySize(params: SortBySizeParams): Promise
Returns fields sorted by size.
`typescript`
await devtool.sortBySize({
sourceFilename: 'source.fmp12',
targetTablename: 'Product Details',
quantity: 5,
sizeUnit: 'mb',
csvFormat: true
});
#### enableEncryption(params: EnableEncryptionParams): Promise
Encrypts an FMP12 file.
`typescript`
await devtool.enableEncryption({
sourceFilename: 'source.fmp12',
targetFilename: 'encrypted.fmp12',
sharedID: '123',
passcode: 'admin',
passcodeHint: 'hint',
keepOpenStorage: true
});
#### removeEncryption(params: RemoveEncryptionParams): Promise
Decrypts an FMP12 file.
`typescript`
await devtool.removeEncryption({
sourceFilename: 'encrypted.fmp12',
targetFilename: 'decrypted.fmp12',
encryptionKey: 'abc'
});
#### recover(params: RecoverParams): Promise
Recovers a damaged FMP12 file.
`typescript`
await devtool.recover({
sourceFilename: 'damaged.fmp12',
targetFilename: 'recovered.fmp12',
generate: 'rebuild',
rebuildIndex: 'now',
bypass: true,
username: 'admin',
password: 'admin'
});
#### checkConsistency(params: CheckConsistencyParams): Promise
Performs consistency check on an FMP12 file.
`typescript`
await devtool.checkConsistency({
sourceFilename: 'source.fmp12',
encryptionKey: 'abc'
});
#### removeAdminAccess(params: RemoveAdminAccessParams): Promise
Removes Full Access privileges from an FMP12 file.
`typescript`
await devtool.removeAdminAccess({
sourceFilename: 'source.fmp12',
targetFilename: 'no_admin.fmp12'
});
#### enableKiosk(params: EnableKioskParams): Promise
Enables Kiosk mode in an FMP12 file.
`typescript`
await devtool.enableKiosk({
sourceFilename: 'source.fmp12',
targetFilename: 'kiosk.fmp12'
});
#### renameFiles(params: RenameFilesParams): Promise
Renames multiple FMP12 files using regex.
`typescript`
await devtool.renameFiles({
targetFolder: '/target/folder',
sourceFilelist: ['file1.fmp12', 'file2.fmp12'],
regex: 'abc.123',
replaceText: 'abc-123'
});
#### resetFileUUID(params: ResetFileUUIDParams): Promise
Regenerates the unique ID of an FMP12 file.
`typescript`
await devtool.resetFileUUID({
sourceFilename: 'source.fmp12'
});
#### uploadDatabases(params: UploadDatabasesParams): Promise
Uploads databases to a FileMaker Server host.
`typescript`
await devtool.uploadDatabases({
hostName: 'myhost.example.com',
hostUsername: 'admin',
hostPassword: 'password',
databasePathlist: ['db1.fmp12', 'db2.fmp12'],
encryptionKey: 'abc',
targetFolder: 'Secure/',
withoutRemoteContainer: false,
automaticallyOpenDbOff: false
});
#### version(): Promise
Gets the version of the developer tool.
`typescript`
const result = await devtool.version();
console.log(result.stdout);
#### help(): Promise
Displays help information.
`typescript`
const result = await devtool.help();
console.log(result.stdout);
All methods return a CommandResult object:
`typescript`
interface CommandResult {
success: boolean; // true if exitCode === 0
stdout: string; // Standard output from the command
stderr: string; // Standard error from the command
exitCode: number; // Exit code from the process
pid?: number; // Process ID of the spawned command
}
You can access the Process ID (PID) in two ways:
#### 1. In the Result (after completion)
`typescript
const result = await devtool.clone({
sourceFilename: 'source.fmp12',
targetFilename: 'clone.fmp12'
});
console.log(Command executed with PID: ${result.pid});Exit code: ${result.exitCode}
console.log();Success: ${result.success}
console.log();`
#### 2. Immediately on Spawn (while running)
Use the onSpawn callback to access the PID immediately when the process starts:
`typescript
const activePIDs = new Map
const devtool = new FMDeveloperTool({
onSpawn: (pid, command) => {
console.log(Process spawned - PID: ${pid}, Command: ${command});
activePIDs.set(pid, command);
// You can now track, monitor, or manage the process while it's running
// For example: send signals, log to a database, update a UI, etc.
}
});
// The callback fires immediately when the command starts
await devtool.clone({
sourceFilename: 'large_database.fmp12',
targetFilename: 'clone.fmp12'
});
`
This is useful for:
- Real-time process monitoring and tracking
- Logging PIDs to a database or file while commands execute
- Updating UI with active operations
- Managing long-running processes (e.g., sending signals if needed)
- Integration with process management tools
`typescript
import { FMDeveloperTool } from 'fmdevelopertool';
async function processDatabase() {
const devtool = new FMDeveloperTool({
defaultUsername: 'Admin',
defaultPassword: 'admin123',
verbose: true
});
try {
// Check consistency first
console.log('Checking consistency...');
const checkResult = await devtool.checkConsistency({
sourceFilename: '/path/to/database.fmp12',
encryptionKey: 'mykey'
});
if (!checkResult.success) {
console.log('Database has issues, recovering...');
// Recover if needed
const recoverResult = await devtool.recover({
sourceFilename: '/path/to/database.fmp12',
targetFilename: '/path/to/database_recovered.fmp12',
encryptionKey: 'mykey',
generate: 'rebuild',
rebuildIndex: 'now'
});
if (!recoverResult.success) {
throw new Error('Recovery failed: ' + recoverResult.stderr);
}
}
// Create a clone for development
console.log('Creating clone...');
const cloneResult = await devtool.clone({
sourceFilename: '/path/to/database.fmp12',
targetFilename: '/path/to/database_dev.fmp12',
encryptionKey: 'mykey'
});
if (cloneResult.success) {
console.log('Clone created successfully!');
}
// Export schema to XML
console.log('Exporting to XML...');
const xmlResult = await devtool.saveAsXML({
sourceFilename: '/path/to/database.fmp12',
targetFilename: '/path/to/schema.xml',
includeDDRInfo: true
});
console.log('All operations completed!');
} catch (error) {
console.error('Error:', error);
}
}
processDatabase();
`
The library is written in TypeScript and includes comprehensive type definitions. All parameters and return types are fully typed for the best development experience.
- 22.0.4.427 - Current stable version with full feature set
When new versions of the FileMaker Developer Tool are released, the library can be easily updated:
1. Add the new version documentation to documentation/FMDeveloperTool/[version].mdsrc/version.ts
2. Update the version registry in
3. Add any new command type definitions if needed
4. Rebuild the library
See documentation/FMDeveloperTool/README.md for detailed instructions.
`typescript
import {
FMDeveloperTool,
getAvailableCommands,
isCommandAvailable,
parseVersion,
CommandNotAvailableError
} from 'fmdevelopertool';
// Auto-detect version
const devtool = new FMDeveloperTool();
const version = await devtool.getVersion();
// Check available commands
const commands = getAvailableCommands(version);
// Check specific command
if (isCommandAvailable(version, 'uploadDatabases')) {
// Command is available
}
// Handle version errors
try {
await devtool.someCommand(params);
} catch (error) {
if (error instanceof CommandNotAvailableError) {
// Handle gracefully
}
}
`
The library includes comprehensive examples demonstrating various usage patterns:
- examples/usage.ts - Basic operations and workflows
- Basic usage patterns
- Database recovery workflow
- Size analysis
- Upload to server
- Complete workflows
- Real-time process monitoring
- examples/version-handling.ts - Version management
- Version detection
- Command availability checking
- Error handling
- Feature detection patterns
library locally in another project, you can follow these steps:
1. Build the Library
First, ensure that the fmdevelopertool library is built. Navigate to the fmdevelopertool project directory and run:
`bash
npm run build
` This will compile the TypeScript code into JavaScript and place it in the
dist folder.
2. Link the Library Locally
In the fmdevelopertool project directory, run:
`bash
npm link
` Then, in your other project where you want to test the library, run:
`bash
npm link fmdevelopertool
` This will create a symbolic link to the local version of
fmdevelopertool.
3. Use the Library in Your Project
Now, you can import and use the fmdevelopertool library in your project as you would with any other npm package:
`typescript
import { FMDeveloperTool } from 'fmdevelopertool';
const devtool = new FMDeveloperTool();
// Use the devtool instance as needed
``MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues related to the FileMaker Developer Tool itself, please refer to the official FileMaker documentation.
For issues with this wrapper library, please open an issue on GitHub.