-
Notifications
You must be signed in to change notification settings - Fork 9
feat: Templates endpoint (public templates) #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
df34285
test: add mock data files for templates endpoint
JanKulhavy 48602c5
feat: add Templates endpoint class and unit tests
JanKulhavy fe24fea
feat: wire Templates endpoint into Make client and exports
JanKulhavy c2861c5
style: align listPublic with codebase conventions
JanKulhavy 62af959
feat: add MCP tool definitions for templates endpoint
JanKulhavy 21ca17a
test: add integration tests for templates endpoint
JanKulhavy b237c0b
chore: format templates files and fix conditional expects
JanKulhavy 4d9ce92
feat: add getPublic and getPublicBlueprint methods for templates
JanKulhavy 4d853ca
refactor(templates): drop private templates, keep public only
JanKulhavy 9a6c6a7
chore(scripts): add usedApps filter to templates smoke test
JanKulhavy b672277
remove: file
JanKulhavy b7161bb
feat(templates): update template names and enhance documentation for …
JanKulhavy ab9c170
feat(templates): rename templates to public-templates and update rela…
JanKulhavy b2d609b
Merge branch 'main' into feat/templates
JanKulhavy d333930
Update src/endpoints/public-templates.mcp.ts
JanKulhavy c710f30
Merge remote-tracking branch 'origin/main' into feat/templates
JanKulhavy d9e6142
Update test/public-templates.integration.test.ts
patriksimek 87d394e
refactor: rename templates to publicTemplates for consistency
patriksimek 82fe4fb
refactor: rename templates to publicTemplates for consistency
patriksimek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| #!/usr/bin/env node | ||
|
|
||
| import dotenv from 'dotenv'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import { dirname, join } from 'node:path'; | ||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| dotenv.config({ path: join(__dirname, '..', '.env') }); | ||
|
|
||
| import { Make } from '../dist/index.js'; | ||
|
|
||
| if (!process.env.MAKE_API_KEY) { | ||
| console.error('Please provide MAKE_API_KEY environment variable.'); | ||
| process.exit(1); | ||
| } | ||
| if (!process.env.MAKE_ZONE) { | ||
| console.error('Please provide MAKE_ZONE environment variable.'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const searchTerm = process.argv[2] ?? 'webhook'; | ||
| const usedApps = process.argv[3] ? process.argv[3].split(',').map(s => s.trim()).filter(Boolean) : undefined; | ||
|
|
||
| const make = new Make(process.env.MAKE_API_KEY, process.env.MAKE_ZONE); | ||
|
|
||
| const filterDesc = usedApps ? `"${searchTerm}" with apps [${usedApps.join(', ')}]` : `"${searchTerm}"`; | ||
| console.log(`\n=== Searching public templates for ${filterDesc} ===\n`); | ||
| const templates = await make.templates.list({ name: searchTerm, usedApps }); | ||
|
|
||
| console.log(`Found ${templates.length} template(s):`); | ||
| templates.slice(0, 5).forEach(t => { | ||
| console.log(` [${t.id}] ${t.name} — apps: ${t.usedApps.join(', ')} — usage: ${t.usage}`); | ||
| }); | ||
|
|
||
| if (templates.length === 0) { | ||
| console.log('No templates found. Try a different search term.'); | ||
| process.exit(0); | ||
| } | ||
|
|
||
| const first = templates[0]; | ||
| console.log(`\n=== Fetching blueprint for template [${first.id}] "${first.name}" (url: ${first.url}) ===\n`); | ||
| const blueprint = await make.templates.getBlueprint(first.url); | ||
|
|
||
| console.log('Language:', blueprint.language); | ||
| console.log('Scheduling:', JSON.stringify(blueprint.scheduling)); | ||
| console.log('Controller name:', blueprint.controller?.name); | ||
| console.log('Blueprint flow (modules):'); | ||
| const flow = blueprint.blueprint?.flow || []; | ||
| flow.forEach((step, i) => { | ||
| console.log(` ${i + 1}. ${step.module} (id ${step.id})`); | ||
| }); | ||
| console.log(`\nFull blueprint size: ${JSON.stringify(blueprint).length} bytes`); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| import type { Make } from '../make.js'; | ||
|
|
||
| export const tools = [ | ||
| { | ||
| name: 'templates_list', | ||
| title: 'List public templates', | ||
| description: | ||
| 'Search and list public (approved) templates available for anyone. Supports name-based search for template discovery. Results are sorted by usage by default.', | ||
| category: 'templates', | ||
| scope: 'templates:read', | ||
| annotations: { | ||
| readOnlyHint: true, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| name: { type: 'string', description: 'Search templates by name' }, | ||
| usedApps: { | ||
| type: 'array', | ||
| items: { type: 'string' }, | ||
| description: 'Filter templates by apps used', | ||
| }, | ||
| includeEn: { | ||
| type: 'boolean', | ||
| description: 'Whether to include English-language templates in results', | ||
| }, | ||
| }, | ||
| }, | ||
| examples: [{ name: 'webhook' }], | ||
| execute: async (make: Make, args: { name?: string; usedApps?: string[]; includeEn?: boolean }) => { | ||
| return await make.templates.list({ ...args, cols: ['*'] }); | ||
| }, | ||
| }, | ||
| { | ||
| name: 'templates_get', | ||
| title: 'Get public template', | ||
| description: | ||
| 'Get details of a public template by its URL slug (e.g. "12289-add-webhook-data-to-a-google-sheet"). Use this for templates discovered via templates_list.', | ||
| category: 'templates', | ||
| scope: 'templates:read', | ||
| identifier: 'templateUrl', | ||
| annotations: { | ||
| readOnlyHint: true, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| templateUrl: { | ||
| type: 'string', | ||
| description: 'The URL slug of the template (e.g. "12289-add-webhook-data-to-a-google-sheet")', | ||
| }, | ||
| }, | ||
| required: ['templateUrl'], | ||
| }, | ||
| examples: [{ templateUrl: '12289-add-webhook-data-to-a-google-sheet' }], | ||
| execute: async (make: Make, args: { templateUrl: string }) => { | ||
| return await make.templates.get(args.templateUrl, { cols: ['*'] }); | ||
| }, | ||
| }, | ||
| { | ||
| name: 'templates_get-blueprint', | ||
| title: 'Get public template blueprint', | ||
| description: | ||
| 'Get the full blueprint of a public template including scenario flow, controller configuration, scheduling, and metadata. Use this for templates discovered via templates_list.', | ||
| category: 'templates', | ||
| scope: 'templates:read', | ||
| identifier: 'templateUrl', | ||
| annotations: { | ||
| readOnlyHint: true, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| templateUrl: { | ||
| type: 'string', | ||
| description: 'The URL slug of the template (e.g. "12289-add-webhook-data-to-a-google-sheet")', | ||
| }, | ||
| }, | ||
| required: ['templateUrl'], | ||
| }, | ||
| examples: [{ templateUrl: '12289-add-webhook-data-to-a-google-sheet' }], | ||
| execute: async (make: Make, args: { templateUrl: string }) => { | ||
| return await make.templates.getBlueprint(args.templateUrl); | ||
| }, | ||
| }, | ||
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| import type { FetchFunction, Pagination, PickColumns } from '../types.js'; | ||
|
|
||
| /** | ||
| * Represents a publicly available approved template in Make. | ||
| * Public templates can be discovered and used by all Make users. | ||
| */ | ||
| export type Template = { | ||
| /** Unique identifier of the public template */ | ||
| id: number; | ||
| /** Name of the public template */ | ||
| name: string; | ||
| /** Human-readable description of what the template does, or null if not set */ | ||
| description: string | null; | ||
| /** URL slug identifying this public template */ | ||
| url: string; | ||
| /** List of app identifiers used in the template */ | ||
| usedApps: string[]; | ||
| /** Number of times this template has been used */ | ||
| usage: number; | ||
| }; | ||
|
|
||
| /** | ||
| * Represents the blueprint (scenario definition) extracted from a template. | ||
| * Contains the full scenario configuration including flow, scheduling, and metadata. | ||
| */ | ||
| export type TemplateBlueprint = { | ||
| /** The scenario blueprint definition */ | ||
| blueprint: Record<string, unknown>; | ||
| /** Controller configuration for the scenario */ | ||
| controller: Record<string, unknown>; | ||
| /** Scheduling configuration for the scenario */ | ||
| scheduling: Record<string, unknown>; | ||
| /** Language code for the template */ | ||
| language: string; | ||
| /** Additional metadata for the template, or null if not set */ | ||
| metadata: Record<string, unknown> | null; | ||
| }; | ||
|
|
||
| /** | ||
| * Options for listing public approved templates. | ||
| * @template C Keys of the Template type to include in the response | ||
| */ | ||
| export type ListTemplatesOptions<C extends keyof Template = never> = { | ||
| /** Specific columns/fields to include in the response */ | ||
| cols?: C[] | ['*']; | ||
| /** Pagination options */ | ||
| pg?: Partial<Pagination<Template>>; | ||
| /** Search templates by name */ | ||
| name?: string; | ||
| /** Filter templates by apps used */ | ||
| usedApps?: string[]; | ||
| /** Whether to include English-language templates in results */ | ||
| includeEn?: boolean; | ||
| }; | ||
|
|
||
| /** | ||
| * Options for getting a single public template. | ||
| * @template C Keys of the Template type to include in the response | ||
| */ | ||
| export type GetTemplateOptions<C extends keyof Template = never> = { | ||
| /** Specific columns/fields to include in the response */ | ||
| cols?: C[] | ['*']; | ||
| }; | ||
|
|
||
| /** | ||
| * Response format for listing public templates. | ||
| */ | ||
| type ListTemplatesResponse<C extends keyof Template = never> = { | ||
| /** List of public templates matching the query */ | ||
| templatesPublic: PickColumns<Template, C>[]; | ||
| /** Pagination information */ | ||
| pg: Pagination<Template>; | ||
| }; | ||
|
|
||
| /** | ||
| * Response format for getting a single public template. | ||
| */ | ||
| type GetTemplateResponse<C extends keyof Template = never> = { | ||
| /** The requested public template */ | ||
| templatePublic: PickColumns<Template, C>; | ||
| }; | ||
|
|
||
| /** | ||
| * Class providing methods for working with public Make templates. | ||
| * Public templates are approved scenario configurations that can be | ||
| * discovered and used by any Make user. | ||
| */ | ||
| export class Templates { | ||
| readonly #fetch: FetchFunction; | ||
|
|
||
| /** | ||
| * Create a new Templates instance. | ||
| * @param fetch Function for making API requests | ||
| */ | ||
| constructor(fetch: FetchFunction) { | ||
| this.#fetch = fetch; | ||
| } | ||
|
|
||
| /** | ||
| * List public (approved) templates available for anyone. | ||
| * Supports name-based search for template discovery. | ||
| * Results are sorted by usage in descending order by default. | ||
| * @param options Optional parameters for searching, filtering, and pagination | ||
| * @returns Promise with the list of public templates | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Search public templates by name | ||
| * const templates = await make.templates.list({ name: 'webhook' }); | ||
| * | ||
| * // Filter by apps used | ||
| * const gmailTemplates = await make.templates.list({ usedApps: ['gmail'] }); | ||
| * ``` | ||
| */ | ||
| async list<C extends keyof Template = never>( | ||
| options: ListTemplatesOptions<C> = {}, | ||
| ): Promise<PickColumns<Template, C>[]> { | ||
| return ( | ||
| await this.#fetch<ListTemplatesResponse<C>>('/templates/public', { | ||
| query: { | ||
| name: options.name, | ||
| usedApps: options.usedApps, | ||
| includeEn: options.includeEn, | ||
| cols: options.cols, | ||
| pg: options.pg, | ||
| }, | ||
| }) | ||
| ).templatesPublic; | ||
| } | ||
|
|
||
| /** | ||
| * Get a single public template by its URL slug. | ||
| * Use this for templates discovered via {@link list}. | ||
| * @param templateUrl The URL slug of the template (e.g. "12289-add-webhook-data-to-a-google-sheet") | ||
| * @param options Optional parameters for field selection | ||
| * @returns Promise with the public template details | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const template = await make.templates.get('12289-add-webhook-data-to-a-google-sheet'); | ||
| * ``` | ||
| */ | ||
| async get<C extends keyof Template = never>( | ||
| templateUrl: string, | ||
| options: GetTemplateOptions<C> = {}, | ||
| ): Promise<PickColumns<Template, C>> { | ||
| return ( | ||
| await this.#fetch<GetTemplateResponse<C>>(`/templates/public/${templateUrl}`, { | ||
| query: { | ||
| cols: options.cols, | ||
| }, | ||
| }) | ||
| ).templatePublic; | ||
| } | ||
|
|
||
| /** | ||
| * Get the blueprint (scenario definition) for a public template. | ||
| * The full response object is returned directly since the API returns a flat | ||
| * structure rather than wrapping the blueprint in a named property. | ||
| * @param templateUrl The URL slug of the template (e.g. "12289-add-webhook-data-to-a-google-sheet") | ||
| * @returns Promise with the full blueprint response | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const blueprint = await make.templates.getBlueprint('12289-add-webhook-data-to-a-google-sheet'); | ||
| * ``` | ||
| */ | ||
| async getBlueprint(templateUrl: string): Promise<TemplateBlueprint> { | ||
| return await this.#fetch<TemplateBlueprint>(`/templates/public/${templateUrl}/blueprint`); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.