2.0.1 • Published 11 months ago

solarwind v2.0.1

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

Solarwind / Modules

Solarwind

All-in-one full-stack package for managing complex web applications.

Solarwind is the full-stack package of choice for creating, managing, and scaling complex web applications with support for single-table design.

Using Solarwind you can quickly create types that can be easily extended, transformed into GraphQL, TypeScript, and used in both frontend and backend applications.

Table of Contents

  1. Typescript Infer
  2. Extending Types
  3. Static typescript Infer
  4. Printing Types as Typescript
  5. Validation
  6. Entity & CRUD
  7. GraphQL

Creating and extending types

import {
  createGraphQLSchema,
  createResolver,
  createType,
  createEntity,
  Infer,
} from 'solarwind';

const AddressType = createType('Address', {
  object: {
    street: 'string',
    number: {
      union: [
        'string',
        'int?',
      ],
    },
  },
});

const UserType = createType(
  {
    object: {
      name: 'string', // any string
      email: 'email?', // email type - will validate against email regex
      age: 'int?', // optional integer
      notes: '[int]?',

      // declaring a union field - will infer as `string | undefined | number[]`
      unionField: {
        union: [
          'string?',
          '[int]?',
        ],
      },

      // represents an enum
      letter: {
        enum: [
          'a',
          'b',
          'c',
        ],
      },

      // more detailed way to define enums
      letterOptionalList: {
        enum: [
          'x',
          'y',
          'z',
        ],
        optional: true,
        list: true,
      },

      // using a previous object as field type
      addresses: {
        type: AddressType,
        list: true,
      },

      // another way to define object fields
      deliveryAddress: {
        object: {
          street: 'string',
          number: 'int?',
        },
      },
    },
  } as const // "as const" is needed to TS to infer types correctly
);

Extending types

const StoreType = UserType.clone((it) =>
  it.exclude(['addresses']).extendObjectDefinition({ storeId: 'ID', ownerId: 'string' }).graphType('Store')
);

Static typescript infer

type TStoreType = Infer<typeof StoreType>;

Printing types as Typescript

const storeTS = await StoreType.typescriptPrint();

expect(storeTS.split('\n')).toEqual([
  'export interface Store {',
  '  name: string;',
  '  email?: Email;',
  '  age?: number;',
  '  notes?: number[];',
  '  unionField?: string | number[];',
  '  letter: "a" | "b" | "c";',
  '  letterOptionalList?: ("x" | "y" | "z")[];',
  '  deliveryAddress: {',
  '    street: string;',
  '    number?: number;',
  '  };',
  '  storeId: ID;',
  '  ownerId: string;',
  '}',
  '',
]);

Validation

try {
  const validStoreData = StoreType.parse({});
  console.log(validStoreData);
} catch (e) {
  /*
   *  Error: Store: ➤ field "ownerId": RequiredField.
   *           ➤ field "storeId": RequiredField.
   *           ➤ field "deliveryAddress": RequiredField.
   *           ➤ field "letter": RequiredField.
   *           ➤ field "name": RequiredField.
   */
}

Entity and CRUD

const StoreEntity = createEntity({
  name: 'Store',
  type: StoreType,
  indexes: [
    {
      name: 'id1', // index in database to be used
      PK: ['.storeId'],
    },
    {
      name: 'id2',
      PK: [
        '.ownerId',
        '.storeId',
      ],
    },
  ],
});

const findStoreResolver = createResolver({
  name: 'findStore',
  type: StoreEntity.edgeType,
  args: {
    storeId: 'string',
  },
}).resolver(async (_, { storeId /* ✨ automaticly typed as string */ }, requestContext) => {
  const filter = {
    storeId,
  };

  return StoreEntity.findOne({ filter, context: requestContext });
});

GraphQL

const graphqlSchema = createGraphQLSchema([findStoreResolver]);

const schemaTXT = graphqlSchema.utils.print();

expect(schemaTXT.split('\n')).toEqual([
  'type Query {',
  '  findStore(storeId: String!): Store_Edge!',
  '}',
  '',
  'type Store_Edge {',
  '  cursor: String!',
  '  node: StoreEntity!',
  '}',
  '',
  'type StoreEntity {',
  '  createdAt: Date!',
  '  createdBy: String',
  '  id: String!',
  '  ulid: Ulid!',
  '  updatedAt: Date!',
  '  updatedBy: String',
  '',
  '  """',
  '  The full string value of the first index following the RegExp format "^store⋮id1⋮.*"',
  '  """',
  '  _id: String!',
  '',
  '  """',
  '  The id1PK field in the RegExp format "^store⋮id1⋮.*"',
  '  """',
  '  id1PK: String!',
  '',
  '  """',
  '  The id2PK field in the RegExp format "^store⋮id2⋮.*"',
  '  """',
  '  id2PK: String!',
  '  name: String!',
  '  email: String',
  '  age: Int',
  '  notes: [Int]',
  '  unionField: StoreEntity_unionField',
  '  letter: StoreEntity_letter!',
  '  letterOptionalList: [StoreEntity_letterOptionalList]',
  '  deliveryAddress: StoreEntity_deliveryAddress!',
  '  storeId: ID!',
  '  ownerId: String!',
  '}',
  '',
  'scalar Date',
  '',
  'scalar Ulid',
  '',
  '"""',
  'Union of { optional:true, type: string } | { list:true, optional:true, type: int }',
  '"""',
  'scalar StoreEntity_unionField',
  '',
  'enum StoreEntity_letter {',
  '  a',
  '  b',
  '  c',
  '}',
  '',
  'enum StoreEntity_letterOptionalList {',
  '  x',
  '  y',
  '  z',
  '}',
  '',
  'type StoreEntity_deliveryAddress {',
  '  street: String!',
  '  number: Int',
  '}',
]);
1.0.14-rc10

11 months ago

1.0.11-beta.1

12 months ago

1.0.11-beta.3

12 months ago

1.0.11-beta.4

12 months ago

1.0.11-beta.5

12 months ago

2.0.1

11 months ago

1.0.14-0

12 months ago

1.0.14-rc9

11 months ago

1.0.14-rc8

11 months ago

1.0.14-rc5

11 months ago

1.0.14-rc4

11 months ago

1.0.14-rc7

11 months ago

1.0.14-rc6

11 months ago

1.0.14-rc1

11 months ago

1.0.14-rc3

11 months ago

1.0.14-rc2

11 months ago

1.0.11

12 months ago

1.0.12-beta.1

12 months ago

1.0.13

12 months ago

1.0.12

12 months ago

1.0.10

12 months ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.8-alpha

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.3

1 year ago

1.0.1

1 year ago

0.2.85

1 year ago

0.2.84

1 year ago

0.2.82

1 year ago

0.2.81

1 year ago

0.2.80

1 year ago

0.2.79

1 year ago

0.2.78

1 year ago

0.2.77

1 year ago

0.2.74

1 year ago

0.2.73

1 year ago

0.2.72

1 year ago

0.2.22

1 year ago

0.2.20

1 year ago

0.2.17

1 year ago

0.2.16

1 year ago

0.2.14

1 year ago

0.2.10

1 year ago