Skip to content
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

Unexpected token 'export' #15

Open
FreePhoenix888 opened this issue Aug 13, 2023 · 8 comments
Open

Unexpected token 'export' #15

FreePhoenix888 opened this issue Aug 13, 2023 · 8 comments

Comments

@FreePhoenix888
Copy link
Member

FreePhoenix888 commented Aug 13, 2023

Error

Unexpected token 'export'

Source Code

import {
  DeepClient,
  SerialOperation,
  Table,
} from '@deep-foundation/deeplinks/imports/client';
import { Link } from '@deep-foundation/deeplinks/imports/minilinks';

async ({
  deep,
  data: { newLink: notifyLink, triggeredByLinkId },
}: {
  deep: DeepClient;
  data: { newLink: Link<number>, triggeredByLinkId: number };
}) => {
  const firebaseAdmin = await import('firebase-admin');
  const util = await import('util');
  const { createSerialOperation } = await import('@deep-foundation/deeplinks/imports/gql/index')
  const logs: Array<any> = [];
  const DEFAULT_LOG_DEPTH = 3;

  async function main() {
    const log = getNamespacedLogger({ namespace: main.name });
    const notificationLinkId = notifyLink.from_id!;
    log({ notificationLinkId })
    const { data: [notificationLink] } = await deep.select(notificationLinkId)
    log({ notificationLink })
    if (!notificationLink.value?.value) {
      throw new Error(`##${notificationLinkId} must have value`)
    }
    const title = notificationLink.value.value.title;
    log({ title })
    if (!title) {
      throw new Error(`Object value of ##${notificationLinkId} must have title property`)
    }

    const body = notificationLink.value.value.body;
    log({ body })
    if (!body) {
      throw new Error(`Object value of ##${notificationLinkId} must have body property`)
    }

    const deviceLinkId = notifyLink.to_id;
    log({ deviceLinkId })

    const containTypeLinkId = await deep.id('@deep-foundation/core', 'Contain');
    log({ containTypeLinkId })

    const serviceAccount = await getServiceAccount({
      containTypeLinkId,
      triggeredByLinkId,
    });
    log({ serviceAccount })

    const firebaseApplication = await getFirebaseApplication({
      firebaseAdmin,
      serviceAccount,
    });
    log({ firebaseApplication })

    const deviceRegistrationToken = await getDeviceRegistrationToken({
      containTypeLinkId,
      deviceLinkId,
    });
    log({ deviceRegistrationToken })

    const pushNotificationData = {
      token: deviceRegistrationToken,
      notification: {
        title: title,
        body: body,
      },
    };
    log({ pushNotificationData })

    await firebaseAdmin.messaging(firebaseApplication).send(pushNotificationData);
    await deep.insert({
      type_id: await deep.id(deep.linkId!, 'Notified'),
      in: {
        data: {
          type_id: containTypeLinkId,
          from_id: triggeredByLinkId,
        },
      },
      from_id: notifyLink.id,
      to_id: deviceLinkId,
    });

    firebaseApplication.delete();
  }

  async function getServiceAccount({ containTypeLinkId, triggeredByLinkId }) {
    const log = getNamespacedLogger({ namespace: getServiceAccount.name });
    const serviceAccountTypeLinkId = await deep.id(
      deep.linkId!,
      'ServiceAccount'
    );
    log({ serviceAccountTypeLinkId })
    const usesServiceAccountTypeLinkId = await deep.id(
      deep.linkId!,
      'UsesServiceAccount'
    );
    log({ usesServiceAccountTypeLinkId })
    const selectData = {
      _or: [
        {
          type_id: serviceAccountTypeLinkId,
          in: {
            type_id: containTypeLinkId,
            from_id: triggeredByLinkId,
          },
        },
        {
          type_id: usesServiceAccountTypeLinkId,
          from_id: triggeredByLinkId,
        },
      ],
    };
    const { data } = await deep.select(selectData);
    log({ data })
    if (data.length === 0) {
      throw new Error(
        `Select with data ${JSON.stringify(selectData)} returned empty result`
      );
    }
    let serviceAccountLink;
    const usesServiceAccountLinks = data.filter(
      (link) => link.type_id === usesServiceAccountTypeLinkId
    );
    if (usesServiceAccountLinks.length > 1) {
      throw new Error(
        `There must be only one link of type ${usesServiceAccountTypeLinkId} and from ${triggeredByLinkId}, instead there are ${usesServiceAccountLinks
          .map((link) => `##${link.id}`)
          .join(', ')}`
      );
    } else if (usesServiceAccountLinks.length === 1) {
      const usesServiceAccountLink = usesServiceAccountLinks[0];
      serviceAccountLink = data.find(
        (link) => link.id === usesServiceAccountLink.to_id
      );
    } else if (usesServiceAccountLinks.length === 0) {
      const serviceAccountLinks = data.filter(
        (link) => link.type_id === serviceAccountTypeLinkId
      );
      if (serviceAccountLinks.length > 1) {
        throw new Error(
          `There must be only one link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId}, instead there are ${serviceAccountLinks
            .map((link) => `##${link.id}`)
            .join(', ')}`
        );
      } else if (serviceAccountLinks.length === 1) {
        serviceAccountLink = serviceAccountLinks[0];
      } else if (serviceAccountLinks.length === 0) {
        throw new Error(
          `A link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId} is not found`
        );
      }
    }
    log({ serviceAccountLink })
    if (!serviceAccountLink) {
      throw new Error(
        `A link of type ##${usesServiceAccountTypeLinkId} and from ##${triggeredByLinkId} is not found`
      );
    }
    if (!serviceAccountLink.value?.value) {
      throw new Error(`##${serviceAccountLink.id} must have value`);
    }
    const result = serviceAccountLink.value.value;
    log({ result })
    return result;
  }

  async function getDeviceRegistrationToken({
    containTypeLinkId,
    deviceLinkId,
  }) {
    const log = getNamespacedLogger({ namespace: getDeviceRegistrationToken.name });
    const deviceRegistrationTokenTypeLinkId = await deep.id(
      deep.linkId!,
      'DeviceRegistrationToken'
    );
    log({ deviceRegistrationTokenTypeLinkId })
    const selectData = {
      type_id: deviceRegistrationTokenTypeLinkId,
      in: {
        type_id: containTypeLinkId,
        from_id: deviceLinkId,
      },
    };
    log({ selectData })
    const {
      data: [deviceRegistrationTokenLink],
    } = await deep.select(selectData);
    if (!deviceRegistrationTokenLink) {
      throw new Error(
        `##${deviceLinkId} must have contained a link of type ##${deviceRegistrationTokenTypeLinkId}. Select with data ${JSON.stringify(
          selectData
        )} returned empty result`
      );
    }
    log({ deviceRegistrationTokenLink })
    if (!deviceRegistrationTokenLink.value?.value) {
      throw new Error(`##${deviceRegistrationTokenLink.id} must have value`);
    }
    const result = deviceRegistrationTokenLink.value.value;
    log({ result })
    return result;
  }

  async function getFirebaseApplication({ firebaseAdmin, serviceAccount }) {
    firebaseAdmin.apps.forEach((app) => app.delete());
    return firebaseAdmin.initializeApp({
      credential: firebaseAdmin.credential.cert(serviceAccount),
    })
  }


  function getNamespacedLogger({
    namespace,
    depth = DEFAULT_LOG_DEPTH,
  }: {
    namespace: string;
    depth?: number;
  }) {
    return function (content: any) {
      const message = util.inspect(content, { depth });
      logs.push(`${namespace}: ${message}`);
    };
  }
};

Dist code transpiled by @deep-foundation/tsx package

async ({ deep, data: { newLink: notifyLink, triggeredByLinkId }, }) => {
    const firebaseAdmin = await import('firebase-admin');
    const util = await import('util');
    const { createSerialOperation } = await import('@deep-foundation/deeplinks/imports/gql/index');
    const logs = [];
    const DEFAULT_LOG_DEPTH = 3;
    async function main() {
        const log = getNamespacedLogger({ namespace: main.name });
        const notificationLinkId = notifyLink.from_id;
        log({ notificationLinkId });
        const { data: [notificationLink] } = await deep.select(notificationLinkId);
        log({ notificationLink });
        if (!notificationLink.value?.value) {
            throw new Error(`##${notificationLinkId} must have value`);
        }
        const title = notificationLink.value.value.title;
        log({ title });
        if (!title) {
            throw new Error(`Object value of ##${notificationLinkId} must have title property`);
        }
        const body = notificationLink.value.value.body;
        log({ body });
        if (!body) {
            throw new Error(`Object value of ##${notificationLinkId} must have body property`);
        }
        const deviceLinkId = notifyLink.to_id;
        log({ deviceLinkId });
        const containTypeLinkId = await deep.id('@deep-foundation/core', 'Contain');
        log({ containTypeLinkId });
        const serviceAccount = await getServiceAccount({
            containTypeLinkId,
            triggeredByLinkId,
        });
        log({ serviceAccount });
        const firebaseApplication = await getFirebaseApplication({
            firebaseAdmin,
            serviceAccount,
        });
        log({ firebaseApplication });
        const deviceRegistrationToken = await getDeviceRegistrationToken({
            containTypeLinkId,
            deviceLinkId,
        });
        log({ deviceRegistrationToken });
        const pushNotificationData = {
            token: deviceRegistrationToken,
            notification: {
                title: title,
                body: body,
            },
        };
        log({ pushNotificationData });
        await firebaseAdmin.messaging(firebaseApplication).send(pushNotificationData);
        await deep.insert({
            type_id: await deep.id(deep.linkId, 'Notified'),
            in: {
                data: {
                    type_id: containTypeLinkId,
                    from_id: triggeredByLinkId,
                },
            },
            from_id: notifyLink.id,
            to_id: deviceLinkId,
        });
        firebaseApplication.delete();
    }
    async function getServiceAccount({ containTypeLinkId, triggeredByLinkId }) {
        const log = getNamespacedLogger({ namespace: getServiceAccount.name });
        const serviceAccountTypeLinkId = await deep.id(deep.linkId, 'ServiceAccount');
        log({ serviceAccountTypeLinkId });
        const usesServiceAccountTypeLinkId = await deep.id(deep.linkId, 'UsesServiceAccount');
        log({ usesServiceAccountTypeLinkId });
        const selectData = {
            _or: [
                {
                    type_id: serviceAccountTypeLinkId,
                    in: {
                        type_id: containTypeLinkId,
                        from_id: triggeredByLinkId,
                    },
                },
                {
                    type_id: usesServiceAccountTypeLinkId,
                    from_id: triggeredByLinkId,
                },
            ],
        };
        const { data } = await deep.select(selectData);
        log({ data });
        if (data.length === 0) {
            throw new Error(`Select with data ${JSON.stringify(selectData)} returned empty result`);
        }
        let serviceAccountLink;
        const usesServiceAccountLinks = data.filter((link) => link.type_id === usesServiceAccountTypeLinkId);
        if (usesServiceAccountLinks.length > 1) {
            throw new Error(`There must be only one link of type ${usesServiceAccountTypeLinkId} and from ${triggeredByLinkId}, instead there are ${usesServiceAccountLinks
                .map((link) => `##${link.id}`)
                .join(', ')}`);
        }
        else if (usesServiceAccountLinks.length === 1) {
            const usesServiceAccountLink = usesServiceAccountLinks[0];
            serviceAccountLink = data.find((link) => link.id === usesServiceAccountLink.to_id);
        }
        else if (usesServiceAccountLinks.length === 0) {
            const serviceAccountLinks = data.filter((link) => link.type_id === serviceAccountTypeLinkId);
            if (serviceAccountLinks.length > 1) {
                throw new Error(`There must be only one link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId}, instead there are ${serviceAccountLinks
                    .map((link) => `##${link.id}`)
                    .join(', ')}`);
            }
            else if (serviceAccountLinks.length === 1) {
                serviceAccountLink = serviceAccountLinks[0];
            }
            else if (serviceAccountLinks.length === 0) {
                throw new Error(`A link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId} is not found`);
            }
        }
        log({ serviceAccountLink });
        if (!serviceAccountLink) {
            throw new Error(`A link of type ##${usesServiceAccountTypeLinkId} and from ##${triggeredByLinkId} is not found`);
        }
        if (!serviceAccountLink.value?.value) {
            throw new Error(`##${serviceAccountLink.id} must have value`);
        }
        const result = serviceAccountLink.value.value;
        log({ result });
        return result;
    }
    async function getDeviceRegistrationToken({ containTypeLinkId, deviceLinkId, }) {
        const log = getNamespacedLogger({ namespace: getDeviceRegistrationToken.name });
        const deviceRegistrationTokenTypeLinkId = await deep.id(deep.linkId, 'DeviceRegistrationToken');
        log({ deviceRegistrationTokenTypeLinkId });
        const selectData = {
            type_id: deviceRegistrationTokenTypeLinkId,
            in: {
                type_id: containTypeLinkId,
                from_id: deviceLinkId,
            },
        };
        log({ selectData });
        const { data: [deviceRegistrationTokenLink], } = await deep.select(selectData);
        if (!deviceRegistrationTokenLink) {
            throw new Error(`##${deviceLinkId} must have contained a link of type ##${deviceRegistrationTokenTypeLinkId}. Select with data ${JSON.stringify(selectData)} returned empty result`);
        }
        log({ deviceRegistrationTokenLink });
        if (!deviceRegistrationTokenLink.value?.value) {
            throw new Error(`##${deviceRegistrationTokenLink.id} must have value`);
        }
        const result = deviceRegistrationTokenLink.value.value;
        log({ result });
        return result;
    }
    async function getFirebaseApplication({ firebaseAdmin, serviceAccount }) {
        firebaseAdmin.apps.forEach((app) => app.delete());
        return firebaseAdmin.initializeApp({
            credential: firebaseAdmin.credential.cert(serviceAccount),
        });
    }
    function getNamespacedLogger({ namespace, depth = DEFAULT_LOG_DEPTH, }) {
        return function (content) {
            const message = util.inspect(content, { depth });
            logs.push(`${namespace}: ${message}`);
        };
    }
};
export {};
//# sourceMappingURL=module.js.map

Question

Is this the problem of js-docker-isolation-provider or @deep-foundation/tsx package? What should we do? The scariest thing is that I have been using handler code transpiled by that version of tsx package and everything was working. I do not know what is changed the way to brake it

@FreePhoenix888
Copy link
Member Author

I had conversation about this with chatgpt: https://chat.openai.com/share/452fcec7-ae51-49ab-9e0e-b22bd9c0e059

@FreePhoenix888
Copy link
Member Author

If I run this file (test.ts):

async ({ deep, data: { newLink: notifyLink, triggeredByLinkId }, }) => {
};
export {};
//# sourceMappingURL=module.js.map

by using

npx ts-node --esm test.ts 

It will run without problem

@FreePhoenix888
Copy link
Member Author

If I run this file (test.ts):

eval(`
async ({ deep, data: { newLink: notifyLink, triggeredByLinkId }, }) => {
};
export {};
//# sourceMappingURL=module.js.map
`)

by using

npx ts-node --esm test.ts 

It will throw the error:

freephoenix888@FreePhoenix:~/Programming/deep/deep-memo-app$ npx ts-node --esm test.ts 
SyntaxError: Unexpected token 'export'
    at file:///home/freephoenix888/Programming/deep/deep-memo-app/test.ts:1:1
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

@FreePhoenix888
Copy link
Member Author

FreePhoenix888 commented Aug 13, 2023

I have talked about this with GPT-4: https://chat.openai.com/share/5bbda39d-1ad5-4eb7-93f1-59061fe47a59

@Konard
Copy link
Member

Konard commented Mar 23, 2024

@FreePhoenix888 did you try to put export before the function? Our code expects that the last expression of the code string will be function expression.

@FreePhoenix888
Copy link
Member Author

@FreePhoenix888 did you try to put export before the function? Our code expects that the last expression of the code string will be function expression.

The reason is - tsx now transpiles ts to esnext (or smth like that) but code is executed by eval by js provider

Eval does not know what export is

As workaround I remove this export

@Konard
Copy link
Member

Konard commented Mar 23, 2024

@FreePhoenix888 I think we can close this issue in favor of #19

What do you think?
Or what is the specific reason to use export? Even if handler supports ts, why would you need to export anything from it?

@FreePhoenix888
Copy link
Member Author

@FreePhoenix888 I think we can close this issue in favor of #19

What do you think? Or what is the specific reason to use export? Even if handler supports ts, why would you need to export anything from it?

I do not export smth manually, export is added itself when tsx bundles to jsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants