f9ec66c562
* upgrade @opentelemetry packages to the latest versions * remove v2 only packages, will be moved to a dedicated repo * remove more v2 code and run pnpm install * use the npm yalt package in the webapp * convert @trigger.dev/core to tshy * Switch from jest to vitest in @trigger.dev/core * Fixed core test * move core-backend code into core subpath export * convert @trigger.dev/sdk to tshy * Removed hono * move core-apps to core/v3/apps, remove core-apps, start converting cli-v3 * Fix up some of the commands * cli now building and loadable * using package-json-from-dist to get package version now in core and cli * dev command WIP * cleaned up some repetition and structure of the entry point stuff * bringing back the background worker stuff * Indexing of the v3 catalog * getting closer to executing dev runs... * centralize dev logging using event emitter * Move indexing to it’s own entry point, simplify code * dev runs working * Get instrumentation to work with openai * debugging achieved internally * provide worker files as part of the worker creation on the server * support for cjs and esm javascript * Fixed timeout * worker manifest now has the config path * auto-upgrade config to non-deprecated alternatives * Adding package preview release * deployment WIP * improve the syncEnvVars output and adapt resolveEnvVars * WIP bun runtime * WIP bun support * seed tasks with the machine preset if listed in the config * deploy run executions WIP, extracted TaskRunProcess into 1 place * deployed tasks running and executing 🎉 * support for waits and better flushing & process cleanup * Fixed the heartbeating * Better warning messages * Improve and unify the indexing between dev and deploy * Support for external deps that need node-gyp to build * build extensions can now install custom packages and run instructions in the image. Also prisma extension now works and also works with multiple schema files * Add back in the main/types/module to sdk * dev no longer is Ink/React, grace period for disconnections in dev * Fix the changeset config * More changeset fixes * Remove config packages * More changeset fixes * Fixed typescript issues (needed to revert back to zod 3.22.3 * Fix pr_checks workflow * Remove the prepare script * Fixed tests and package versions * Remove cli test script * Remove packages from tailwind watch paths * Add repo to public packages * Just commit the generated files and do the building at dev time * Try and get pkg.pr.new working * Try again * Fix emitDecoratorMetadata importing named export from typescript * config file backwards compat with export const config * Fixed issue where import errors weren’t coming through * p-retry is a prod dep * typescript needs to be a prod dependency for emitDecoratorMetadata * Add better debug logging to help track down import-in-the-middle bug * An external is only considered resolvable if it resolves to the same path as the collected external * Fix runtime checks to allow >=18.20 * Move extensions to a new build package * Fixed building packages in dockerfile * Remove the e2e test from publish workflow for now * Don’t treat pkg.pr.new versions has needing upgrading * making sure config handleError works, and discovered path aliases don’t work in config files * Strip empty string env vars so they accidentally override real values * Couple of things * Update version to use preview instead of beta * Hopefully fix re-attempts with >30s delay * Match socket emit messages to current latest in main * Initial guide * Go back to beta * Go back to the preview, and update guide to use pr preview tags * Go back to beta --------- Co-authored-by: Matt Aitken <matt@mattaitken.com>
213 lines
6.1 KiB
TypeScript
213 lines
6.1 KiB
TypeScript
import { flattenAttributes, unflattenAttributes } from "../src/v3/utils/flattenAttributes.js";
|
|
|
|
describe("flattenAttributes", () => {
|
|
it("handles null correctly", () => {
|
|
expect(flattenAttributes(null)).toEqual({ "": "$@null((" });
|
|
expect(unflattenAttributes({ "": "$@null((" })).toEqual(null);
|
|
|
|
expect(flattenAttributes(null, "$output")).toEqual({ $output: "$@null((" });
|
|
expect(flattenAttributes({ foo: null })).toEqual({ foo: "$@null((" });
|
|
expect(unflattenAttributes({ foo: "$@null((" })).toEqual({ foo: null });
|
|
|
|
expect(flattenAttributes({ foo: [null] })).toEqual({ "foo.[0]": "$@null((" });
|
|
expect(unflattenAttributes({ "foo.[0]": "$@null((" })).toEqual({ foo: [null] });
|
|
|
|
expect(flattenAttributes([null])).toEqual({ "[0]": "$@null((" });
|
|
expect(unflattenAttributes({ "[0]": "$@null((" })).toEqual([null]);
|
|
});
|
|
|
|
it("flattens string attributes correctly", () => {
|
|
const result = flattenAttributes("testString");
|
|
expect(result).toEqual({ "": "testString" });
|
|
expect(unflattenAttributes(result)).toEqual("testString");
|
|
});
|
|
|
|
it("flattens number attributes correctly", () => {
|
|
const result = flattenAttributes(12345);
|
|
expect(result).toEqual({ "": 12345 });
|
|
expect(unflattenAttributes(result)).toEqual(12345);
|
|
});
|
|
|
|
it("flattens boolean attributes correctly", () => {
|
|
const result = flattenAttributes(true);
|
|
expect(result).toEqual({ "": true });
|
|
expect(unflattenAttributes(result)).toEqual(true);
|
|
});
|
|
|
|
it("flattens boolean attributes correctly", () => {
|
|
const result = flattenAttributes(true, "$output");
|
|
expect(result).toEqual({ $output: true });
|
|
expect(unflattenAttributes(result)).toEqual({ $output: true });
|
|
});
|
|
|
|
it("flattens array attributes correctly", () => {
|
|
const input = [1, 2, 3];
|
|
const result = flattenAttributes(input);
|
|
expect(result).toEqual({ "[0]": 1, "[1]": 2, "[2]": 3 });
|
|
expect(unflattenAttributes(result)).toEqual(input);
|
|
});
|
|
|
|
it("flattens complex objects correctly", () => {
|
|
const obj = {
|
|
level1: {
|
|
level2: {
|
|
value: "test",
|
|
},
|
|
array: [1, 2, 3],
|
|
},
|
|
};
|
|
const expected = {
|
|
"level1.level2.value": "test",
|
|
"level1.array.[0]": 1,
|
|
"level1.array.[1]": 2,
|
|
"level1.array.[2]": 3,
|
|
};
|
|
expect(flattenAttributes(obj)).toEqual(expected);
|
|
});
|
|
|
|
it("applies prefixes correctly", () => {
|
|
const obj = { key: "value" };
|
|
const expected = { "prefix.key": "value" };
|
|
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
|
|
});
|
|
|
|
it("handles arrays of objects correctly", () => {
|
|
const obj = {
|
|
array: [{ key: "value" }, { key: "value" }, { key: "value" }],
|
|
};
|
|
const expected = {
|
|
"array.[0].key": "value",
|
|
"array.[1].key": "value",
|
|
"array.[2].key": "value",
|
|
};
|
|
expect(flattenAttributes(obj)).toEqual(expected);
|
|
});
|
|
|
|
it("handles arrays of objects correctly with prefixing correctly", () => {
|
|
const obj = {
|
|
array: [{ key: "value" }, { key: "value" }, { key: "value" }],
|
|
};
|
|
const expected = {
|
|
"prefix.array.[0].key": "value",
|
|
"prefix.array.[1].key": "value",
|
|
"prefix.array.[2].key": "value",
|
|
};
|
|
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
|
|
});
|
|
|
|
it("handles objects of objects correctly", () => {
|
|
const obj = {
|
|
level1: {
|
|
level2: {
|
|
key: "value",
|
|
},
|
|
},
|
|
};
|
|
const expected = { "level1.level2.key": "value" };
|
|
expect(flattenAttributes(obj)).toEqual(expected);
|
|
});
|
|
|
|
it("handles objects of objects correctly with prefixing", () => {
|
|
const obj = {
|
|
level1: {
|
|
level2: {
|
|
key: "value",
|
|
},
|
|
},
|
|
};
|
|
const expected = { "prefix.level1.level2.key": "value" };
|
|
expect(flattenAttributes(obj, "prefix")).toEqual(expected);
|
|
});
|
|
|
|
it("handles retry.byStatus correctly", () => {
|
|
const obj = {
|
|
"500": {
|
|
strategy: "backoff",
|
|
maxAttempts: 2,
|
|
factor: 2,
|
|
minTimeoutInMs: 1_000,
|
|
maxTimeoutInMs: 30_000,
|
|
randomize: false,
|
|
},
|
|
};
|
|
|
|
const expected = {
|
|
"retry.byStatus.500.strategy": "backoff",
|
|
"retry.byStatus.500.maxAttempts": 2,
|
|
"retry.byStatus.500.factor": 2,
|
|
"retry.byStatus.500.minTimeoutInMs": 1_000,
|
|
"retry.byStatus.500.maxTimeoutInMs": 30_000,
|
|
"retry.byStatus.500.randomize": false,
|
|
};
|
|
|
|
expect(flattenAttributes(obj, "retry.byStatus")).toEqual(expected);
|
|
});
|
|
});
|
|
|
|
describe("unflattenAttributes", () => {
|
|
it("returns the original object for primitive types", () => {
|
|
// @ts-expect-error
|
|
expect(unflattenAttributes("testString")).toEqual("testString");
|
|
// @ts-expect-error
|
|
expect(unflattenAttributes(12345)).toEqual(12345);
|
|
// @ts-expect-error
|
|
expect(unflattenAttributes(true)).toEqual(true);
|
|
});
|
|
|
|
it("correctly reconstructs an object from flattened attributes", () => {
|
|
const flattened = {
|
|
"level1.level2.value": "test",
|
|
"level1.array.[0]": 1,
|
|
"level1.array.[1]": 2,
|
|
"level1.array.[2]": 3,
|
|
};
|
|
const expected = {
|
|
level1: {
|
|
level2: {
|
|
value: "test",
|
|
},
|
|
array: [1, 2, 3],
|
|
},
|
|
};
|
|
expect(unflattenAttributes(flattened)).toEqual(expected);
|
|
});
|
|
|
|
it("handles complex nested objects with mixed types", () => {
|
|
const flattened = {
|
|
"user.details.name": "John Doe",
|
|
"user.details.age": 30,
|
|
"user.preferences.colors.[0]": "blue",
|
|
"user.preferences.colors.[1]": "green",
|
|
"user.active": true,
|
|
};
|
|
const expected = {
|
|
user: {
|
|
details: {
|
|
name: "John Doe",
|
|
age: 30,
|
|
},
|
|
preferences: {
|
|
colors: ["blue", "green"],
|
|
},
|
|
active: true,
|
|
},
|
|
};
|
|
expect(unflattenAttributes(flattened)).toEqual(expected);
|
|
});
|
|
|
|
it("correctly identifies arrays vs objects", () => {
|
|
const flattened = {
|
|
"array.[0]": 1,
|
|
"array.[1]": 2,
|
|
"object.key": "value",
|
|
};
|
|
const expected = {
|
|
array: [1, 2],
|
|
object: {
|
|
key: "value",
|
|
},
|
|
};
|
|
expect(unflattenAttributes(flattened)).toEqual(expected);
|
|
});
|
|
});
|