Skip to content

Commit f1c725f

Browse files
authored
Update identifier validation logic for run method (#55)
* Align run identifier validation with Docker naming rules * Add test for calling run with invalid identifiers * Add test for running with identifier containing hyphen and full stop
1 parent 4aa2362 commit f1c725f

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

index.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,18 @@ class Replicate {
8181
* @returns {Promise<object>} - Resolves with the output of running the model
8282
*/
8383
async run(identifier, options) {
84-
const pattern =
85-
/^(?<owner>[a-zA-Z0-9-_]+?)\/(?<name>[a-zA-Z0-9-_]+?):(?<version>[0-9a-fA-F]+)$/;
86-
const match = identifier.match(pattern);
84+
// Define a pattern for owner and model names that allows
85+
// letters, digits, and certain special characters.
86+
// Example: "user123", "abc__123", "user.name"
87+
const namePattern = /[a-zA-Z0-9]+(?:(?:[._]|__|[-]*)[a-zA-Z0-9]+)*/;
88+
89+
// Define a pattern for "owner/name:version" format with named capturing groups.
90+
// Example: "user123/repo_a:1a2b3c"
91+
const pattern = new RegExp(
92+
`^(?<owner>${namePattern.source})/(?<name>${namePattern.source}):(?<version>[0-9a-fA-F]+)$`
93+
);
8794

95+
const match = identifier.match(pattern);
8896
if (!match || !match.groups) {
8997
throw new Error(
9098
'Invalid version. It must be in the format "owner/name:version"'

index.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,37 @@ describe('Replicate client', () => {
426426
);
427427
expect(output).toBe('foobar');
428428
});
429+
430+
test('Does not throw an error for identifier containing hyphen and full stop', async () => {
431+
nock(BASE_URL)
432+
.post('/predictions')
433+
.reply(200, {
434+
id: 'ufawqhfynnddngldkgtslldrkq',
435+
status: 'processing',
436+
})
437+
.get('/predictions/ufawqhfynnddngldkgtslldrkq')
438+
.reply(200, {
439+
id: 'ufawqhfynnddngldkgtslldrkq',
440+
status: 'succeeded',
441+
output: 'foobar',
442+
});
443+
444+
await expect(client.run('a/b-1.0:abc123', { input: { text: 'Hello, world!' } })).resolves.not.toThrow();
445+
});
446+
447+
test('Throws an error for invalid identifiers', async () => {
448+
const options = { input: { text: 'Hello, world!' } }
449+
450+
await expect(client.run('owner/model:invalid', options)).rejects.toThrow();
451+
452+
// @ts-expect-error
453+
await expect(client.run('owner:abc123', options)).rejects.toThrow();
454+
455+
await expect(client.run('/model:abc123', options)).rejects.toThrow();
456+
457+
// @ts-expect-error
458+
await expect(client.run(':abc123', options)).rejects.toThrow();
459+
});
429460
});
430461

431462
// Continue with tests for other methods

0 commit comments

Comments
 (0)