Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
erickoledadevrel committed Sep 24, 2024
1 parent 7ea99bb commit ac196c5
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 2 deletions.
19 changes: 18 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"text-encoding": "^0.7.0",
"tokenize-words": "^0.0.4-alpha.0",
"url-parse": "^1.5.10",
"url-polyfill": "^1.1.12"
"url-polyfill": "^1.1.12",
"yaml": "^2.5.1"
},
"devDependencies": {
"@types/chai": "^4.3.0",
Expand Down
3 changes: 3 additions & 0 deletions yaml/.coda-pack.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"packId": 34536
}
140 changes: 140 additions & 0 deletions yaml/pack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import * as coda from "@codahq/packs-sdk";
import YAML from "yaml";

const OneDaySecs = 24 * 60 * 60;

export const pack = coda.newPack();

const YAMLParam = coda.makeParameter({
type: coda.ParameterType.String,
name: "yaml",
description: "The YAML contents as a string.",
});

const IndentParam = coda.makeParameter({
type: coda.ParameterType.Number,
name: "indent",
description: "The number of spaces to indent by. Default: 2.",
optional: true,
});

pack.addFormula({
name: "FormatYAML",
description: "Formats YAML content using the options provided.",
parameters: [
YAMLParam,
IndentParam,
],
resultType: coda.ValueType.String,
cacheTtlSecs: OneDaySecs,
examples: [
{
params: [`a: [1, 2]`],
result: trimIndent(`
a:
- 1
- 2
`),
},
{
params: [`a: [1, 2]`, 4],
result: trimIndent(`
a:
- 1
- 2
`),
},
],
execute: async function (args, context) {
let [yaml, indent] = args;
let options: Record<string, any> = {};
if (typeof indent == "number") {
options.indent = indent;
}
let value = parse(yaml);
return YAML.stringify(value, null, options);
},
});

pack.addFormula({
name: "IsValidYAML",
description: "Returns true if the content is valid YAML, false otherwise.",
parameters: [
YAMLParam,
],
resultType: coda.ValueType.Boolean,
cacheTtlSecs: OneDaySecs,
examples: [
{ params: [`a: [1, 2]`], result: true },
{ params: [`a: [1, 2`, ], result: false },
],
execute: async function (args, context) {
let [yaml] = args;
try {
YAML.parse(yaml);
} catch (e) {
if (e.toString().startsWith("YAMLParseError")) {
return false;
}
throw e;
}
return true;
},
});

pack.addFormula({
name: "ToJSON",
description: "Converts a YAML string to JSON.",
parameters: [
YAMLParam,
IndentParam,
],
resultType: coda.ValueType.String,
cacheTtlSecs: OneDaySecs,
examples: [
{ params: [`a: [1, 2]`], result: `{"a":[1,2]}` },
{
params: [`a: [1, 2]`, 2],
result: trimIndent(`
{
"a": [
1,
2
]
}
`, true)
},
],
execute: async function (args, context) {
let [yaml, spaces] = args;
let value = parse(yaml);
return JSON.stringify(value, null, spaces);
},
});

function parse(yaml: string) {
try {
return YAML.parse(yaml);
} catch (e) {
if (e.toString().startsWith("YAMLParseError")) {
throw new coda.UserVisibleError(e);
}
throw e;
}
}

function trimIndent(str: string, trim = false) {
let lines = str.split("\n");
if (lines[0] == "") {
lines = lines.slice(1);
}
if (lines.at(-1) == "") {
lines = lines.slice(0, -1);
}
let indent = lines[0].match(/^\s*/)[0].length;
let result = lines.map(line => line.substring(indent)).join("\n");
if (trim) {
result = result.trim();
}
return result;
}
26 changes: 26 additions & 0 deletions yaml/tests/pack_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {executeFormulaFromPackDef} from '@codahq/packs-sdk/dist/development';
import {pack} from '../pack';
import * as chai from "chai";
import {assert} from "chai";
import {describe} from "mocha";
import {it} from "mocha";
import chaiAsPromised from "chai-as-promised";
chai.use(chaiAsPromised);
chai.should();

describe("Examples", () => {
for (let formula of pack.formulas) {
describe(formula.name, () => {
for (let [i, example] of formula.examples.entries()) {
it(`Example ${i}`, async () => {
const result = await executeFormulaFromPackDef(pack, formula.name, example.params as any);
if (typeof example.result == "object") {
assert.deepEqual(result, example.result);
} else {
assert.equal(result, example.result);
}
});
}
});
}
});

0 comments on commit ac196c5

Please sign in to comment.