@smartive/graphql-magic 14.1.0 → 15.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.env +1 -1
  2. package/CHANGELOG.md +3 -3
  3. package/README.md +1 -36
  4. package/dist/bin/gqm.cjs +171 -123
  5. package/dist/cjs/index.cjs +133 -118
  6. package/dist/esm/context.d.ts +1 -1
  7. package/dist/esm/models/utils.d.ts +4 -4
  8. package/dist/esm/permissions/check.d.ts +1 -0
  9. package/dist/esm/permissions/check.js +19 -11
  10. package/dist/esm/permissions/check.js.map +1 -1
  11. package/dist/esm/resolvers/filters.js +1 -1
  12. package/dist/esm/resolvers/filters.js.map +1 -1
  13. package/dist/esm/resolvers/mutations.js +4 -4
  14. package/dist/esm/resolvers/mutations.js.map +1 -1
  15. package/dist/esm/resolvers/resolver.js +3 -0
  16. package/dist/esm/resolvers/resolver.js.map +1 -1
  17. package/dist/esm/resolvers/resolvers.d.ts +1 -1
  18. package/dist/esm/resolvers/resolvers.js +29 -23
  19. package/dist/esm/resolvers/resolvers.js.map +1 -1
  20. package/dist/esm/resolvers/selects.js +4 -3
  21. package/dist/esm/resolvers/selects.js.map +1 -1
  22. package/dist/esm/schema/generate.js +76 -72
  23. package/dist/esm/schema/generate.js.map +1 -1
  24. package/docker-compose.yml +0 -4
  25. package/docs/README.md +41 -0
  26. package/docs/babel.config.js +3 -0
  27. package/docs/docs/tutorial.md +425 -0
  28. package/docs/docusaurus.config.ts +110 -0
  29. package/docs/package-lock.json +14680 -0
  30. package/docs/package.json +47 -0
  31. package/docs/sidebars.ts +31 -0
  32. package/docs/src/css/custom.css +30 -0
  33. package/docs/src/pages/index.module.css +23 -0
  34. package/docs/src/pages/index.tsx +39 -0
  35. package/docs/src/pages/markdown-page.md +7 -0
  36. package/docs/static/.nojekyll +0 -0
  37. package/docs/static/img/docusaurus-social-card.jpg +0 -0
  38. package/docs/static/img/docusaurus.png +0 -0
  39. package/docs/static/img/favicon.ico +0 -0
  40. package/docs/static/img/logo.svg +1 -0
  41. package/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  42. package/docs/static/img/undraw_docusaurus_react.svg +170 -0
  43. package/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  44. package/docs/tsconfig.json +7 -0
  45. package/package.json +5 -5
  46. package/src/bin/gqm/codegen.ts +3 -1
  47. package/src/bin/gqm/gqm.ts +3 -69
  48. package/src/bin/gqm/parse-knexfile.ts +5 -6
  49. package/src/bin/gqm/settings.ts +32 -5
  50. package/src/bin/gqm/templates.ts +60 -8
  51. package/src/context.ts +1 -1
  52. package/src/permissions/check.ts +24 -16
  53. package/src/resolvers/filters.ts +1 -1
  54. package/src/resolvers/mutations.ts +4 -4
  55. package/src/resolvers/resolver.ts +4 -0
  56. package/src/resolvers/resolvers.ts +33 -27
  57. package/src/resolvers/selects.ts +4 -3
  58. package/src/schema/generate.ts +78 -72
package/.env CHANGED
@@ -1,4 +1,4 @@
1
1
  DATABASE_HOST=localhost
2
2
  DATABASE_NAME=postgres
3
3
  DATABASE_USER=postgres
4
- DATABAE_PASSWORD=password
4
+ DATABASE_PASSWORD=password
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
- # [14.1.0](https://github.com/smartive/graphql-magic/compare/v14.0.2...v14.1.0) (2024-03-04)
1
+ ## [15.0.1](https://github.com/smartive/graphql-magic/compare/v15.0.0...v15.0.1) (2024-04-03)
2
2
 
3
3
 
4
- ### Features
4
+ ### Bug Fixes
5
5
 
6
- * Add display to relation ([#143](https://github.com/smartive/graphql-magic/issues/143)) ([58e3bf8](https://github.com/smartive/graphql-magic/commit/58e3bf80ea9be367a20b4a5a7129a68c21e2e75a))
6
+ * Stuff ([#152](https://github.com/smartive/graphql-magic/issues/152)) ([be06252](https://github.com/smartive/graphql-magic/commit/be0625222485da5ddb22b0d9feaf3ac7fdccd1a6))
package/README.md CHANGED
@@ -2,42 +2,7 @@
2
2
 
3
3
  Welcome to graphql-magic!
4
4
 
5
- ## Usage
6
-
7
- ### Prerequisites
8
-
9
- * Next.js
10
- * TypeScript
11
- * Knex.js
12
- * Postgresql
13
-
14
- ### Setup
15
-
16
- Dependencies:
17
-
18
- ```
19
- npm i @smartive/graphql-magic
20
- ```
21
-
22
- Setup:
23
-
24
- ```
25
- npx gqm setup
26
- ```
27
-
28
- Generate all the things:
29
-
30
- ```
31
- npx gqm generate
32
- ```
33
-
34
- Generate a migration:
35
-
36
- ```
37
- npx gqm generate-migration
38
- ```
39
-
40
- To be continued...
5
+ See the [docs](https://)
41
6
 
42
7
  ## Development
43
8
 
package/dist/bin/gqm.cjs CHANGED
@@ -1343,7 +1343,7 @@ var generateDefinitions = ({
1343
1343
  entities,
1344
1344
  objects
1345
1345
  }) => {
1346
- return [
1346
+ const definitions = [
1347
1347
  // Predefined types
1348
1348
  ...rawEnums.map((model) => enm(model.name, model.values)),
1349
1349
  ...enums.map((model) => enm(model.name, model.values)),
@@ -1487,80 +1487,84 @@ var generateDefinitions = ({
1487
1487
  ]
1488
1488
  })),
1489
1489
  ...objects.filter((model) => model.name === "Query").flatMap((model) => model.fields)
1490
- ]),
1491
- object("Mutation", [
1492
- ...entities.flatMap((model) => {
1493
- const mutations = [];
1494
- if (!isRootModel(model)) {
1495
- if (model.creatable) {
1496
- mutations.push({
1497
- name: `create${model.name}`,
1498
- type: model.name,
1499
- nonNull: true,
1500
- args: [
1501
- {
1502
- name: "data",
1503
- type: `Create${model.name}`,
1504
- nonNull: true
1505
- }
1506
- ]
1507
- });
1508
- }
1509
- if (model.updatable) {
1510
- mutations.push({
1511
- name: `update${model.name}`,
1512
- type: model.name,
1513
- nonNull: true,
1514
- args: [
1515
- {
1516
- name: "where",
1517
- type: `${model.name}WhereUnique`,
1518
- nonNull: true
1519
- },
1520
- {
1521
- name: "data",
1522
- type: `Update${model.name}`,
1523
- nonNull: true
1524
- }
1525
- ]
1526
- });
1527
- }
1528
- if (model.deletable) {
1529
- mutations.push({
1530
- name: `delete${model.name}`,
1531
- type: "ID",
1532
- nonNull: true,
1533
- args: [
1534
- {
1535
- name: "where",
1536
- type: `${model.name}WhereUnique`,
1537
- nonNull: true
1538
- },
1539
- {
1540
- name: "dryRun",
1541
- type: "Boolean"
1542
- }
1543
- ]
1544
- });
1545
- mutations.push({
1546
- name: `restore${model.name}`,
1547
- type: "ID",
1548
- nonNull: true,
1549
- args: [
1550
- {
1551
- name: "where",
1552
- type: `${model.name}WhereUnique`,
1553
- nonNull: true
1554
- }
1555
- ]
1556
- });
1557
- }
1558
- }
1559
- return mutations;
1560
- }),
1561
- ...objects.filter((model) => model.name === "Mutation").flatMap((model) => model.fields)
1562
1490
  ])
1563
1491
  ];
1492
+ const mutations = [
1493
+ ...entities.flatMap((model) => {
1494
+ const mutations2 = [];
1495
+ if (!isRootModel(model)) {
1496
+ if (model.creatable) {
1497
+ mutations2.push({
1498
+ name: `create${model.name}`,
1499
+ type: model.name,
1500
+ nonNull: true,
1501
+ args: [
1502
+ {
1503
+ name: "data",
1504
+ type: `Create${model.name}`,
1505
+ nonNull: true
1506
+ }
1507
+ ]
1508
+ });
1509
+ }
1510
+ if (model.updatable) {
1511
+ mutations2.push({
1512
+ name: `update${model.name}`,
1513
+ type: model.name,
1514
+ nonNull: true,
1515
+ args: [
1516
+ {
1517
+ name: "where",
1518
+ type: `${model.name}WhereUnique`,
1519
+ nonNull: true
1520
+ },
1521
+ {
1522
+ name: "data",
1523
+ type: `Update${model.name}`,
1524
+ nonNull: true
1525
+ }
1526
+ ]
1527
+ });
1528
+ }
1529
+ if (model.deletable) {
1530
+ mutations2.push({
1531
+ name: `delete${model.name}`,
1532
+ type: "ID",
1533
+ nonNull: true,
1534
+ args: [
1535
+ {
1536
+ name: "where",
1537
+ type: `${model.name}WhereUnique`,
1538
+ nonNull: true
1539
+ },
1540
+ {
1541
+ name: "dryRun",
1542
+ type: "Boolean"
1543
+ }
1544
+ ]
1545
+ });
1546
+ mutations2.push({
1547
+ name: `restore${model.name}`,
1548
+ type: "ID",
1549
+ nonNull: true,
1550
+ args: [
1551
+ {
1552
+ name: "where",
1553
+ type: `${model.name}WhereUnique`,
1554
+ nonNull: true
1555
+ }
1556
+ ]
1557
+ });
1558
+ }
1559
+ }
1560
+ return mutations2;
1561
+ }),
1562
+ ...objects.filter((model) => model.name === "Mutation").flatMap((model) => model.fields)
1563
+ ];
1564
+ if (mutations.length) {
1565
+ definitions.push(object("Mutation", mutations));
1566
+ }
1567
+ return definitions;
1564
1568
  };
1565
1569
  var generate = (models) => document(generateDefinitions(models));
1566
1570
  var printSchema = (schema) => [
@@ -1593,10 +1597,14 @@ var readLine = (prompt) => {
1593
1597
  };
1594
1598
 
1595
1599
  // src/bin/gqm/templates.ts
1596
- var EMPTY_MODELS = `
1597
- import { RawModels, Models } from '@smartive/graphql-magic';
1600
+ var GITIGNORE = (path) => `
1601
+ # graphql-magic
1602
+ ${path}/**/*
1603
+ ${path}/**/.gitkeep
1604
+ `;
1605
+ var EMPTY_MODELS = `import { ModelDefinitions, Models } from '@smartive/graphql-magic';
1598
1606
 
1599
- const rawModels: RawModels = [
1607
+ const modelDefinitions: ModelDefinitions = [
1600
1608
  {
1601
1609
  kind: 'entity',
1602
1610
  name: 'User',
@@ -1604,10 +1612,9 @@ const rawModels: RawModels = [
1604
1612
  },
1605
1613
  ]
1606
1614
 
1607
- export const models = new Models(rawModels);
1615
+ export const models = new Models(modelDefinitions);
1608
1616
  `;
1609
- var KNEXFILE = `
1610
- import { DateTime } from 'luxon';
1617
+ var KNEXFILE = `import { DateTime } from 'luxon';
1611
1618
  import { types } from 'pg';
1612
1619
 
1613
1620
  const dateOids = { date: 1082, timestamptz: 1184, timestamp: 1114 };
@@ -1620,7 +1627,7 @@ for (const oid of Object.values(numberOids)) {
1620
1627
  types.setTypeParser(oid, Number);
1621
1628
  }
1622
1629
 
1623
- const config = {
1630
+ const knexConfig = {
1624
1631
  client: 'postgresql',
1625
1632
  connection: {
1626
1633
  host: process.env.DATABASE_HOST,
@@ -1637,12 +1644,75 @@ const config = {
1637
1644
  },
1638
1645
  } as const;
1639
1646
 
1640
- export default config;
1647
+ export default knexConfig;
1648
+ `;
1649
+ var GET_ME = `import { gql } from '@smartive/graphql-magic';
1650
+
1651
+ export const GET_ME = gql\`
1652
+ query GetMe {
1653
+ me {
1654
+ id
1655
+ }
1656
+ }
1657
+ \`;
1658
+ `;
1659
+ var EXECUTE = `
1660
+ import knexConfig from "@/knexfile";
1661
+ import { Context, User, execute } from "@smartive/graphql-magic";
1662
+ import { randomUUID } from "crypto";
1663
+ import { knex } from 'knex';
1664
+ import { DateTime } from "luxon";
1665
+ import { models } from "../config/models";
1666
+
1667
+ export const executeGraphql = async <T, V = undefined>(
1668
+ body: {
1669
+ query: string;
1670
+ operationName?: string;
1671
+ variables?: V;
1672
+ options?: { email?: string };
1673
+ }): Promise<{ data: T }> => {
1674
+ const db = knex(knexConfig);
1675
+ let user: User | undefined;
1676
+ // TODO: get user
1677
+
1678
+ const result = await execute({
1679
+ req: null as unknown as Context['req'],
1680
+ body,
1681
+ knex: db as unknown as Context['knex'],
1682
+ locale: 'en',
1683
+ locales: ['en'],
1684
+ user,
1685
+ models: models,
1686
+ permissions: { ADMIN: true, UNAUTHENTICATED: true },
1687
+ now: DateTime.local(),
1688
+ });
1689
+ await db.destroy();
1690
+
1691
+ // https://github.com/vercel/next.js/issues/47447#issuecomment-1500371732
1692
+ return JSON.parse(JSON.stringify(result)) as { data: T };
1693
+ }
1641
1694
  `;
1642
1695
 
1643
1696
  // src/bin/gqm/settings.ts
1644
1697
  var SETTINGS_PATH = ".gqmrc.json";
1698
+ var DEFAULT_ENV = {
1699
+ DATABASE_HOST: "localhost",
1700
+ DATABASE_NAME: "postgres",
1701
+ DATABASE_USER: "postgres",
1702
+ DATABASE_PASSWORD: "password"
1703
+ };
1645
1704
  var DEFAULTS = {
1705
+ knexfilePath: {
1706
+ question: "What is the knexfile path?",
1707
+ defaultValue: "knexfile.ts",
1708
+ init: (path) => {
1709
+ for (const [name2, value2] of Object.entries(DEFAULT_ENV)) {
1710
+ ensureFileContains(".env", `${name2}=`, `${name2}=${value2}
1711
+ `);
1712
+ }
1713
+ ensureFileExists(path, KNEXFILE);
1714
+ }
1715
+ },
1646
1716
  modelsPath: {
1647
1717
  question: "What is the models path?",
1648
1718
  defaultValue: "src/config/models.ts",
@@ -1654,6 +1724,7 @@ var DEFAULTS = {
1654
1724
  question: "What is the path for generated stuff?",
1655
1725
  defaultValue: "src/generated",
1656
1726
  init: (path) => {
1727
+ ensureFileContains(".gitignore", GITIGNORE(path));
1657
1728
  ensureFileExists(`${path}/.gitkeep`, "");
1658
1729
  ensureFileExists(`${path}/db/.gitkeep`, "");
1659
1730
  ensureFileExists(`${path}/api/.gitkeep`, "");
@@ -1661,10 +1732,11 @@ var DEFAULTS = {
1661
1732
  }
1662
1733
  },
1663
1734
  graphqlQueriesPath: {
1664
- question: "Where to look for graphql queries?",
1665
- defaultValue: "src/graphql/client/queries",
1735
+ question: "Where to put graphql code?",
1736
+ defaultValue: "src/graphql",
1666
1737
  init: (path) => {
1667
- ensureDirectoryExists(path);
1738
+ ensureFileExists(`${path}/client/queries/get-me.ts`, GET_ME);
1739
+ ensureFileExists(`${path}/execute.ts`, EXECUTE);
1668
1740
  }
1669
1741
  },
1670
1742
  gqlModule: {
@@ -1730,6 +1802,13 @@ var ensureFileExists = (filePath, content) => {
1730
1802
  (0, import_fs.writeFileSync)(filePath, content);
1731
1803
  }
1732
1804
  };
1805
+ var ensureFileContains = (filePath, content, fallback) => {
1806
+ ensureFileExists(filePath, "");
1807
+ const fileContent = (0, import_fs.readFileSync)(filePath, "utf-8");
1808
+ if (!fileContent.includes(content)) {
1809
+ (0, import_fs.writeFileSync)(filePath, fileContent + (fallback ?? content));
1810
+ }
1811
+ };
1733
1812
  var writeToFile = (filePath, content) => {
1734
1813
  ensureDirectoryExists((0, import_path.dirname)(filePath));
1735
1814
  if ((0, import_fs.existsSync)(filePath)) {
@@ -1767,6 +1846,7 @@ var generateGraphqlApiTypes = async () => {
1767
1846
  var generateGraphqlClientTypes = async () => {
1768
1847
  const generatedFolderPath = await getSetting("generatedFolderPath");
1769
1848
  const graphqlQueriesPath = await getSetting("graphqlQueriesPath");
1849
+ ensureDirectoryExists(graphqlQueriesPath);
1770
1850
  await (0, import_cli.generate)({
1771
1851
  schema: `${generatedFolderPath}/schema.graphql`,
1772
1852
  documents: [graphqlQueriesPath, `${generatedFolderPath}/client/mutations.ts`],
@@ -1790,7 +1870,8 @@ var generateGraphqlClientTypes = async () => {
1790
1870
  },
1791
1871
  scalars: {
1792
1872
  DateTime: "string"
1793
- }
1873
+ },
1874
+ ignoreNoDocuments: true
1794
1875
  }
1795
1876
  });
1796
1877
  };
@@ -2038,16 +2119,16 @@ var findDeclaration = (syntaxList, name2) => {
2038
2119
  };
2039
2120
 
2040
2121
  // src/bin/gqm/parse-knexfile.ts
2041
- var KNEXFILE_PATH = `knexfile.ts`;
2042
2122
  var parseKnexfile = async () => {
2043
2123
  const project = new import_ts_morph4.Project({
2044
2124
  manipulationSettings: {
2045
2125
  indentationText: import_ts_morph4.IndentationText.TwoSpaces
2046
2126
  }
2047
2127
  });
2048
- ensureFileExists(KNEXFILE_PATH, KNEXFILE);
2049
- const sourceFile = project.addSourceFileAtPath(KNEXFILE_PATH);
2050
- const configDeclaration = findDeclarationInFile(sourceFile, "config");
2128
+ const knexfilePath = await getSetting("knexfilePath");
2129
+ ensureFileExists(knexfilePath, KNEXFILE);
2130
+ const sourceFile = project.addSourceFileAtPath(knexfilePath);
2131
+ const configDeclaration = findDeclarationInFile(sourceFile, "knexConfig");
2051
2132
  const config2 = staticEval(configDeclaration, {});
2052
2133
  return config2;
2053
2134
  };
@@ -2077,11 +2158,8 @@ var parseModels = async () => {
2077
2158
  path: ".env.local"
2078
2159
  });
2079
2160
  import_commander.program.description("The graphql-magic cli.");
2080
- import_commander.program.command("setup").description("Set up the project").action(async () => {
2081
- await getSettings();
2082
- ensureFileExists(KNEXFILE_PATH, KNEXFILE);
2083
- });
2084
2161
  import_commander.program.command("generate").description("Generate all the things").action(async () => {
2162
+ await getSetting("knexfilePath");
2085
2163
  const models = await parseModels();
2086
2164
  const generatedFolderPath = await getSetting("generatedFolderPath");
2087
2165
  const gqlModule = await getSetting("gqlModule");
@@ -2092,36 +2170,6 @@ import_commander.program.command("generate").description("Generate all the thing
2092
2170
  await generateGraphqlApiTypes();
2093
2171
  await generateGraphqlClientTypes();
2094
2172
  });
2095
- import_commander.program.command("generate-models").description("Generate models.json").action(async () => {
2096
- await parseModels();
2097
- });
2098
- import_commander.program.command("generate-schema").description("Generate schema").action(async () => {
2099
- const models = await parseModels();
2100
- const generatedFolderPath = await getSetting("generatedFolderPath");
2101
- writeToFile(`${generatedFolderPath}/schema.graphql`, printSchemaFromModels(models));
2102
- });
2103
- import_commander.program.command("generate-mutation-queries").description("Generate mutation-queries").action(async () => {
2104
- const models = await parseModels();
2105
- const generatedFolderPath = await getSetting("generatedFolderPath");
2106
- const gqlModule = await getSetting("gqlModule");
2107
- writeToFile(`${generatedFolderPath}/client/mutations.ts`, generateMutations(models, gqlModule));
2108
- });
2109
- import_commander.program.command("generate-db-types").description("Generate DB types").action(async () => {
2110
- const models = await parseModels();
2111
- const generatedFolderPath = await getSetting("generatedFolderPath");
2112
- writeToFile(`${generatedFolderPath}/db/index.ts`, generateDBModels(models));
2113
- });
2114
- import_commander.program.command("generate-knex-types").description("Generate Knex types").action(async () => {
2115
- const models = await parseModels();
2116
- const generatedFolderPath = await getSetting("generatedFolderPath");
2117
- writeToFile(`${generatedFolderPath}/db/knex.ts`, generateKnexTables(models));
2118
- });
2119
- import_commander.program.command("generate-graphql-api-types").description("Generate Graphql API types").action(async () => {
2120
- await generateGraphqlApiTypes();
2121
- });
2122
- import_commander.program.command("generate-graphql-client-types").description("Generate Graphql client types").action(async () => {
2123
- await generateGraphqlClientTypes();
2124
- });
2125
2173
  import_commander.program.command("generate-migration [<name>] [<date>]").description("Generate Migration").action(async (name2, date) => {
2126
2174
  const git = (0, import_simple_git.simpleGit)();
2127
2175
  if (!name2) {