Milestone 0: import zappier billing, Verae middleware, and Zapier research

Compose-ready workspace: packages/zappier (rate card, portal, Stripe),
packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier
(CLI app), vendor/zapier-platform, and research/zapier vendor corpus.

Gate 0 structure checks pass. Product code and research are not yet wired.
This commit is contained in:
George Lambert 2026-09-09 02:37:36 -04:00
commit b4150c8250
1364 changed files with 6814366 additions and 0 deletions

View file

@ -0,0 +1,62 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# environment variables file
.env
.environment
# next.js build output
.next

View file

@ -0,0 +1,30 @@
# callback
This Zapier integration project is generated by the `zapier-platform init` CLI command.
These are what you normally do next:
```bash
# Install dependencies
npm install # or you can use yarn
# Run tests
zapier-platform test
# Register the integration on Zapier if you haven't
zapier-platform register "App Title"
# Or you can link to an existing integration on Zapier
zapier-platform link
# Push it to Zapier
zapier-platform push
```
Find out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.
# The "Callback" Template
This example has a create showcasing the `performResume` callback function.
Find out more in the docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli#zgeneratecallbackurl.

View file

@ -0,0 +1,73 @@
// We recommend writing your creates separate like this and rolling them
// into the App definition at the end.
module.exports = {
key: 'prediction',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Prediction',
display: {
label: 'Create Prediction',
description: 'Creates a new prediction.',
},
// `operation` is where the business logic goes.
operation: {
inputFields: [
{
key: 'question',
required: true,
type: 'string',
helpText: 'Provide a "Yes" or "No" question to ask the Magic 8-Ball.',
},
],
perform: (z, bundle) => {
const promise = z.request({
url: 'https://auth-json-server.zapier-staging.com/magic',
method: 'POST',
body: {
callbackUrl: z.generateCallbackUrl(),
},
headers: {
'content-type': 'application/json',
// This is NOT how you normally do authentication. This is just to demo how to write a create here.
// Refer to this doc to set up authentication:
// https://docs.zapier.com/platform/reference/cli-docs#authentication
'X-API-Key': 'secret',
},
});
return promise.then((response) => ({ ...response.data, extra: 'data' }));
},
performResume: (z, bundle) => {
// The original output from perform is available in bundle.outputData.
// The data POSTed to the callbackUrl is in bundle.cleanedRequest.
// The full request object corresponding to bundle.cleanedRequest can be found in bundle.rawRequest.
const { extra, ...originalOutput } = bundle.outputData;
// The following line will return an object containing the contents of the original API response to the
// request from the perform function merged with the contents of the new request from the API.
return { ...originalOutput, ...bundle.cleanedRequest };
},
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
callbackUrl: 'http://zapier.com/hooks/catch/-1234/abcdef/',
status: 'success',
result: 'Ask again later.',
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{ key: 'callbackUrl', label: 'Callback URL' },
{ key: 'status', label: 'Status' },
{ key: 'result', label: 'Predicted Result' },
],
},
};

View file

@ -0,0 +1,17 @@
const prediction = require('./creates/prediction');
// Now we can roll up all our behaviors in an App.
const App = {
// This is just shorthand to reference the installed dependencies you have. Zapier will
// need to know these before we can upload
version: require('./package.json').version,
platformVersion: require('zapier-platform-core').version,
// If you want your creates to show up, you better include it here!
creates: {
[prediction.key]: prediction,
},
};
// Finally, export the app.
module.exports = App;

View file

@ -0,0 +1,16 @@
{
"name": "callback",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest --testTimeout 10000"
},
"dependencies": {
"zapier-platform-core": "19.1.0"
},
"devDependencies": {
"jest": "^25.5.3"
},
"private": true
}

View file

@ -0,0 +1,46 @@
/* globals describe, expect, test */
const zapier = require('zapier-platform-core');
const App = require('../index');
const appTester = zapier.createAppTester(App);
zapier.tools.env.inject();
describe('creates', () => {
test('perform function returns intermediate data', async () => {
const bundle = { inputData: { question: 'Will this work?' } };
const result = await appTester(
App.creates.prediction.operation.perform,
bundle,
);
expect(result).toMatchObject({
status: '...thinking...',
callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',
extra: 'data',
});
});
test('performResume function returns "final" data', async () => {
const bundle = {
outputData: {
callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',
status: '...thinking...',
extra: 'data',
},
cleanedRequest: {
status: 'success',
result: 'Ask again later.',
},
};
const result = await appTester(
App.creates.prediction.operation.performResume,
bundle,
);
expect(result).toMatchObject({
status: 'success',
result: 'Ask again later.',
callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',
});
});
});