1.0.0-beta.128 • Published 4 months ago

@socialbaking/karma v1.0.0-beta.128

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

Karma - Node & JavaScript implementation

Support

Node.js supported

Test Coverage

59.91%25 lines covered 59.91%25 statements covered 47.37%25 functions covered 83.38%25 branches covered

Client's TypeScript Interface

export interface ClientOptions {
  partnerId?: string;
  accessToken?: string;
  version?: number;
  prefix?: string;
  url?: string | URL;
  fetch?: typeof fetch
}

export interface Client {
  addPartner(partner: PartnerData): Promise<Partner>;
  addCategory(category: CategoryData): Promise<Category>;
  addProduct(product: ProductData): Promise<Product>;
  addReport(report: ReportData): Promise<Report>;
  addReportMetrics(data: ReportMetricsData): Promise<ReportMetrics>;
  getProduct(productId: string): Promise<Product | undefined>;
  getReport(reportId: string): Promise<Report | undefined>;
  listPartners(): Promise<Partner[]>;
  listOrganisations(): Promise<Organisation[]>;
  listSystemLogs(): Promise<SystemLog[]>;
  listProducts(): Promise<Product[]>;
  listReports(): Promise<Report[]>;
  listCategories(): Promise<Category[]>;
  listDailyMetrics(): Promise<CountryProductMetrics[]>;
  listMonthlyMetrics(): Promise<CountryProductMetrics[]>;
  listMetrics(): Promise<CountryProductMetrics[]>;
  listReportMetrics(): Promise<ReportMetrics[]>;
  listProductMetrics(productId: string): Promise<CountryProductMetrics[]>;
  listCalculationKeys(): Promise<string[]>;
  listCalculations(): Promise<CalculationSource[]>;
  background(query: Record<string, string> | URLSearchParams): Promise<void>;
}

export type KarmaAuthenticationRole =
  | "moderator"
  | "admin"
  | "owner"
  | "patient"
  | "industry"
  | "member"
  | "pharmacy"
  | "clinic"
  | "booster"
  | "developer"
  | "coordinator"
  | "partner";

declare global {
    interface AuthenticationRoles extends Record<KarmaAuthenticationRole, KarmaAuthenticationRole> {
    }
}

// Used by client
type AuthenticationRole =
    | KarmaAuthenticationRole
    | keyof AuthenticationRoles;

export interface CalculationSource {
  calculationKey: string;
  title: string;
  description: string;
  anonymous: boolean;
}

export interface CategoryData extends Record<string, unknown> {
  categoryName: string;
  defaultUnit?: string;
  defaultSizes?: ProductSizeData[];
  countryCode?: string;
  order?: number;
  associatedTerms?: string[];
}

export interface Category extends CategoryData {
  categoryId: string;
  createdAt: string;
  updatedAt: string;
}

export interface Expiring {
  expiresAt?: string;
}

export type BaseFileStoreType = "product" | "inventory" | "productFile" | "inventoryFile"
export type BaseFileRemoteSourceName = "discord" | BaseFileStoreType;
export type RemoteFileSourceName = BaseFileRemoteSourceName | `${BaseFileRemoteSourceName}_${number}`;

export type FileUploadedSynced = "r2" | "disk";
export type FileType = BaseFileStoreType | `${RemoteFileSourceName}_import`;

export interface ResolvedFilePart extends Record<string, unknown> {

}

export interface FileImageSize extends Expiring {
    width: number;
    height: number;
    signed?: boolean;
    fileName?: string;
    checksum?: Record<string, string>
}

export interface FileSize extends FileImageSize {
    url: string;
    synced: FileUploadedSynced;
    syncedAt: string;
    version: number;
    watermark?: boolean;
    copyright?: string;
    license?: string;
    fileName?: string;
    signed?: boolean;
}

export interface FileErrorDescription {
    stack?: string;
    message: string;
    createdAt: string;
    repeated?: number;
}

export interface FileData extends Record<string, unknown>, Partial<FileImageSize> {
    fileName: string;
    contentType: string;
    size?: number;
    path?: string;
    url?: string;
    pinned?: boolean;
    uploadedAt?: string;
    uploadedByUsername?: string;
    source?: RemoteFileSourceName;
    sourceId?: string;
    synced?: FileUploadedSynced;
    syncedAt?: string;
    version?: number;
    type?: FileType | string;
    sizes?: FileSize[];
    /** @deprecated use remoteUrl */
    externalUrl?: string;
    remoteUrl?: string;
    reactionCounts?: Record<string, number>;
    reactionCountsUpdatedAt?: string;
    resolved?: ResolvedFilePart[];
    resolvedAt?: string;
    errors?: FileErrorDescription[];
}

export interface File extends FileData {
    fileId: string;
    createdAt: string;
    updatedAt: string;
    uploadedAt: string;
}

export interface ResolvedFile extends File {
    url: string;
    synced: FileUploadedSynced;
}

import {
  CalculationConsent,
  CalculationConsentItem,
  ReportDateData,
  ReportRoleData,
} from "../report";



export interface ActiveIngredientMetrics extends Record<string, unknown> {
  type: string;
  unit: string;
  value: string;
  // If the calculation of cost takes into account the
  // proportion of this vs total active ingredients
  proportional?: boolean;
  mean?: boolean;
  size?: ProductSizeData;
  prefix?: string;
  calculation?: "minimum" | "maximum" | "mean" | string;
}

export interface ProductMetricData extends Record<string, unknown> {
  productId: string;
  activeIngredients: ActiveIngredientMetrics[];
}

export interface MetricsData
  extends ReportDateData,
    Expiring,
    CalculationConsent {
  products: ProductMetricData[];
  countryCode: string;
  currencySymbol?: string; // "$"
  timezone?: string; // Pacific/Auckland
  anonymous?: boolean;
}

export interface ReportMetricsData extends MetricsData {
  parentReportId?: string;
  type?: string;
}

export interface ReportMetrics
  extends ReportMetricsData,
    ReportRoleData,
    Record<string, unknown> {
  type?: string;
  metricsId: string;
  reportId: string;
  reportedAt: string;
  createdAt: string;
  updatedAt: string;
  // consent required to be stored
  calculationConsent: CalculationConsentItem[];
}

export type CountryProductMetricDuration = "day" | "month";

export interface CountryProductMetrics extends MetricsData {
  metricsId: string;
  createdAt: string;
  updatedAt: string;
  currencySymbol: string; // "$"
  timezone: string;
  duration: CountryProductMetricDuration;
  reportingDateKey: keyof ReportDateData;
}

export {
    Offer,
    OfferData,
    OfferItem,
    OfferItemType,
    OfferPrice,
    OfferStatus,
    InventoryOffer,
    OrderOfferItem,
    ProductOfferItem,
} from "@opennetwork/logistics";

export interface OrganisationBaseData extends Record<string, unknown> {
  countryCode?: string; // "NZ"
  location?: string;
  remote?: boolean;
  onsite?: boolean;
  pharmacy?: boolean;
  delivery?: boolean;
  clinic?: boolean;
  website?: string;
  associatedBrandingTerms?: string[]; // Eg common names used to refer to the organisation by way of brand
}

export interface OrganisationData extends OrganisationBaseData {
  organisationName: string;
  partnerId?: string;
  approved?: boolean;
  approvedAt?: string;
}

export interface Organisation extends OrganisationData {
  organisationId: string;
  createdAt: string;
  updatedAt: string;
  approvedByUserId?: string;
}

export interface PartnerData extends Record<string, unknown> {
  partnerName: string;
  countryCode?: string;
}

export interface AddPartnerData extends PartnerData, OrganisationBaseData {}

export interface Partner extends PartnerData {
  partnerId: string;
  organisationId: string;
  accessToken?: string;
  createdAt: string;
  updatedAt: string;
  approved?: boolean;
  approvedAt?: string;
  approvedByUserId?: string;
}

export interface ProductTemperature {
  value: string;
  unit?: string;
}

export interface ProductIngredient {
  name: string;
  active?: boolean;
  boil?: ProductTemperature;
}

export interface ProductSizeData extends Record<string, unknown> {
  value: string;
  unit: string;
}

export interface ProductInfo {
  title?: string;
  text: string;
  url?: string;
  description?: string;
}

export interface ProductFile extends Partial<FileData> {
  fileId: string;
}

export interface ProductData extends Record<string, unknown> {
  productName: string;
  order?: number;
  countryCode?: string;
  organisationId?: string;
  licencedOrganisationId?: string;
  // Flag for products we don't have the exact licence date for
  licenceApprovedBeforeGivenDate?: boolean;
  licenceApprovedAt?: string;
  licenceExpiredAt?: string;
  licenceApprovalWebsite?: string;
  // ISO 3166-1 alpha-3 country code
  licenceCountryCode?: string;
  // Flag for products we don't have the exact availability date for
  availableBeforeGivenDate?: boolean;
  availableAt?: string;
  // For products that we will no longer have available
  availableUntil?: string;
  sizes?: ProductSizeData[];
  // Direct text about the active ingredients, not specific values
  activeIngredientDescriptions?: string[];
  categoryId?: string;
  generic?: boolean;
  public?: boolean;
  branded?: boolean;
  genericSearchTerm?: string;
  genericCategoryNames?: string[];
  genericAcronym?: string;
  info?: ProductInfo[];
  files?: ProductFile[];
  obsoleteAt?: string;
  ingredients?: ProductIngredient[];
}

export interface ProductActiveIngredient {
  type: string;
  unit: string;
  value: string;
  prefix?: string;
  calculated?: boolean;
  calculatedUnit?: string;
  size?: ProductSizeData;
  proportional?: boolean;
}

export interface Product extends ProductData {
  productId: string;
  createdAt: string;
  updatedAt: string;
  activeIngredients?: ProductActiveIngredient[];
}

export interface ReportDateData {
  orderedAt?: string;
  shippedAt?: string;
  receivedAt?: string;
  updatedAt?: string;
  createdAt?: string;
  reportedAt?: string;
}

export interface CalculationConsentItem extends Record<string, unknown> {
  calculationKey: string;
  consented?: boolean;
  consentedAt?: string;
}

export interface CalculationConsent {
  calculationConsent?: CalculationConsentItem[];
}

export interface ReportRoleData {
  roles: AuthenticationRole[];
}

export type ReportType = "purchase" | "product" | "poll";

export interface DeprecatedReportData {
  // TODO No longer used fields, but keeping around until v1.0.0
  productPurchase?: boolean;
  productPurchaseTotalCost?: string | number; // "908.50", capture the user input raw
  productPurchaseItems?: string | number; // "2", capture the user input raw
  productPurchaseItemCost?: string | number; // "450", capture the user input raw
  productPurchaseDeliveryCost?: string | number; // "8.50", capture the user input raw
  productPurchaseFeeCost?: string | number; // "3.50", capture the user input raw
  productPurchaseOrganisationId?: string;
  productPurchaseOrganisationName?: string; // Actual organisationName, not free text
  productPurchaseOrganisationText?: string; // User free text of the organisationName
}

type StringNumber = `${number}` | number | string;

export interface ProductReviewReportData {
  comment?: string;
  rating?: string | `${number}` | number;
  vibes?: string;
}
export interface ProductReportData extends DeprecatedReportData, ProductReviewReportData {
  productId?: string;
  productName?: string; // Actual productName, not free text
  productText?: string; // User free text of the product
  productSize?: ProductSizeData;
  productTotalCost: StringNumber; // "908.50", capture the user input raw
  productItems: StringNumber; // "2", capture the user input raw
  productItemCost: StringNumber; // "450", capture the user input raw
  productDeliveryCost?: StringNumber; // "8.50", capture the user input raw
  productFeeCost?: StringNumber; // "3.50", capture the user input raw
  productOrganisationId?: string;
  productOrganisationName?: string; // Actual organisationName, not free text
  productOrganisationText?: string; // User free text of the organisationName
}

export interface PollReportOptionData extends Partial<ActiveIngredientMetrics> {
  title: string;
  votes: `${number}` | string;
}

export interface PollReportData {
  title: string;
  url?: string;
  options: PollReportOptionData[];
}

export type PartialReportData = Partial<PollReportData> & Partial<ProductReportData>

export interface ReportData
  extends ReportDateData,
    Expiring,
    CalculationConsent,
    PartialReportData,
    Record<string, unknown> {
  type: ReportType | string;
  countryCode: string; // "NZ"
  currencySymbol?: string; // "$"
  timezone?: string; // Pacific/Auckland
  note?: string;
  parentReportId?: string;
  createdByUserId?: string;
  createdByPartnerId?: string;
  anonymous?: boolean;
}

export interface Report extends ReportData, ReportRoleData {
  reportId: string;
  createdAt: string;
  updatedAt: string;
  reportedAt: string;
  reports?: Report[];
}

export interface SystemLogData extends Record<string, unknown> {
  uniqueCode?: string;
  value?: number;
  partnerId: string;
  message: string;
  timestamp?: string;
  action?: string;
}

export interface SystemLog extends SystemLogData {
  systemLogId: string;
  timestamp: string;
}

Local Development

Dependencies

You will need to install the dependencies with yarn

Once you have yarn installed, use the command:

yarn

.env

First you will need to set up a .env file in the same directory as this README.md file

Copy the .env.example to make your .env file

Reddit

To setup reddit authentication, you will need to either be provided a client ID if you're working with the socialbaking team, or you will need to create a new application at the bottom of this screen

The local redirect url is http://localhost:3000/api/authentication/reddit/callback

Once created, copy the value under "web app" and set that as your REDDIT_CLIENT_ID

Copy the "secret" and set that as REDDIT_CLIENT_SECRET

Set the reddit community name, and associated flair, as you see fit:

REDDIT_NAME=MedicalCannabisNZ
REDDIT_FLAIR="Medical Patient"
1.0.0-beta.127

4 months ago

1.0.0-beta.128

4 months ago

1.0.0-beta.126

4 months ago

1.0.0-beta.125

5 months ago

1.0.0-beta.123

5 months ago

1.0.0-beta.121

7 months ago

1.0.0-beta.122

7 months ago

1.0.0-beta.120

7 months ago

1.0.0-beta.115

10 months ago

1.0.0-beta.118

10 months ago

1.0.0-beta.119

10 months ago

1.0.0-beta.116

10 months ago

1.0.0-beta.117

10 months ago

1.0.0-beta.114

10 months ago

1.0.0-beta.113

10 months ago

1.0.0-beta.112

10 months ago

1.0.0-beta.111

10 months ago

1.0.0-beta.110

10 months ago

1.0.0-beta.109

10 months ago

1.0.0-beta.108

10 months ago

1.0.0-beta.107

10 months ago

1.0.0-beta.106

10 months ago

1.0.0-beta.105

10 months ago

1.0.0-beta.104

10 months ago

1.0.0-beta.103

10 months ago

1.0.0-beta.102

11 months ago

1.0.0-beta.101

11 months ago

1.0.0-beta.100

11 months ago

1.0.0-beta.99

11 months ago

1.0.0-beta.98

11 months ago

1.0.0-beta.97

11 months ago

1.0.0-beta.96

11 months ago

1.0.0-beta.95

11 months ago

1.0.0-beta.94

11 months ago

1.0.0-beta.93

11 months ago

1.0.0-beta.92

11 months ago

1.0.0-beta.91

11 months ago

1.0.0-beta.90

11 months ago

1.0.0-beta.89

11 months ago

1.0.0-beta.88

11 months ago

1.0.0-beta.87

11 months ago

1.0.0-beta.86

11 months ago

1.0.0-beta.85

11 months ago

1.0.0-beta.84

11 months ago

1.0.0-beta.83

11 months ago

1.0.0-beta.82

11 months ago

1.0.0-beta.81

11 months ago

1.0.0-beta.80

11 months ago

1.0.0-beta.79

11 months ago

1.0.0-beta.78

11 months ago

1.0.0-beta.77

11 months ago

1.0.0-beta.76

11 months ago

1.0.0-beta.75

11 months ago

1.0.0-beta.74

11 months ago

1.0.0-beta.73

11 months ago

1.0.0-beta.72

11 months ago

1.0.0-beta.71

11 months ago

1.0.0-beta.70

11 months ago

1.0.0-beta.69

11 months ago

1.0.0-beta.68

11 months ago

1.0.0-beta.66

11 months ago

1.0.0-beta.65

11 months ago

1.0.0-beta.64

11 months ago

1.0.0-beta.63

11 months ago

1.0.0-beta.62

11 months ago

1.0.0-beta.61

11 months ago

1.0.0-beta.60

11 months ago

1.0.0-beta.59

11 months ago

1.0.0-beta.58

11 months ago

1.0.0-beta.57

11 months ago

1.0.0-beta.56

11 months ago

1.0.0-beta.55

11 months ago

1.0.0-beta.54

11 months ago

1.0.0-beta.53

11 months ago

1.0.0-beta.52

11 months ago

1.0.0-beta.51

11 months ago

1.0.0-beta.50

11 months ago

1.0.0-beta.49

11 months ago

1.0.0-beta.48

11 months ago

1.0.0-beta.47

11 months ago

1.0.0-beta.46

11 months ago

1.0.0-beta.45

11 months ago

1.0.0-beta.44

11 months ago

1.0.0-beta.43

11 months ago

1.0.0-beta.42

11 months ago

1.0.0-beta.41

11 months ago

1.0.0-beta.40

11 months ago

1.0.0-beta.39

11 months ago

1.0.0-beta.38

11 months ago

1.0.0-beta.37

11 months ago

1.0.0-beta.36

11 months ago

1.0.0-beta.35

11 months ago

1.0.0-beta.34

11 months ago

1.0.0-beta.33

11 months ago

1.0.0-beta.32

11 months ago

1.0.0-beta.31

11 months ago

1.0.0-beta.29

11 months ago

1.0.0-beta.28

11 months ago

1.0.0-beta.27

11 months ago

1.0.0-beta.26

11 months ago

1.0.0-beta.25

11 months ago

1.0.0-beta.24

11 months ago

1.0.0-beta.23

11 months ago

1.0.0-beta.22

11 months ago

1.0.0-beta.21

11 months ago

1.0.0-beta.20

11 months ago

1.0.0-beta.19

11 months ago

1.0.0-beta.18

11 months ago

1.0.0-beta.17

11 months ago

1.0.0-beta.16

11 months ago

1.0.0-beta.15

11 months ago

1.0.0-beta.14

11 months ago

1.0.0-beta.13

11 months ago

1.0.0-beta.12

11 months ago

1.0.0-beta.11

11 months ago

1.0.0-beta.10

11 months ago

1.0.0-beta.9

11 months ago

1.0.0-beta.8

12 months ago

1.0.0-beta.7

12 months ago

1.0.0-beta.6

12 months ago

1.0.0-beta.5

12 months ago

1.0.0-beta.4

12 months ago

1.0.0-beta.3

12 months ago

1.0.0-beta.2

12 months ago

1.0.0-beta.1

12 months ago

1.0.0-beta.0

12 months ago

1.0.0-alpha.130

12 months ago

1.0.0-alpha.129

12 months ago

1.0.0-alpha.128

12 months ago

1.0.0-alpha.127

12 months ago

1.0.0-alpha.126

12 months ago

1.0.0-alpha.125

12 months ago

1.0.0-alpha.124

12 months ago

1.0.0-alpha.123

12 months ago

1.0.0-alpha.122

12 months ago

1.0.0-alpha.121

12 months ago

1.0.0-alpha.120

12 months ago

1.0.0-alpha.119

12 months ago

1.0.0-alpha.118

12 months ago

1.0.0-alpha.117

12 months ago

1.0.0-alpha.116

12 months ago

1.0.0-alpha.115

12 months ago

1.0.0-alpha.114

12 months ago

1.0.0-alpha.113

12 months ago

1.0.0-alpha.112

12 months ago

1.0.0-alpha.111

12 months ago

1.0.0-alpha.110

12 months ago

1.0.0-alpha.109

12 months ago

1.0.0-alpha.108

12 months ago

1.0.0-alpha.107

12 months ago

1.0.0-alpha.106

12 months ago

1.0.0-alpha.105

12 months ago

1.0.0-alpha.104

12 months ago

1.0.0-alpha.103

12 months ago

1.0.0-alpha.102

12 months ago

1.0.0-alpha.101

12 months ago

1.0.0-alpha.100

12 months ago

1.0.0-alpha.99

12 months ago

1.0.0-alpha.98

12 months ago

1.0.0-alpha.97

12 months ago

1.0.0-alpha.96

12 months ago

1.0.0-alpha.95

12 months ago

1.0.0-alpha.94

12 months ago

1.0.0-alpha.93

12 months ago

1.0.0-alpha.92

12 months ago

1.0.0-alpha.91

12 months ago

1.0.0-alpha.90

12 months ago

1.0.0-alpha.89

12 months ago

1.0.0-alpha.88

12 months ago

1.0.0-alpha.87

12 months ago

1.0.0-alpha.86

12 months ago

1.0.0-alpha.85

12 months ago

1.0.0-alpha.84

12 months ago

1.0.0-alpha.83

12 months ago

1.0.0-alpha.82

12 months ago

1.0.0-alpha.81

12 months ago

1.0.0-alpha.80

12 months ago

1.0.0-alpha.79

12 months ago

1.0.0-alpha.78

12 months ago

1.0.0-alpha.77

12 months ago

1.0.0-alpha.76

12 months ago

1.0.0-alpha.75

12 months ago

1.0.0-alpha.74

12 months ago

1.0.0-alpha.73

12 months ago

1.0.0-alpha.72

12 months ago

1.0.0-alpha.71

12 months ago

1.0.0-alpha.70

12 months ago