@checkstack/scripts 0.1.0 → 0.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @checkstack/scripts
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 0b9fc58: Fix workspace:\* protocol resolution in published packages
8
+
9
+ Published packages now correctly have resolved dependency versions instead of `workspace:*` references. This is achieved by using `bun publish` which properly resolves workspace protocol references.
10
+
3
11
  ## 0.1.0
4
12
 
5
13
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/scripts",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "bin": {
5
5
  "checkstack-scripts": "./src/cli.ts"
6
6
  },
@@ -13,7 +13,7 @@
13
13
  "handlebars": "^4.7.8"
14
14
  },
15
15
  "devDependencies": {
16
- "@checkstack/tsconfig": "workspace:*",
16
+ "@checkstack/tsconfig": "0.0.2",
17
17
  "@types/inquirer": "^8.2.10",
18
18
  "@types/handlebars": "^4.1.0",
19
19
  "typescript": "^5.0.0"
@@ -1,7 +1,6 @@
1
1
  import { implement } from "@orpc/server";
2
- import { autoAuthMiddleware, type RpcContext } from "@checkstack/backend-api";
2
+ import { autoAuthMiddleware, type RpcContext, type SafeDatabase } from "@checkstack/backend-api";
3
3
  import { {{pluginNameCamel}}Contract } from "@checkstack/{{pluginBaseName}}-common";
4
- import type { NodePgDatabase } from "drizzle-orm/node-postgres";
5
4
  import type * as schema from "./schema";
6
5
  import { {{pluginNamePascal}}Service } from "./service";
7
6
 
@@ -18,7 +17,7 @@ const os = implement({{pluginNameCamel}}Contract)
18
17
  export function create{{pluginNamePascal}}Router({
19
18
  database,
20
19
  }: {
21
- database: NodePgDatabase<typeof schema>;
20
+ database: SafeDatabase<typeof schema>;
22
21
  }) {
23
22
  const service = new {{pluginNamePascal}}Service(database);
24
23
 
@@ -28,7 +27,7 @@ export function create{{pluginNamePascal}}Router({
28
27
  }),
29
28
 
30
29
  getItem: os.getItem.handler(async ({ input }) => {
31
- return await service.getItem(input);
30
+ return await service.getItem(input.id);
32
31
  }),
33
32
 
34
33
  createItem: os.createItem.handler(async ({ input }) => {
@@ -40,7 +39,7 @@ export function create{{pluginNamePascal}}Router({
40
39
  }),
41
40
 
42
41
  deleteItem: os.deleteItem.handler(async ({ input }) => {
43
- await service.deleteItem(input);
42
+ await service.deleteItem(input.id);
44
43
  }),
45
44
  });
46
45
  }
@@ -1,4 +1,4 @@
1
- import type { NodePgDatabase } from "drizzle-orm/node-postgres";
1
+ import type { SafeDatabase } from "@checkstack/backend-api";
2
2
  import { eq } from "drizzle-orm";
3
3
  import * as schema from "./schema";
4
4
  import { {{pluginNameCamel}}Items } from "./schema";
@@ -8,7 +8,7 @@ import type {
8
8
  } from "@checkstack/{{pluginBaseName}}-common";
9
9
 
10
10
  export class {{pluginNamePascal}}Service {
11
- constructor(private readonly database: NodePgDatabase<typeof schema>) {}
11
+ constructor(private readonly database: SafeDatabase<typeof schema>) {}
12
12
 
13
13
  async getItems() {
14
14
  return await this.database.select().from({{pluginNameCamel}}Items);
@@ -10,16 +10,15 @@ export const {{pluginNameCamel}}Access = {
10
10
  * - read: View {{pluginBaseName}} data (auto-assigned to authenticated users)
11
11
  * - manage: Create, update, and delete {{pluginBaseName}} data
12
12
  */
13
- ...accessPair(
14
- "{{pluginBaseName}}",
15
- {
16
- read: "Read {{pluginBaseName}} data",
17
- manage: "Manage {{pluginBaseName}} data",
13
+ ...accessPair("{{pluginBaseName}}", {
14
+ read: {
15
+ description: "Read {{pluginBaseName}} data",
16
+ isDefault: true, // read is auto-assigned to "users" role
18
17
  },
19
- {
20
- readIsDefault: true, // read is auto-assigned to "users" role
21
- }
22
- ),
18
+ manage: {
19
+ description: "Manage {{pluginBaseName}} data",
20
+ },
21
+ }),
23
22
  };
24
23
 
25
24
  /**
@@ -1,5 +1,4 @@
1
- import { oc } from "@orpc/contract";
2
- import { createClientDefinition, type ProcedureMetadata } from "@checkstack/common";
1
+ import { createClientDefinition, proc } from "@checkstack/common";
3
2
  import { z } from "zod";
4
3
  import {
5
4
  {{pluginNamePascal}}ItemSchema,
@@ -9,31 +8,38 @@ import {
9
8
  import { {{pluginNameCamel}}Access } from "./access";
10
9
  import { pluginMetadata } from "./plugin-metadata";
11
10
 
12
- // Create base builder with ProcedureMetadata support
13
- // See: https://docs.checkstack.dev/common-plugins#contract-based-auth-enforcement
14
- const _base = oc.$meta<ProcedureMetadata>({});
15
-
16
11
  export const {{pluginNameCamel}}Contract = {
17
12
  // List all items - requires authenticated user with read access
18
- getItems: _base
19
- .meta({ userType: "user", access: [{{pluginNameCamel}}Access.read] })
20
- .output(z.array({{pluginNamePascal}}ItemSchema)),
13
+ getItems: proc({
14
+ operationType: "query",
15
+ userType: "user",
16
+ access: [{{pluginNameCamel}}Access.read],
17
+ }).output(z.array({{pluginNamePascal}}ItemSchema)),
21
18
 
22
19
  // Get single item
23
- getItem: _base
24
- .meta({ userType: "user", access: [{{pluginNameCamel}}Access.read] })
25
- .input(z.string())
20
+ getItem: proc({
21
+ operationType: "query",
22
+ userType: "user",
23
+ access: [{{pluginNameCamel}}Access.read],
24
+ })
25
+ .input(z.object({ id: z.string() }))
26
26
  .output({{pluginNamePascal}}ItemSchema),
27
27
 
28
28
  // Create item
29
- createItem: _base
30
- .meta({ userType: "user", access: [{{pluginNameCamel}}Access.manage] })
29
+ createItem: proc({
30
+ operationType: "mutation",
31
+ userType: "user",
32
+ access: [{{pluginNameCamel}}Access.manage],
33
+ })
31
34
  .input(Create{{pluginNamePascal}}ItemSchema)
32
35
  .output({{pluginNamePascal}}ItemSchema),
33
36
 
34
37
  // Update item
35
- updateItem: _base
36
- .meta({ userType: "user", access: [{{pluginNameCamel}}Access.manage] })
38
+ updateItem: proc({
39
+ operationType: "mutation",
40
+ userType: "user",
41
+ access: [{{pluginNameCamel}}Access.manage],
42
+ })
37
43
  .input(
38
44
  z.object({
39
45
  id: z.string(),
@@ -43,17 +49,21 @@ export const {{pluginNameCamel}}Contract = {
43
49
  .output({{pluginNamePascal}}ItemSchema),
44
50
 
45
51
  // Delete item
46
- deleteItem: _base
47
- .meta({ userType: "user", access: [{{pluginNameCamel}}Access.manage] })
48
- .input(z.string())
52
+ deleteItem: proc({
53
+ operationType: "mutation",
54
+ userType: "user",
55
+ access: [{{pluginNameCamel}}Access.manage],
56
+ })
57
+ .input(z.object({ id: z.string() }))
49
58
  .output(z.void()),
50
59
  };
51
60
 
52
61
  // Export contract type
53
62
  export type {{pluginNamePascal}}Contract = typeof {{pluginNameCamel}}Contract;
54
63
 
55
- // Export client definition for type-safe forPlugin usage
56
- // Use: const client = rpcApi.forPlugin({{pluginNamePascal}}Api);
64
+ // Export client definition for type-safe usePluginClient usage
65
+ // Frontend: const client = usePluginClient({{pluginNamePascal}}Api);
66
+ // Backend: const client = rpcClient.forPlugin({{pluginNamePascal}}Api);
57
67
  export const {{pluginNamePascal}}Api = createClientDefinition(
58
68
  {{pluginNameCamel}}Contract,
59
69
  pluginMetadata
@@ -1,15 +1,9 @@
1
- import { createApiRef } from "@checkstack/frontend-api";
2
- import type { InferClient } from "@checkstack/common";
3
- import { {{pluginNamePascal}}Api } from "@checkstack/{{pluginBaseName}}-common";
4
-
5
- // Re-export types for convenience
1
+ // Re-export types from common for convenience
6
2
  export type {
7
3
  {{pluginNamePascal}}Item,
8
4
  Create{{pluginNamePascal}}Item,
9
5
  Update{{pluginNamePascal}}Item,
10
6
  } from "@checkstack/{{pluginBaseName}}-common";
11
7
 
12
- // {{pluginNamePascal}}ApiClient is the client type inferred from the Api definition
13
- export type {{pluginNamePascal}}ApiClient = InferClient<typeof {{pluginNamePascal}}Api>;
14
-
15
- export const {{pluginNameCamel}}ApiRef = createApiRef<{{pluginNamePascal}}ApiClient>("{{pluginBaseName}}-api");
8
+ // Re-export the Api definition for usePluginClient usage
9
+ export { {{pluginNamePascal}}Api } from "@checkstack/{{pluginBaseName}}-common";
@@ -1,53 +1,55 @@
1
- import { useEffect, useState } from "react";
2
- import { useApi } from "@checkstack/frontend-api";
3
- import { {{pluginNameCamel}}ApiRef, type {{pluginNamePascal}}Item } from "../api";
4
- import { Button, Card } from "@checkstack/ui";
1
+ import { usePluginClient } from "@checkstack/frontend-api";
2
+ import { {{pluginNamePascal}}Api } from "@checkstack/{{pluginBaseName}}-common";
3
+ import type { {{pluginNamePascal}}Item } from "../api";
4
+ import { Button, Card, PageLayout } from "@checkstack/ui";
5
5
  import { useNavigate } from "react-router-dom";
6
+ import { Boxes } from "lucide-react";
6
7
 
7
8
  export const {{pluginNamePascal}}ListPage = () => {
8
- const api = useApi({{pluginNameCamel}}ApiRef);
9
+ const client = usePluginClient({{pluginNamePascal}}Api);
9
10
  const navigate = useNavigate();
10
- const [items, setItems] = useState<{{pluginNamePascal}}Item[]>([]);
11
- const [loading, setLoading] = useState(true);
12
- const [error, setError] = useState<Error>();
13
11
 
14
- useEffect(() => {
15
- api
16
- .getItems()
17
- .then(setItems)
18
- .catch(setError)
19
- .finally(() => setLoading(false));
20
- }, [api]);
12
+ // Query for items - automatic loading and error states
13
+ const { data: items = [], isLoading, error, refetch } = client.getItems.useQuery({});
21
14
 
22
- const handleDelete = async (id: string) => {
23
- try {
24
- await api.deleteItem(id);
25
- setItems(items.filter((item) => item.id !== id));
26
- } catch (error) {
27
- console.error("Failed to delete item:", error);
28
- }
15
+ // Delete mutation with refetch on success
16
+ const deleteMutation = client.deleteItem.useMutation({
17
+ onSuccess: () => {
18
+ void refetch();
19
+ },
20
+ });
21
+
22
+ const handleDelete = (id: string) => {
23
+ deleteMutation.mutate({ id });
29
24
  };
30
25
 
31
- if (loading) return <div className="p-6">Loading...</div>;
32
- if (error) return <div className="p-6 text-red-500">Error: {error.message}</div>;
26
+ if (error) {
27
+ return (
28
+ <PageLayout title="{{pluginNamePascal}}" icon={Boxes}>
29
+ <div className="text-destructive">Error: {error.message}</div>
30
+ </PageLayout>
31
+ );
32
+ }
33
33
 
34
34
  return (
35
- <div className="p-6">
36
- <div className="flex justify-between items-center mb-4">
37
- <h1 className="text-2xl font-bold">{{pluginNamePascal}} Items</h1>
35
+ <PageLayout
36
+ title="{{pluginNamePascal}}"
37
+ icon={Boxes}
38
+ loading={isLoading}
39
+ actions={
38
40
  <Button onClick={() => navigate("/{{pluginBaseName}}/new")}>
39
41
  Create Item
40
42
  </Button>
41
- </div>
42
-
43
+ }
44
+ >
43
45
  <div className="grid gap-4">
44
- {items.map((item) => (
46
+ {items.map((item: {{pluginNamePascal}}Item) => (
45
47
  <Card key={item.id} className="p-4">
46
48
  <div className="flex justify-between items-start">
47
49
  <div>
48
50
  <h3 className="font-semibold">{item.name}</h3>
49
51
  {item.description && (
50
- <p className="text-sm text-gray-600">{item.description}</p>
52
+ <p className="text-sm text-muted-foreground">{item.description}</p>
51
53
  )}
52
54
  </div>
53
55
  <div className="flex gap-2">
@@ -62,8 +64,9 @@ export const {{pluginNamePascal}}ListPage = () => {
62
64
  variant="destructive"
63
65
  size="sm"
64
66
  onClick={() => handleDelete(item.id)}
67
+ disabled={deleteMutation.isPending}
65
68
  >
66
- Delete
69
+ {deleteMutation.isPending ? "Deleting..." : "Delete"}
67
70
  </Button>
68
71
  </div>
69
72
  </div>
@@ -71,11 +74,11 @@ export const {{pluginNamePascal}}ListPage = () => {
71
74
  ))}
72
75
 
73
76
  {items.length === 0 && (
74
- <Card className="p-8 text-center text-gray-500">
77
+ <Card className="p-8 text-center text-muted-foreground">
75
78
  No items yet. Create your first item to get started.
76
79
  </Card>
77
80
  )}
78
81
  </div>
79
- </div>
82
+ </PageLayout>
80
83
  );
81
84
  };
@@ -1,7 +1,6 @@
1
- import { createFrontendPlugin, rpcApiRef, type ApiRef } from "@checkstack/frontend-api";
2
- import { {{pluginNameCamel}}ApiRef, type {{pluginNamePascal}}ApiClient } from "./api";
1
+ import { createFrontendPlugin } from "@checkstack/frontend-api";
3
2
  import { {{pluginNamePascal}}ListPage } from "./components/{{pluginNamePascal}}ListPage";
4
- import { {{pluginNameCamel}}Routes, {{pluginNamePascal}}Api, pluginMetadata, {{pluginNameCamel}}Access } from "@checkstack/{{pluginBaseName}}-common";
3
+ import { {{pluginNameCamel}}Routes, pluginMetadata, {{pluginNameCamel}}Access } from "@checkstack/{{pluginBaseName}}-common";
5
4
 
6
5
  export default createFrontendPlugin({
7
6
  metadata: pluginMetadata,
@@ -15,18 +14,6 @@ export default createFrontendPlugin({
15
14
  accessRule: {{pluginNameCamel}}Access.read,
16
15
  },
17
16
  ],
18
-
19
- // Register client API using oRPC
20
- apis: [
21
- {
22
- ref: {{pluginNameCamel}}ApiRef,
23
- factory: (deps: { get: <T>(ref: ApiRef<T>) => T }): {{pluginNamePascal}}ApiClient => {
24
- const rpcApi = deps.get(rpcApiRef);
25
- // Create type-safe client using the plugin's Api definition
26
- return rpcApi.forPlugin({{pluginNamePascal}}Api);
27
- },
28
- },
29
- ],
30
17
  });
31
18
 
32
19
  export * from "./api";