@nasebanal/cli 0.1.0
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/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/apis.js +6 -0
- package/dist/auth.js +98 -0
- package/dist/config.js +97 -0
- package/dist/http.js +55 -0
- package/dist/index.js +53 -0
- package/dist/oauth.js +265 -0
- package/dist/output.js +26 -0
- package/dist/spec/build.js +185 -0
- package/dist/spec/loader.js +23 -0
- package/package.json +59 -0
- package/specs/account.yaml +990 -0
- package/specs/app-template.yaml +486 -0
- package/specs/recorder.yaml +2774 -0
- package/specs/target.yaml +1540 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
openapi: 3.0.3
|
|
2
|
+
info:
|
|
3
|
+
title: NASEBANAL - App Template API
|
|
4
|
+
description: >-
|
|
5
|
+
A template API for NASEBANAL applications. Provides sample CRUD endpoints, user authentication via Auth0 JWT and
|
|
6
|
+
Personal Access Tokens (PAT), and integration with the Account API.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
All responses use a uniform envelope: successful responses are `{ "success": true, "data": ... }` and failures are
|
|
10
|
+
`{ "success": false, "error": { "code", "message" } }`. This mirrors `successResponse()` / `errorResponse()` in the
|
|
11
|
+
implementation. The `success` discriminator is pinned with `enum` so both Specmatic stub generation and contract
|
|
12
|
+
tests treat it as a fixed value per response class.
|
|
13
|
+
version: 1.1.1
|
|
14
|
+
contact:
|
|
15
|
+
name: NASEBANAL
|
|
16
|
+
url: https://www.nasebanal.com
|
|
17
|
+
servers:
|
|
18
|
+
- url: http://localhost:8789
|
|
19
|
+
description: Local dev (wrangler dev)
|
|
20
|
+
- url: https://api.app-template.nasebanal.com
|
|
21
|
+
description: Production
|
|
22
|
+
security:
|
|
23
|
+
- BearerAuth: []
|
|
24
|
+
paths:
|
|
25
|
+
/api/v1/health:
|
|
26
|
+
get:
|
|
27
|
+
operationId: getHealth
|
|
28
|
+
tags:
|
|
29
|
+
- Health
|
|
30
|
+
summary: Health check
|
|
31
|
+
description: Returns the health status of the API.
|
|
32
|
+
security: []
|
|
33
|
+
responses:
|
|
34
|
+
'200':
|
|
35
|
+
description: API is healthy
|
|
36
|
+
content:
|
|
37
|
+
application/json:
|
|
38
|
+
schema:
|
|
39
|
+
type: object
|
|
40
|
+
required:
|
|
41
|
+
- success
|
|
42
|
+
- data
|
|
43
|
+
properties:
|
|
44
|
+
success:
|
|
45
|
+
type: boolean
|
|
46
|
+
enum: [true]
|
|
47
|
+
data:
|
|
48
|
+
type: object
|
|
49
|
+
required:
|
|
50
|
+
- status
|
|
51
|
+
- timestamp
|
|
52
|
+
properties:
|
|
53
|
+
status:
|
|
54
|
+
type: string
|
|
55
|
+
timestamp:
|
|
56
|
+
type: string
|
|
57
|
+
format: date-time
|
|
58
|
+
examples:
|
|
59
|
+
valid:
|
|
60
|
+
value:
|
|
61
|
+
success: true
|
|
62
|
+
data:
|
|
63
|
+
status: ok
|
|
64
|
+
timestamp: '2026-05-14T12:00:00Z'
|
|
65
|
+
/api/v1/me:
|
|
66
|
+
get:
|
|
67
|
+
operationId: getCurrentUser
|
|
68
|
+
tags:
|
|
69
|
+
- User
|
|
70
|
+
summary: Get current user profile
|
|
71
|
+
description: Returns the authenticated user's profile information from the Account API.
|
|
72
|
+
responses:
|
|
73
|
+
'200':
|
|
74
|
+
description: User profile
|
|
75
|
+
content:
|
|
76
|
+
application/json:
|
|
77
|
+
schema:
|
|
78
|
+
$ref: '#/components/schemas/UserResponse'
|
|
79
|
+
examples:
|
|
80
|
+
valid:
|
|
81
|
+
value:
|
|
82
|
+
success: true
|
|
83
|
+
data:
|
|
84
|
+
id: 42
|
|
85
|
+
auth0_sub: auth0|0123456789abcdef
|
|
86
|
+
email: user@example.com
|
|
87
|
+
name: Sample User
|
|
88
|
+
language: ja
|
|
89
|
+
plan: pro
|
|
90
|
+
subscription_status: active
|
|
91
|
+
subscription_expires_at: '2026-12-31T23:59:59Z'
|
|
92
|
+
'401':
|
|
93
|
+
$ref: '#/components/responses/Unauthorized'
|
|
94
|
+
/api/v1/items:
|
|
95
|
+
get:
|
|
96
|
+
operationId: listItems
|
|
97
|
+
tags:
|
|
98
|
+
- Items
|
|
99
|
+
summary: List items
|
|
100
|
+
description: Returns all items belonging to the authenticated user.
|
|
101
|
+
responses:
|
|
102
|
+
'200':
|
|
103
|
+
description: List of items
|
|
104
|
+
content:
|
|
105
|
+
application/json:
|
|
106
|
+
schema:
|
|
107
|
+
type: object
|
|
108
|
+
required:
|
|
109
|
+
- success
|
|
110
|
+
- data
|
|
111
|
+
properties:
|
|
112
|
+
success:
|
|
113
|
+
type: boolean
|
|
114
|
+
enum: [true]
|
|
115
|
+
data:
|
|
116
|
+
type: object
|
|
117
|
+
required:
|
|
118
|
+
- data
|
|
119
|
+
- total
|
|
120
|
+
properties:
|
|
121
|
+
data:
|
|
122
|
+
type: array
|
|
123
|
+
items:
|
|
124
|
+
$ref: '#/components/schemas/Item'
|
|
125
|
+
total:
|
|
126
|
+
type: integer
|
|
127
|
+
examples:
|
|
128
|
+
valid:
|
|
129
|
+
value:
|
|
130
|
+
success: true
|
|
131
|
+
data:
|
|
132
|
+
data:
|
|
133
|
+
- id: itm_a1b2c3d4
|
|
134
|
+
user_id: 42
|
|
135
|
+
name: My Item
|
|
136
|
+
description: A sample item description
|
|
137
|
+
created_at: '2026-05-14T12:00:00Z'
|
|
138
|
+
updated_at: '2026-05-14T12:00:00Z'
|
|
139
|
+
total: 1
|
|
140
|
+
'401':
|
|
141
|
+
$ref: '#/components/responses/Unauthorized'
|
|
142
|
+
post:
|
|
143
|
+
operationId: createItem
|
|
144
|
+
tags:
|
|
145
|
+
- Items
|
|
146
|
+
summary: Create item
|
|
147
|
+
description: Creates a new item for the authenticated user.
|
|
148
|
+
requestBody:
|
|
149
|
+
required: true
|
|
150
|
+
content:
|
|
151
|
+
application/json:
|
|
152
|
+
schema:
|
|
153
|
+
$ref: '#/components/schemas/CreateItemInput'
|
|
154
|
+
examples:
|
|
155
|
+
valid:
|
|
156
|
+
value:
|
|
157
|
+
name: My Item
|
|
158
|
+
description: A sample item description
|
|
159
|
+
responses:
|
|
160
|
+
'201':
|
|
161
|
+
description: Item created
|
|
162
|
+
content:
|
|
163
|
+
application/json:
|
|
164
|
+
schema:
|
|
165
|
+
$ref: '#/components/schemas/ItemResponse'
|
|
166
|
+
examples:
|
|
167
|
+
valid:
|
|
168
|
+
value:
|
|
169
|
+
success: true
|
|
170
|
+
data:
|
|
171
|
+
id: itm_a1b2c3d4
|
|
172
|
+
user_id: 42
|
|
173
|
+
name: My Item
|
|
174
|
+
description: A sample item description
|
|
175
|
+
created_at: '2026-05-14T12:00:00Z'
|
|
176
|
+
updated_at: '2026-05-14T12:00:00Z'
|
|
177
|
+
'401':
|
|
178
|
+
$ref: '#/components/responses/Unauthorized'
|
|
179
|
+
/api/v1/items/{id}:
|
|
180
|
+
get:
|
|
181
|
+
operationId: getItem
|
|
182
|
+
tags:
|
|
183
|
+
- Items
|
|
184
|
+
summary: Get item
|
|
185
|
+
description: Returns a single item by ID.
|
|
186
|
+
parameters:
|
|
187
|
+
- name: id
|
|
188
|
+
in: path
|
|
189
|
+
required: true
|
|
190
|
+
schema:
|
|
191
|
+
type: string
|
|
192
|
+
examples:
|
|
193
|
+
valid:
|
|
194
|
+
value: itm_a1b2c3d4
|
|
195
|
+
responses:
|
|
196
|
+
'200':
|
|
197
|
+
description: Item details
|
|
198
|
+
content:
|
|
199
|
+
application/json:
|
|
200
|
+
schema:
|
|
201
|
+
$ref: '#/components/schemas/ItemResponse'
|
|
202
|
+
examples:
|
|
203
|
+
valid:
|
|
204
|
+
value:
|
|
205
|
+
success: true
|
|
206
|
+
data:
|
|
207
|
+
id: itm_a1b2c3d4
|
|
208
|
+
user_id: 42
|
|
209
|
+
name: My Item
|
|
210
|
+
description: A sample item description
|
|
211
|
+
created_at: '2026-05-14T12:00:00Z'
|
|
212
|
+
updated_at: '2026-05-14T12:00:00Z'
|
|
213
|
+
'401':
|
|
214
|
+
$ref: '#/components/responses/Unauthorized'
|
|
215
|
+
'404':
|
|
216
|
+
$ref: '#/components/responses/NotFound'
|
|
217
|
+
put:
|
|
218
|
+
operationId: updateItem
|
|
219
|
+
tags:
|
|
220
|
+
- Items
|
|
221
|
+
summary: Update item
|
|
222
|
+
description: Updates an existing item.
|
|
223
|
+
parameters:
|
|
224
|
+
- name: id
|
|
225
|
+
in: path
|
|
226
|
+
required: true
|
|
227
|
+
schema:
|
|
228
|
+
type: string
|
|
229
|
+
examples:
|
|
230
|
+
valid:
|
|
231
|
+
value: itm_a1b2c3d4
|
|
232
|
+
requestBody:
|
|
233
|
+
required: true
|
|
234
|
+
content:
|
|
235
|
+
application/json:
|
|
236
|
+
schema:
|
|
237
|
+
$ref: '#/components/schemas/UpdateItemInput'
|
|
238
|
+
examples:
|
|
239
|
+
valid:
|
|
240
|
+
value:
|
|
241
|
+
name: Updated Item
|
|
242
|
+
description: An updated item description
|
|
243
|
+
responses:
|
|
244
|
+
'200':
|
|
245
|
+
description: Item updated
|
|
246
|
+
content:
|
|
247
|
+
application/json:
|
|
248
|
+
schema:
|
|
249
|
+
$ref: '#/components/schemas/ItemResponse'
|
|
250
|
+
examples:
|
|
251
|
+
valid:
|
|
252
|
+
value:
|
|
253
|
+
success: true
|
|
254
|
+
data:
|
|
255
|
+
id: itm_a1b2c3d4
|
|
256
|
+
user_id: 42
|
|
257
|
+
name: Updated Item
|
|
258
|
+
description: An updated item description
|
|
259
|
+
created_at: '2026-05-14T12:00:00Z'
|
|
260
|
+
updated_at: '2026-05-15T09:30:00Z'
|
|
261
|
+
'401':
|
|
262
|
+
$ref: '#/components/responses/Unauthorized'
|
|
263
|
+
'404':
|
|
264
|
+
$ref: '#/components/responses/NotFound'
|
|
265
|
+
delete:
|
|
266
|
+
operationId: deleteItem
|
|
267
|
+
tags:
|
|
268
|
+
- Items
|
|
269
|
+
summary: Delete item
|
|
270
|
+
description: Deletes an item by ID.
|
|
271
|
+
parameters:
|
|
272
|
+
- name: id
|
|
273
|
+
in: path
|
|
274
|
+
required: true
|
|
275
|
+
schema:
|
|
276
|
+
type: string
|
|
277
|
+
examples:
|
|
278
|
+
valid:
|
|
279
|
+
value: itm_a1b2c3d4
|
|
280
|
+
responses:
|
|
281
|
+
'200':
|
|
282
|
+
description: Item deleted
|
|
283
|
+
content:
|
|
284
|
+
application/json:
|
|
285
|
+
schema:
|
|
286
|
+
$ref: '#/components/schemas/SuccessResponse'
|
|
287
|
+
examples:
|
|
288
|
+
valid:
|
|
289
|
+
value:
|
|
290
|
+
success: true
|
|
291
|
+
data:
|
|
292
|
+
success: true
|
|
293
|
+
'401':
|
|
294
|
+
$ref: '#/components/responses/Unauthorized'
|
|
295
|
+
'404':
|
|
296
|
+
$ref: '#/components/responses/NotFound'
|
|
297
|
+
components:
|
|
298
|
+
securitySchemes:
|
|
299
|
+
BearerAuth:
|
|
300
|
+
type: http
|
|
301
|
+
scheme: bearer
|
|
302
|
+
bearerFormat: JWT or PAT
|
|
303
|
+
description: Use either an Auth0 JWT token or a Personal Access Token (PAT) starting with `nbpat_`.
|
|
304
|
+
schemas:
|
|
305
|
+
User:
|
|
306
|
+
type: object
|
|
307
|
+
required:
|
|
308
|
+
- id
|
|
309
|
+
- auth0_sub
|
|
310
|
+
- email
|
|
311
|
+
- name
|
|
312
|
+
- language
|
|
313
|
+
- plan
|
|
314
|
+
properties:
|
|
315
|
+
id:
|
|
316
|
+
type: integer
|
|
317
|
+
auth0_sub:
|
|
318
|
+
type: string
|
|
319
|
+
email:
|
|
320
|
+
type: string
|
|
321
|
+
format: email
|
|
322
|
+
name:
|
|
323
|
+
type: string
|
|
324
|
+
language:
|
|
325
|
+
type: string
|
|
326
|
+
enum:
|
|
327
|
+
- ja
|
|
328
|
+
- en
|
|
329
|
+
plan:
|
|
330
|
+
type: string
|
|
331
|
+
enum:
|
|
332
|
+
- free
|
|
333
|
+
- pro
|
|
334
|
+
- family
|
|
335
|
+
- enterprise
|
|
336
|
+
subscription_status:
|
|
337
|
+
type: string
|
|
338
|
+
enum:
|
|
339
|
+
- active
|
|
340
|
+
- canceled
|
|
341
|
+
- past_due
|
|
342
|
+
- trialing
|
|
343
|
+
- null
|
|
344
|
+
nullable: true
|
|
345
|
+
subscription_expires_at:
|
|
346
|
+
type: string
|
|
347
|
+
format: date-time
|
|
348
|
+
nullable: true
|
|
349
|
+
UserResponse:
|
|
350
|
+
type: object
|
|
351
|
+
required:
|
|
352
|
+
- success
|
|
353
|
+
- data
|
|
354
|
+
properties:
|
|
355
|
+
success:
|
|
356
|
+
type: boolean
|
|
357
|
+
enum: [true]
|
|
358
|
+
data:
|
|
359
|
+
$ref: '#/components/schemas/User'
|
|
360
|
+
Item:
|
|
361
|
+
type: object
|
|
362
|
+
required:
|
|
363
|
+
- id
|
|
364
|
+
- user_id
|
|
365
|
+
- name
|
|
366
|
+
- created_at
|
|
367
|
+
- updated_at
|
|
368
|
+
properties:
|
|
369
|
+
id:
|
|
370
|
+
type: string
|
|
371
|
+
user_id:
|
|
372
|
+
type: integer
|
|
373
|
+
name:
|
|
374
|
+
type: string
|
|
375
|
+
description:
|
|
376
|
+
type: string
|
|
377
|
+
nullable: true
|
|
378
|
+
created_at:
|
|
379
|
+
type: string
|
|
380
|
+
format: date-time
|
|
381
|
+
updated_at:
|
|
382
|
+
type: string
|
|
383
|
+
format: date-time
|
|
384
|
+
ItemResponse:
|
|
385
|
+
type: object
|
|
386
|
+
required:
|
|
387
|
+
- success
|
|
388
|
+
- data
|
|
389
|
+
properties:
|
|
390
|
+
success:
|
|
391
|
+
type: boolean
|
|
392
|
+
enum: [true]
|
|
393
|
+
data:
|
|
394
|
+
$ref: '#/components/schemas/Item'
|
|
395
|
+
CreateItemInput:
|
|
396
|
+
type: object
|
|
397
|
+
required:
|
|
398
|
+
- name
|
|
399
|
+
properties:
|
|
400
|
+
name:
|
|
401
|
+
type: string
|
|
402
|
+
minLength: 1
|
|
403
|
+
maxLength: 200
|
|
404
|
+
description:
|
|
405
|
+
type: string
|
|
406
|
+
maxLength: 1000
|
|
407
|
+
UpdateItemInput:
|
|
408
|
+
type: object
|
|
409
|
+
properties:
|
|
410
|
+
name:
|
|
411
|
+
type: string
|
|
412
|
+
minLength: 1
|
|
413
|
+
maxLength: 200
|
|
414
|
+
description:
|
|
415
|
+
type: string
|
|
416
|
+
maxLength: 1000
|
|
417
|
+
SuccessResponse:
|
|
418
|
+
type: object
|
|
419
|
+
required:
|
|
420
|
+
- success
|
|
421
|
+
- data
|
|
422
|
+
properties:
|
|
423
|
+
success:
|
|
424
|
+
type: boolean
|
|
425
|
+
enum: [true]
|
|
426
|
+
data:
|
|
427
|
+
type: object
|
|
428
|
+
required:
|
|
429
|
+
- success
|
|
430
|
+
properties:
|
|
431
|
+
success:
|
|
432
|
+
type: boolean
|
|
433
|
+
enum: [true]
|
|
434
|
+
Error:
|
|
435
|
+
type: object
|
|
436
|
+
required:
|
|
437
|
+
- success
|
|
438
|
+
- error
|
|
439
|
+
properties:
|
|
440
|
+
success:
|
|
441
|
+
type: boolean
|
|
442
|
+
enum: [false]
|
|
443
|
+
error:
|
|
444
|
+
type: object
|
|
445
|
+
required:
|
|
446
|
+
- code
|
|
447
|
+
- message
|
|
448
|
+
properties:
|
|
449
|
+
code:
|
|
450
|
+
type: string
|
|
451
|
+
message:
|
|
452
|
+
type: string
|
|
453
|
+
responses:
|
|
454
|
+
Unauthorized:
|
|
455
|
+
description: Authentication required or invalid token
|
|
456
|
+
content:
|
|
457
|
+
application/json:
|
|
458
|
+
schema:
|
|
459
|
+
$ref: '#/components/schemas/Error'
|
|
460
|
+
examples:
|
|
461
|
+
unauthorized:
|
|
462
|
+
value:
|
|
463
|
+
success: false
|
|
464
|
+
error:
|
|
465
|
+
code: AUTH_ERROR
|
|
466
|
+
message: No authentication token provided
|
|
467
|
+
NotFound:
|
|
468
|
+
description: Resource not found
|
|
469
|
+
content:
|
|
470
|
+
application/json:
|
|
471
|
+
schema:
|
|
472
|
+
$ref: '#/components/schemas/Error'
|
|
473
|
+
examples:
|
|
474
|
+
not_found:
|
|
475
|
+
value:
|
|
476
|
+
success: false
|
|
477
|
+
error:
|
|
478
|
+
code: NOT_FOUND
|
|
479
|
+
message: Resource not found
|
|
480
|
+
tags:
|
|
481
|
+
- name: Health
|
|
482
|
+
description: Health check endpoints
|
|
483
|
+
- name: User
|
|
484
|
+
description: User profile endpoints
|
|
485
|
+
- name: Items
|
|
486
|
+
description: Sample CRUD endpoints (replace with your domain)
|